Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:
1.原理: 动态的创建属性和方法.
2.实现: 通过魔术方法[__set,__get,__isset,__unset,__call,__callStatic]来实现.
实例:
// 实例:
class Demo1
{
private $overloadData = [];
public $name;
public $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
public function getUser(): string
{
return "{$this->name} : {$this->email}";
}
public function insertData($name): string
{
$this->overloadData[$name] = $name;
echo nl2br("创建成功...\n");
return $this->overloadData[$name];
}
// 当调用未设置的属性时,会自动调用
public function __get($name): string
{
if (array_key_exists($name, $this->overloadData)) {
return $this->overloadData[$name];
} else {
echo nl2br("没有该属性$name, 尝试创建中.....\n");
return $this->insertData($name);
}
}
// 当对未设置的属性赋值时,会自动调用
public function __set($name, $value)
{
// echo "$name : $value<br>";
$this->overloadData[$name] = $value;
}
// 当对未设置的属性调用isset()方法并且时,会自动调用
public function __isset($name): string
{
echo "Is '{$name}' set?\n";
return isset($this->overloadData[$name]);
}
// 当对未设置的属性调用unset()方法并且时,会自动调用
public function __unset($name)
{
echo "类实例中没有 '$name'\n";
unset($this->overloadData[$name]);
}
// 当访问的非静态方法不存在时,会自动调用该方法
public function __call($funcName, $ages)
{
return "函数名: $funcName, 参数: [" . implode(', ', $ages) . "]";
}
// 当访问的静态方法不存在时,会自动调用该方法
public static function __callStatic($funcName, $ages)
{
return "静态函数名: $funcName, 参数: [" . implode(', ', $ages) . "]";
}
}
$objTest0222 = new Demo1('张三', 'admin@test.com');
echo $objTest0222->name, '<br>';
echo $objTest0222->email, '<br>';
echo $objTest0222->getUser(), '<hr>';
// 调用没有创建的属性
echo $objTest0222->a, '<br>';
echo '<hr>';
// 对为创建的属性赋值
$objTest0222->aa = '随便赋的值';
echo $objTest0222->aa, '<br>';
echo '<hr>';
// 对未创建的属性调用isset或者unset
var_dump(isset($objTest0222->aaa));
unset($objTest0222->aaa);
echo '<hr>';
// 调用没有创建的方法时
// 非静态方法
echo $objTest0222->testtest(1,2,3,4,5,6), '<br>';
echo Demo1::testtestStatic(...([6,5,4,3,2,1])), '<br>';
全局成员: 类, 常量, 函数
const PATH = '/0222/test2/';
class Test2Demo1
{
//...
}
function test2Demo1()
{
// ....
}
// 命名空间的创建由关键值nampspace修饰
namespace ts {
}
// 访问空间成员
namespace ts1 {
const PATH = '/0222/test2';
class Test2Demo1
{
public function text2Demo1(): string
{
return '我是空间内类的函数: ' . __METHOD__;
}
}
function test2Demo1(): string
{
return '我是空间内的函数: ' . __FUNCTION__;
}
echo PATH, '<br>'; // 或者 \ts1\PATH 或者 namespace\PATH ,这三种方式访问都可以
echo (new Test2Demo1())->text2Demo1(), '<br>';
echo test2Demo1(), '<br>';
}
空间成员的分解: 当一个空间内的代码过长时,可以把同一个空间内的代码分解到多个php脚本文件中.
实例:
<?php
namespace test2;
require 'test2-2.php';
require 'test2-3.php';
const PATH = '/0222/test2';
// 访问空间成员
echo PATH, '<br>';
echo (new Test2Demo1())->text2Demo1(), '<br>';
echo test2Demo1(), '<br>';
<?php
namespace test2;
class Test2Demo1
{
public function text2Demo1(): string
{
return '我是空间内类的函数: ' . __METHOD__;
}
}
<?php
namespace test2;
function test2Demo1(): string
{
return '我是空间内的函数: ' . __FUNCTION__;
}
子空间: PHP 命名空间允许指定层次化的命名空间的名称,因此,命名空间的名字可以使用分层次的方式定义
<?php
namespace test3 {
function test31(): string
{
return "我是父级空间的方法" . __METHOD__;
}
echo "当前空间: " . __NAMESPACE__, "<br>";
echo test31(), "<hr>";
echo '------------------调用下级空间的成员------------------<br>';
// namespace\test3One\test1() 和 \test3\test3One\test1() 也是一样的效果
// namespace: 代指当前空间,类似于class中的$this和self
echo "test3\\test3One空间的成员: ", test3One\test1(), "<br>";
}
namespace test3\test3One{
function test1(): string
{
return "我是子空间的方法" . __METHOD__;
}
echo "当前空间: " . __NAMESPACE__, "<br>";
echo test1(), "<hr>";
echo '------------------调用下级空间的成员------------------<br>';
echo "test3\\test3One\\test3Two空间的成员: ", test3Two\test2(), "<br>";
echo '------------------调用上级空间的成员------------------<br>';
echo "test3空间的成员: ", \test3\test31(), "<br>";
}
namespace test3\test3One\test3Two{
function test2(): string
{
return "我是子空间的方法" . __METHOD__;
}
echo "当前空间: " . __NAMESPACE__, "<br>";
echo test2(), "<hr>";
echo '------------------调用上级空间的成员------------------<br>';
echo "test3空间的成员: ", \test3\test31(), "<br>";
echo "test3\\test3One空间的成员: ", \test3\test3One\test1(), "<br>";
}