设为首页 收藏本站
查看: 681|回复: 0

[经验分享] PHP 类的魔术方法及类的自动加载

[复制链接]

尚未签到

发表于 2015-8-24 07:19:43 | 显示全部楼层 |阅读模式
  类的模式方法都是 public 的,以 两个下划线开头,在某些情况下自动被调用,有点类似 hook 或者 事件触发。
  魔术方法的传参方式不能使用引用。
  
  __construct() :
  构造函数,实例化对象时调用,可以接收传入的参数
  
  __destruct():
  析构函数,对象被注销、脚本结束、对象的所有引用被删除时调用(垃圾回收),该函数不能接收参数,析构函数可以在代码中被显示调用,但是不建议这样做,应该由系统在垃圾回收时自动调用。
  
   __call(string methodName, array arguments):
  试图调用一个不存在的方法时被调用,这在 PHP 框架的路由设计中很有用,比如 传了一个错误的路径解析出一个不存在的 action,或者是某种有意设计成的路劲规则 ,可以用该方法灵活处理:按路劲的信息直接指向某个文件或跳转到错误页面。

  
   static __callStatic(string methodName, array arguments):
  试图调用一个不存在的静态方法时调用,这个方法应该声明为静态方法。
  
   __get(string key):
  试图通过对象访问一个不能访问的属性(不存在的属性或保护、私有属性)时被调用,应该返回一个值。
  例如  $obj->key ; //key 属性不存在或不是 public 是就会触发 __get(),并获得返回值(或者你也可以直接抛出错误,或做其他处理)
  如果使用 empty() 来检测一个对象通过 __get() 方法返回的属性值,将得到 true, 而 isset() 的检测将得到 false.
  
  __set(string key):
  试图通过对象为一个不能访问的属性赋值时被调用,该方法的返回值被忽略。
  
   __isset(string key) :
  当使用 isset() 或 empty() 检测一个无法在外部访问的对象属性时被触发,应当返回 bool 值。
  
  __unset(string key) :
  对一个无法在外部访问的对象属性使用 unset() 注销时被触发
  
  __sleep() :
对一个对象进行使用 serialize() 序列化时被调用,返回一个以属性名称为元素的数组告诉脚本应该保存对象的哪些属性值。

__wakeup():
对一个对象系列化字符串( 通过 serialize($obj)得到的字符串 )使用 unserialize() 反序列化时被调用。



class Connection {
protected $link;
private $server, $username, $password, $db;
public function __construct($server, $username, $password, $db)   {
$this->server = $server;
$this->username = $username;
$this->password = $password;
$this->db = $db;
$this->connect();
}
private function connect()  {
$this->link = mysql_connect($this->server, $this->username, $this->password);
mysql_select_db($this->db, $this->link);
}
public function __sleep()   {//系列化时只需保存这些属性的值
return array('server', 'username', 'password', 'db');//必须返回一个数组
    }
public function __wakeup()  { //反系列化得到对象后立即连接数据库
$this->connect();
}
}
  
__toString():
试图将对象作为一个字符串使用时被调用,返回一个字符串,类似 js 对象的 toString()

__invoke():
将一个对象作为函数调用时被调用。如
  $object($a,$b) 将调用  $object->__invoke($a,$b)

__set_state() :
对一个对象使用 var_export() 时被调用,其返回值将被打印,可以接受一个 key-value 数组参数,用于在打印对象结构时格式化对象属性的值,key 为对象属性名.
  
  __clone():
  对 一个对象使用 clone 操作时被调用,无返回值,该方法可用于 在返回 clone 得到的对象之前修改其属性使得 clone 得到的对象与 被操 作的对象属性值可以不同,但并不能通过返回 null 或 false 来阻止 对象克隆操作, clone 操作得到的对象不是通过该方法的返回值返回 的。
  
  一些注意事项:
  __get、__set 方法可常用于灵活处理 对象私有属性、保护属性的访问。
  由于 PHP 对象对于的方法使用 isset() 或 empty() 判定时,不会认为 方法是一个可访问的属性(写多了 javascript 要注意了,PHP 里面 属性就是属性方法就是方法不可混淆)
  
  在使用 __get 时 ,你可能会在该方法中对属性使用 isset($this->key) 判断,尤其是要特别处理 私有属性的时候,这时要注意 __set() 有没有定义以及如何定义以免出现误判。
  
  如果一个对象的方法在调用时不需要传参,或者传参是固定的,可以通过 __get() 方法来将方法属性化,在 __get() 里面自动调用该方法并将值返回。
  比如 在类内定义 __get 方法如下:



