PHP 属性重载|学习笔记

简介: 快速学习 PHP 属性重载

开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第二阶段:PHP 属性重载】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/712/detail/12712


PHP 属性重载


内容介绍:

一、目标

二、概念

三、示例

四、小结


一、目标

了解 PHP 属性重载的意义,掌握 PHP 重载实现代码的容错性


二、概念

PHP 属性重载:当对象访问不存在的或者权限不够的属性的时候,自动触发的魔术方法让代码不出错(容错处理)

1.属性重载魔术方法

(1)_get (属性名):访问不存在或者权限不够的属性时触发

(2)_set (属性名,属性值):设置不存在或者权限不够的属性时触发(3)_isset (属性名):判定不存在或者权限不够的属性时触发

(4)_unset (属性名):删除不存在或者权限不够的属性时触发


三、示例

1.魔术方法

指系统为类中预先设计好的,只需要开发者实现的方法,魔术方法以双下划线--开始。对象在某些特定情况下会自动调用的方法。构造方法、析构方法和克隆方法就是魔术方法。

class Man{

public function _construct(){}

}

new Man() ;    #实例化后对象自动调用(触发时机:对象被实例化)

2.实现属性重载

如果想在外部读取私有属性而不报错,需要给一个名字来帮取

class Man{

#属性:私有

private $age = 10;

#读取重载

public function __get($key){

echo $key ,__METHOD__,'
';

}

#写重载

public function _set($key , $value){

echo $key . ' : ' . $value . '
';

}

#查是否存在重载

public function _isset($key){

echo $key,_METHOD__, '
'

}

#删除属性重载

public function _unset($key){

echo $key ,_METHOD__, '
';

}

}

#实例化

$m = new Man();

$m->age;             #类外访问私有属性:原本不允许

$m->age = 100;      #设置

isset($m->age) ;    #判定

unset($m->age);     #删除

class Man{

#属性:私有

private $age = 10;(年龄私有不允许访问日,如果想要访问需要实例化)

}

$m = new Man();

$m->age;(直接调用访问,不输出)

此时不允许访问

图片1.png

此时可以增加一个读取重载来解决

#读取重载

public function __get($key){

echo $key ,__METHOD__,'
';

}

如果需要访问不存在的: $m->name

也显示不存在

图片2.png

此时添加一项 name

图片3.png

再点击刷新,只剩一个 get。因为 age 没有权限,而 name 存在而且能访问,所以不会走读取重载。

图片4.png

如果读取重载后想要写入数据 $m->age++;

get 就不管用了

图片5.png

此时添加写重载。

#写重载

public function _set($key , $value){

echo $key . ' : ' . $value . '
';

}

#写入数据

Sm->age十十;

$m->age=12;

系统不理解为设置,而是读取,因此会走__get()

图片6.png

再运行

图片7.png

此时如果对 name 设置则根本不会走,因为它本身允许被设置。如果再往里放入其他东西也不影响,不会增加对应的属性,所以对象想要增加属性,不能直接添加属性,比如增加$m->gender = 'Male';

图片8.png

此时再打一个对象 var_dump($m);

点击刷新,发现并没有添加这个属性。

图片9.png

这是因为写重载并没有真正地增加对象的属性。如果要判定重载是否存在

#判定属性

var dump(isset($m->age));

点击刷新显示 false

图片10.png

这是因为我们没有设定它是不允许访问的,此时可以进行检查性的重载。

#查是否存在重载

public function __isset($key){

echo $key,__METHOD__,'
';

}

}

但是此时还是无法访问,因为在 isset 里并没有告知是否存在。

再来删除一个属性:

unset($m->age);

图片11.png

显示为不能访问私有。此时添加一个删除属性重载

#删除属性重载

public function _unset($key){

echo $key ,_METHOD__, '
';

}

}

图片12.png

此时系统没有报错,目的已经完成。

3.属性重载的目的

一方面为了不让程序运行出错,另一方面可以在类内部由我们自己控制内容的访问。比如在 get 的时候有些东西允许访问有些东西不允许访问,所以可以定义一个列表,如果访问的是 age,内部帮你访问,否则 false。

class Man{

private $age = 10;

#读取重载

public function __get($key){

# echo $key , '
';

#定义一个允许访问列表:假设有很多私有属性

$allow = array( 'age ');

#判定是否在列表内:在就允许访问,不在就返回 NULL 或者 false

if(in_array($key , $a11ow)){

return $this->$key;    #可变属性: $key 是外部访问的目标,最终为 $this->age

}

#不允许访问

return false;

}

可变属性相当于可变变量,本来 $this 的访问属性名不需要带$符号,但这时 $key 是变量,是最终取出来的结果。

再访问就会调用方法并且输出10,说明它走了这个方法,因为不允许访问,但是内部提供了结果可以使用。

图片13.png

如果 var_dump 一个不存在的 var_dump($m->gender);

此时显示 false

图片14.png

此时除了不让系统报错,而且内部限定了哪些东西可以分为哪些东西不能访问。

# 写重载(该方法没有返回值)

public function __set($key , $value){

# echo $key . ' : ' . Svalue . '
';

#与 _get 理论类似:允许的设置,不允许的不设置(什么都不做即可)

如果想让某些东西可写,需要增加一个列表,判断如果存在,就在里面帮它设置

}

#判定重载

public function __isset(Skey){

#给出内部判定结果

return isset($this->$key);

}

在判定时加一个内部判定,再进行判定时

图片15.png

False 变成了 true,说明属性是存在的。如果不加,系统还是 false。因为不能读取的话在外面判定不了。所以有了这个重载之后就可以在内部判定是否真有。

删除的另一种方法:

#对象重载

public function  toString(){

#返回一个指定字符串(一般是当类有属性保存某些信息时,输出某个属性) return __METHOD__;

}

}

