前言:这个章节主要分享一些高级的PHP面向对象的知识
(一) 两种常见的设计模式(单例和工厂模式)
<?php // class A{ private static $_obj;//定义了一个 静态的 私有的 属性 //将构造方法私有化,使得无法在类的外部使用new关键字实例化这个类的对象 private function __construct(){ } private function __clone(){ } //定义一个共有的 静态的 方法single public static function single(){ //判断$_obj静态私有属性是否保存了一个本类的对象 if( empty(self::$_obj) ){//如果$_obj为空,则表示之前没有创建过本类的对象 self::$_obj = new self; } return self::$_obj; } }
2.工厂模式
<?php class Factory{ public static function produce($className){ if( $className=='A' ){ include './A.class.php'; }elseif( $className=='B' ){ include './B.class.php'; } $obj = new $className; return $obj; } } $a1 = Factory::produce('A'); var_dump( $a1 ); echo '<hr/>'; $b1 = Factory::produce('B'); var_dump( $b1 );
(二) 对象遍历
引言:
1.默认的对象遍历
<?php class A{ public $name='zhangsan'; public $age=12; public $height=1.8; } $a1 = new A; var_dump( $a1 ); echo '<hr/>';echo '<hr/>'; //实现使用foreach对对象进行遍历 foreach( $a1 as $k=>$v ){ echo '$k:'; var_dump( $k ); echo '<br/>'; echo '$v:'; var_dump( $v ); echo '<hr/>'; }
//小结:默认的对象遍历,就是逐个的获得对象中的属性(属性名和属性值);
2.自定义对象遍历
自定义对象遍历的概念:当遍历一个对象时,PHP自动按顺序执行预定义接口Iterator中实现的五个方法
<?php class A implements Iterator{ public $count=0; public function current(){ echo 'current<br/>'; } public function key(){ echo 'key<br/>'; } public function next(){ echo 'next<br/>'; } public function rewind(){ echo 'rewind<br/>'; } public function valid(){ $this->count++; if( $this->count<4 ){ echo 'valid<br/>'; return true; }else{ return false; } } } $a1 = new A; var_dump( $a1 ); echo '<hr/>'; foreach( $a1 as $k=>$v ){ }
小结:
-
-
第二次以后会按照 valid->current->key->next这个顺序循环执行4个被实现的方法;
(三) 对象序列化
涉及的函数:
<?php class DirTool{ public $path; public $resource; public function __construct(){ $this->path = './dir'; $this->resource = opendir($this->path); } } $d = new DirTool; var_dump( $d ); echo '<hr/>'; //将$d对象进行序列化,获得序列化之后的字符串结果 $str = serialize($d); var_dump( $str );
-
经过序列化之后的对象,变成了一个具有一定格式的字符串。
-
<?php class DirTool{ public $path; public $resource; public function __construct(){ $this->path = './dir'; $this->resource = opendir($this->path); } //__sleep魔术方法 当基于该类的对象被序列化的时候,__sleep魔术方法将被触发执行 public function __sleep(){ //echo 100; return ['path'];//不在数组中的属性名,将会被排除在序列化操作之外 } } $d = new DirTool; var_dump( $d ); echo '<hr/>'; //将$d对象进行序列化,获得序列化之后的字符串结果 $str = serialize($d); var_dump( $str );
-
PHP不负责定义__sleep魔术方法,只负责调用该魔术方法;
-
调用该魔术方法的时机是:当使用serialize函数序列化一个对象时,该类中的__sleep魔术方法将会被触发自动执行;
-
在__sleep魔术方法中,可以同return语句指定乃个属性应该参与到序列化的过程中来,不在数组中的属性都将被排除在序列化的过程之外;
反序列化
涉及的函数:
<?php $str = 'O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}'; //将序列化后的字符串进行反序列化,还原回对象 $obj = unserialize($str); var_dump( $obj );
<?php class DirTool{ public $path; public $resource; public function __construct(){ $this->path = './dir'; $this->resource = opendir($this->path); } } $str = 'O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}'; //将序列化后的字符串进行反序列化,还原回对象 $obj = unserialize($str); var_dump( $obj );
-
我们可以使用unserialize函数对序列化后的字符串结果进行反序列化;
-
反序列化有一个前提,在反序列化的过程中,必须存在该对象的原始类的定义,否则将会把还原的对象归到一个系统类__PHP_Incomplete_
<?php class DirTool{ public $path; public $resource; public function __construct(){ $this->path = './dir'; $this->resource = opendir($this->path); } //__wakeup魔术方法 public function __wakeup(){ $this->resource = opendir($this->path); } } //$str = 'O:7:"DirTool":2:{s:4:"path";s:5:"./dir";s:8:"resource";i:0;}'; $str = 'O:7:"DirTool":1:{s:4:"path";s:5:"./dir";}'; var_dump(unserialize($str));
-
我们在__wakeup魔术方法中所作的操作,其实就是将之前排除的属性重新进行赋值操作;
-
PHP不负责定义__wakeup魔术方法,只负责调用该魔术方法;
-
调用该魔术方法的时机是:当使用unserialize函数反序列化一个字符串时,该类中的__wakeup魔术方法将会被触发自动执行;
(五) 命名空间
#关键字为namespace namespace 空间名;
命名空间的使用
<?php namespace first; function f1(){ echo 100; } namespace second; function f1($v1){ echo 200; }
f1();//就近原则,不限定名称访问
firstf1();// 限定命名空间的访问 echo '嘿嘿嘿嘿,能看到我么';
命名空间的引入
//空间的引入,接上一个方法
use first;
f1();
小结 :
1.命名空间都是在全局空间下的
2.命名空间如果需要用到另外的空间需要用use引入才可以使用