public function  __get($key){
if(property_exists($this,$key)){
return $this->$key; //私有、保护属性允许访问

}else if(method_exists($this,'get'.$key)){
return $this->{'get'.$key}();  
//或者....
// $methodName = 'get'.$key;   
//return $this-> $methodName();

}else{
thrown new Exception('class '.__class__.' do not has property '.$key);
}
}

//方法属性化访问:
$obj->getModelName();
$obj->ModelName; //属性化
  
  unserialize() 方法:当试图反序列化一个对象时,该函数需要知道对象的 类,如果这个系列化字符串从其他方式得来,脚本环境中没有定义对象的类,就需要将类的文件引入,unserialize() 第二个参数是可选的 callback 型参数,用于引入类所在的文件。



function importClass($calssName){
include('xxxx.php');  //包含该类的文件

}
unserialize($objstr,$callbackName);
  
  类的自动加载: __autoload()
  __autoload() 是PHP执行环境中约定的一个函数而非某个类的方法,如果一个类在使用之前没有加载到当前文件,会自动调用 __autoload() 函数来加载该类,通常这些类的加载规则都是约定的,比如这些类包含在以类名命名的文件内,该方法可以实现类的按需加载,避免脚本执行前加载不必要的类从而降低资源占用、提交性能。
  注意:__autoload() 内的错误不能被 try-catch 捕获。




function __autoload($class_name){
require_once(PATH.'/calsses/'.$class_name.'.php');
}
$obj1 = new mycalss1();
  
  注册 __autoload() 自动调用的函数:
  spl 代码库在 PHP5.0 之后默认自动启用
  spl_autoload_register([callback]); //不将具体实现的加载代码写在 __autoload() 内,可使用该函数注册回调函数。
  如果使用类的方法作为回调函数需要传入一个数组:
  spl_autoload_register(array('class_name'|$obj,'method_name'));
  例如:



spl_autoload_register(array($this,'autoloadClass'));
spl_autoload_register(array('YiiBase','autoload'));// YII 框架的自动加载类的实现, YiiBase 类实现了一个autoload 方法。
  spl_autoload_register() 可以注册多个加载函数,成功加载类文件之前将逐个尝试所有注册的加载函数。这在不同的类使用不同逻辑来导入类文件的时候很有用。
  spl_autoload_unregister(); //取消某个注册的加载函数,参数与 spl_autoload_register() 相同.
  spl_autoload_functions();// 以数组形式返回所有注册的 __autoload() 函数
  
  spl_autoload(class_name[,file_extentions]); // __autoload() 函数的默认实现。 spl_autoload_register() 被调用时如果没有传入 函数名,则默认使用该函数,该函数的执行规则是: 类名转为小写作为文件名,传入的 file_extentions(多个扩展名以逗号隔开,默认为 .inc 和 .php)为扩展名,根据得到的文件名尝试在 php.ini 内设置的 include paths 中搜索。
  
  spl_autoload_call(class_name);//手动调用所有注册的 __autoload() 函数来主动加载类文件
  spl_autoload_extentions([file_extentions]); //注册或返回 spl_autoload() 中可以使用的文件扩展名,扩展名可以是 .a.b 这样的形式,例如:
  



spl_autoload_extentions(".class.php");
spl_autoload_register(); //使用spl_autoload() 来尝试自动加载类文件
//这样 spl_autoload('myclassName'); 会尝试加载 文件 "myclassName.class.php" .
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-103192-1-1.html 上篇帖子: java解析php函数json_encode unicode 编码问题 下篇帖子: PHP面向对象的进阶学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表