批改状态:合格
老师批语:
__get(), __set()
<?phpnamespace _0815;/////////////demo1///////////////*** 属性重载 __get(),__set()**///封装,重载,继承class User{//private:私有封装private array $data = ['age' => 20,];//查询接口public function __get($name){$condition = array_key_exists($name, $this->data) ;return $condition ? $this->data[$name] : "$name 属性不存在";}//设置接口public function __set($name, $value){$condition = array_key_exists($name, $this->data) ;if(!$condition){//这里如果不做提示和返回,对于把age错写成ag3,echo时又写对成age,是不是不好定位设置值不成功的问题?echo "$name 属性不存在<br>";// 但是这里出现了多处返回,是不是部分编辑器会报错?return ;}return $condition ? $this->data[$name] : "$name 属性不存在";}}$user =new User();echo $user->age.'<br>';$user->ag3 = 10;echo $user->age.'<br>';

遗留问题:
如上述代码注释所述,array_key_exist在__set中应用,多处return是否可以?不可以,如何处理注释中提到的问题?
__call(), static function __callStatic()
<?phpnamespace _0815;/////////////demo1///////////////*** 属性重载 __get(),__set()* 方法重载 __call($name, $args), __callStatic($name, $args)*///封装,重载,继承class User{//private:私有封装private array $data = ['age' => 20,];//查询接口public function __get($name){$condition = array_key_exists($name, $this->data) ;return $condition ? $this->data[$name] : "$name 属性不存在";}//设置接口public function __set($name, $value){$condition = array_key_exists($name, $this->data) ;if(!$condition){//这里如果不做提示和返回,对于把age错写成ag3,echo时又写对成age,是不是不好定位设置值不成功的问题?echo "$name 属性不存在<br>";// 但是这里出现了多处返回,是不是部分编辑器会报错?return ;}return $condition ? $this->data[$name] : "$name 属性不存在";}// 可以自动拦截对方法的非法请求public function __call($name, $arguments){printf('非法动态方法:%s,<pre>%s</pre>.<br>', $name, print_r($arguments, true));}// 拦截对静态方法的非法请求public static function __callStatic($name, $arguments){printf('非法静态方法:%s,<pre>%s</pre>.<br>', $name, print_r($arguments, true));}}$user =new User();echo $user->age.'<br>';$user->ag3 = 10;echo $user->age.'<br>';// 非静态方法$user->hello('路人甲','4352259');// 静态方法User::world('路人乙','28375985');

//ThinkPHP,查询构造器,数据库操作class Query{public function table(){echo 'Query table()->';return $this;}public function where(){echo 'Query where()->';return $this;}public function find(){echo 'Query find()<br>';}}// 查询入口class Db{//实例化时自动连接数据库// public function __construct()// {// self::connect();// }public static function __callStatic($name, $arguments){// printf('方法:%s,参数:<pre>%s</pre>',$name, print_r($arguments, true));// 所有查询在此完成,单入口查询return call_user_func_array([new Query, $name] , $arguments);}}Db::table('think_user')->where('id', 1)->find();

/*** 类的扩展(继承)/抽象/最终* 1. 可继承成员protected* 2. extends: 类成员的来源* 3. parent:父类引用*/class Person{//属性// public:公共成员,类内、子类、类外部可访问public string $email = 'admin@php.cn';// private:私有成员,类内可访问。private int $id = 10;//protected:受保护成员,类内、子类可访问。protected string $name;//方法public function __construct($name){$this->name =$name;}// 自定义方法protected function getInfo():string{return $this->name;}}class Stu extends Person{//只需要扩展属性和方法// 属性扩展private string $lesson;private int $score;//方法扩展// 构造方法扩展public function __construct($name, $lesson, $score){//引用父类parent::__construct($name);$this->lesson = $lesson;$this->score =$score;}// 为方便外部访问,由public定义public function getInfo(): string{return parent::getInfo().'同学,'.$this->lesson.'成绩:'.$this->score.'<br>';}}$stu = new Stu('路人甲', 'php', 99);echo $stu->getInfo();

// 禁用父类,仅允许通过他的子类来访问父类成员。// 把当前类声明为抽象类abstract。// 如果类中有抽象方法,则必须声明为抽象类。abstract class demo1{public string $name = 'admin';// 抽象方法,没有具体实现体的方法应该声明成抽象方法。abstract public static function getInfo($name);}class demo2 extends demo1{// 在子类中必须实现父类抽象方法,否则报错。public static function getInfo($name){return 'Hello,'.$name;}}echo demo2::getInfo('路人甲');

// final最终类,禁止继承,直接用final class demofin{}//继承会报错class demo extends demofin{}

//接口:升级版的抽象类interface iUser{//接口的属性必须是常量public const NATION = 'CHINA';//接口方法必须是publicpublic function m1();public function m2();}// 工作类:实现接口内容class demo1 implements iUser{// 接口中的抽象方法必须在工作类中全部实现public function m1(){}public function m2(){}}// 仅实现一部分,需声明为抽象子类abstract class Demo2 implements iUser{public function m1(){}}class demo3 extends Demo2{public function m2(){}}// php是单继承,可以通过接口间接多继承,不推荐interface A{}interface B{}interface C{}// 多继承class Test implements A, B, C{}interface iDb{// 插入public static function insert(array $data);// 更新public static function update(array $data, string $where);// 删除public static function delete(string $where);// 查询public static function select(array $options);}//这个地方上课时没有implements,是默认的么?abstract class aDb implements iDb{// 插入public static function insert(array $data){}// 更新public static function update(array $data, string $where){}// 删除public static function delete(string $where){}// 查询public static function select(array $options){}}class Db extends aDb{}
全局成员:函数,常量,类/接口,全局有效,禁止重复声明
解决全局成员命名冲突问题
namespace _0815;function hello(){}const A = 1;class D{}namespace _0815_1;function hello(){}const A = 1;class D{}
namespace one;class Demo1{public static string $name = 'admin';}// 当存在命名空间时,全局成员应该使用完整名称。// 完整类名 = 空间名称\类名// ::class 获取完整类名echo Demo1::class.'<br>';namespace two;class demo1{public static string $name = '路人甲';}echo Demo1::class.'<br>';// 跨空间访问// echo one\Demo1::$name;->实际访问’two\one\Demo1‘// 要从根空间'\'开始echo \one\Demo1::$name;

// 1. 当前路径:非限定名称 Index// 2. 相对路径:限定名称 two\Index// 3. 绝对路径:完全限定名称 \one\two\Indexnamespace _0815;namespace one;class index{public static function show(){return __METHOD__;}}echo Index::show().'<br>';echo two\Index::show().'<br>';// 空间可分层namespace one\two;class index{public static function show(){return __METHOD__;}}echo Index::show().'<br>';

use起别名简化长度
namespace one;class Index{public static function show(){return __METHOD__;}}echo \one\two\three\Index::show().'<br>';// use默认使用完全限定名称的类名/绝对路径,用别名简化长度。use \one\two\three\Index as UserIndex;echo UserIndex::show().'<br>';//-----------------------------------------namespace one\two\three;class Index{public static function show(){return __METHOD__;}}

上面代码中,如果namespace one没有Index类,那么use可以直接起别名Index,
...use \one\two\three\Index as Index;echo Index::show().'<br>';
当前类别名Index与原始类名相同,还可以不写
...use \one\two\three\Index;echo Index::show().'<br>';
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号