当对象被当作普通数据时会自动触发。对象是一种复合类型的数据,不能直接输出,所以会报错。

图片16.png

如果添加对象重载,刷新

public function __unset ( $key){

echo $key,__METHOD__,'
';

}

#对象重载

public function __toString(){

#返回一个指定字符串(一般是当类有属性保存某些信息时,输出某个属性) return __METHOD__;

}

}

$m = new Man();

# var__dump($m->age);

# var__dump($m->gender);

#$m->name;

#写入数据

# $m->age++;     #系统不理解为设置,而是读取:因此会走 _get()

/*$m->age = 12;

$m->gender = ' Male ';

var_dump( $m);*/

#判定属性

#var_dump(isset($m->age));

#删除属性

#unset($m->age);

#直接输出对象

echo $m;

图片17.png

就可以在里面写好哪些东西是可以输出的,比如说对象可以把属性某一个给组装起来,或者组装成一条指令、代码或字符块,这样 echo 系统就不会出错。自从做了属性之后,凡是和属性操作甚至对象的直接输出相关的所有错误都不存在,都不会报错,但是外面是否能拿到正确的结果取决于内部的实现,做好了外部就可以用,没做好外部依然看不到正确结果,但是不会报错。


四、小结

1、PHP 中属性重载是为了保证数据的安全性,不让代码出现一些操作性错误。

2、PHP 重载机制 _get() 和 _set() 也可以理解为统一为属性设置访问和设置方法(便捷)。一般在 Java 里增加一个属性之后系统会额外增加两个方法,分别为 get 方法和 set 方法,但不是每一个属性都需要增加,针对属性需要传一个名字进去对应的类型限定。

3、属性重载也能有效保证对象结构,不会让用户无限增加对象属性。有了 _set() 之后就不能再添加对象,即使加了属性系统也不认。这样对象的属性就不会无限增加,因为增加越多对象就越慢,数据越大,本身内存的访问效率就比较低。

4、一般情况下系统内部使用的类如果不是特殊情况不需要使用到属性重载,如果类是对外提供操作的那么应该增加相应的重载机制以防出错。

相关文章
|
3月前
|
存储 Java 数据库连接
php学习笔记-代码基本语法-day01
本文是关于PHP编程语言的基础语法学习笔记,内容包括PHP的介绍、注释风格、数据类型、命名规范、常量和变量的使用,以及变量和常量相关的常用函数。文中详细解释了PHP的基本语法元素和一些易混淆的概念,如传值赋值与传址赋值、可变变量,以及如何检查变量是否已定义或为空。
php学习笔记-代码基本语法-day01
|
3月前
|
JavaScript 前端开发 安全
php学习笔记-普通表单参数提交获取及页面的重定向和一个登录小demo-day05
本文介绍了PHP中普通表单参数的提交获取、页面重定向的方法,并通过一个登录示例演示了表单参数的封装和页面跳转处理。
|
3月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
3月前
|
存储 API PHP
php学习笔记-php数组的创建和使用,数组常用函数-day03
关于PHP数组的创建、使用以及常用函数的详细学习笔记。
php学习笔记-php数组的创建和使用,数组常用函数-day03
|
3月前
|
JavaScript Java PHP
php学习笔记-php运算符,类型转换,打印输出语句相较于其他语言的特殊部分-day02
本文是第二天的PHP学习笔记,涵盖了PHP中运算符的使用、类型转换方式,以及打印输出语句的特点,展示了其相较于其他编程语言的一些特殊之处。
php学习笔记-php运算符,类型转换,打印输出语句相较于其他语言的特殊部分-day02
|
3月前
|
SQL 关系型数据库 MySQL
php学习笔记-连接操作mysq数据库(基础)-day08
本文介绍了PHP中连接操作MySQL数据库的常用函数,包括连接服务器、设置字符集、关闭连接、选择数据库、结果集释放、获取影响行数以及遍历结果集等操作。通过书籍查询的实例演示了如何使用这些函数进行数据库操作,并提供了一个PHP操纵MySQL数据库的模板。
php学习笔记-连接操作mysq数据库(基础)-day08
|
3月前
|
前端开发 PHP
php学习笔记-php文件表单上传-day06
本文介绍了PHP文件上传处理流程、预定义变量`$_FILES`的使用、文件上传状态代码以及文件上传实现函数。同时,通过一个文件上传的小例子,演示了文件上传表单的创建、文件上传表单处理的PHP页面编写以及运行测试输出。
php学习笔记-php文件表单上传-day06
|
3月前
|
JavaScript 程序员 PHP
php学习笔记-php自定义函数-day05
本文介绍了PHP自定义函数的创建、调用、参数赋值以及作用域和生命周期,还探讨了`global`和`static`关键字的使用,以及`return`、`exit`和`die`的不同用法。
|
3月前
|
XML SQL PHP
php学习笔记-php字符串及字符串常用函数总结-day04
本文总结了PHP中字符串的三种定义方式和常用字符串处理函数,包括字符串的修剪、转换、长度计算、子串操作、比较、连接、分割及替换等操作。
|
PHP 数据库
PHP:pdo连接数据库获取分区名称及属性信息
PHP:pdo连接数据库获取分区名称及属性信息
66 0