php面向对象-一揽子方案
PHP-OOP1(万物皆对象!)-编程思想,类,属性,方法
一、编程思想:计算机解决实际问题的一种思维方式。
PHP是同时支持面向过程和面向对象两种编程思想的语言。
面向对象的核心思想是:不仅仅简单的将某些功能进行封装(封装成函数),更是对调用该功能的主体进行封装,实现某个
主体拥有多个功能,在使用的过程中,先得到对应的主体,再使用主体去实现相关的功能!
面向过程---自顶向下,逐步细化
面向对象---在编程的时候尽可能的模拟现实世界!
面向过程写代码,需要实现哪些功能以及如何去实现---1调用系统函数,2用户自定义函数,3流程控制(整体调度)
面向对象写代码,首先想到的是应该有什么样的主体去完成什么样的功能,再把该主体的属性和功能进行封装,再去实现该主体的功能!
面向对象与面向过程的区别
- 都可以实现代码重用和模块化编程,面向对象的模块化更深,数据更封闭,也更安全
- 面向对象的思维方式更加贴近于现实生活,也容易解决大型复杂的业务逻辑
- 从前期开发的角度看,面向对象比面向过程更复杂,但是,从维护和扩展功能的角度来看,面向对象要远比面向过程要简单!
二、1.面向对象三阶段OOA,OOD,OOP----------OOP:面向对象编程
对象是采用属性(property)来保存数据!
对象是采用方法(method)来管理数据!
对象是由类实例化而来的!
强调:无论在哪里,访问成员的属性和方法都要先找到其对象才可以!
二、2.1类的定义类就是具有相同或相似的特征特性的一组事物的一个通用的名称!
使用class关键字来定义!
2.2类的组成定义一个类,其实就是定义三种类成员:定义属性(变量),定义方法(函数),定义类常量(常量)
2.3类的实例化语法形式是:new
类名;
几点需要注意的地方:
1.属性和方法都需要进行声明才可以使用!(采用访问控制修饰限定符来声明public,proteced,private)
2.public可以用var来代替,只是对低版本的一种兼容!
3.方法的前面可以省略掉访问控制修饰限定符,默认的就是public
4.在定义类的时候,属性的值默认是NULL型,但是如果给属性赋上一个初始值,必须是“直接值”,不能是表达式计算之后的值!
//例:定义一个类
Class Student{
public $stu_name;
public $stu_money=30000;
public function payMoney(){
echo $this->stu_name,"刚交完",$this->stu_money,"学费,要好好学习";
} //this调用当前对象
}
$stu=new Student;//类的实例化
$stu->stu_name="鸣人";//访问对象的属性
$stu->payMoney();//调用对象的方法(方法必须有对象来调用才能执行,否则找不到方法)
//执行结果: 鸣人刚交完30000学费,要好好学习
3.类成员的访问使用箭头
->实现对象对对象成员的访问!
属性不能在方法内直接访问,需要找到其对象才能访问,典型的做法就是,在方法内使用this来代替当前对象的名称!
调用方法时,必须先通过对象找到所属类,然后再找到相应方法
打印实例时,为什么只能打印出属性而打印不出方法?
方法属于公共代码,存储在用户代码区,由类管理。而属性属于每个实例,由实例管理,3空间如下
类---------类空间---------类常量
类---------用户代码区-----方法
对象-------对象空间-------属性
4.面向对象的编程思想和过程
第一步:找到所有的实体
第二步:定义相关的类
第三步:实例化对象并初始化
第四步:执行相应的功能
5.构造方法
在实例化一个对象的时候,PHP会自动的调用一个名字叫作__construct()的方法,该方法由于专门负责对新对象进行初始化,称之为“构造方法”!
在实例化一个对象的时候,顺便在类名的后面增加一些用括号括起来的参数列表(可以理解为构造方法的实参)
创建初始化方法和构造方法
Class Student{
public $stu_name;
public $stu_money;
public function payMoney(){
echo $this->stu_name,"刚交完",$this->stu_money,"学费,要好好学习";
}
// public function init($m,$n){ //创建一个专门对对象的属性初始化的方法
// $this->stu_name=$n;
// $this->stu_money=$m;
// }
public function __construct($m,$n){ //构造方法
$this->stu_name=$n;
$this->stu_money=$m;
}
}
// $stu1=new Student;//类的实例化
// $stu1->init(30000,"鸣人");
// $stu1->payMoney();//调用对象的方法
echo "<br>";
$stu2=new Student(50000,"佐助");//类的实例化
$stu2->payMoney();//调用对象的方法
可兼容旧版本的构造方法书写方式:
public function __construct($n,$a,$m){
$this->Student($n,$a,$m);
}
public function Student($n,$a,$m) {
$this->stu_name = $n;
$this->stu_age = $a;
$this->stu_money = $m;
}
6.析构方法
主要的作用就是用于释放对象所占用的额外的资源!而不是对象本身!
析构方法的名字叫作__destruct(),注意,里面不能有任何的参数!在对象消失之前调用。因此还能使用$this!
对象消失的几种情况
1、include,include_once,requice,requice_one常规加载
2、__autoload() 3、spl_autoload_register() 函数名:__autoload() 触发情况:当php找不到类文件的时候//注意触发条件,如果本页面内有该类名,无法加载 function __autoload($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } $stu=new Studet; //本页无Student类,则会自动去Student.class.php中找Student类。 为何要使用自定义的类文件自动加载函数? 因为随着项目的扩展,可能后期会出现多个自动加载函数,这时候就出现了函数的重名问题,因此我们要自己注册自动加载函数 八-9.1注册其他的自动加载函数 实现步骤:第一步:定义一个可以加载类文件的普通函数 第二步:使用spl_autoload_register(函数名)来实现注册spl_autoload_register(‘函数名’); 注意: 1.注册一定要发生在需要某个类之前 2.可以注册多个,在需要的类文件载入成功之前,系统会依次调用 3.一旦注册成功,系统默认的__autoload就会失效,如果想继续使用,就需要像注册其他普通函数一样重新注册 function f1($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } spl_autoload_register("f1"); $obj=new A;//本页无A类,则会自动去A.class.php中找A类。 八-9.2 注册自动加载方法 在面向对象的编程风格中,我们一般会将用户自定义的自动加载函数封装到一个类中! 1如果自动加载函数为静态方法 语法形式1为spl_autoload_register(array(类名,方法名))spl_autoload_register(array("Common","hhh")); 语法形式2为spl_autoload_register("类名::方法名")spl_autoload_register("Common::hhh"); 2如果自动加载函数为非静态方法 先实例化对象,再注册。语法形式为spl_autoload_register(array(对象,"方法名")) $stu=new Common; spl_autoload_register(array($stu,"hhh")); class Common{ //public static function hhh($class_name){ public function hhh($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } } // spl_autoload_register(array("Common","hhh")); //静态方法注册 $stu=new Common; //1实例化方法对象并注册该方法 spl_autoload_register(array($stu,"hhh"));//非静态方法注册 $obj = new A; //2自动去A.class.php中找A类,这样就可以使用A类中的函数了。 PHP-OOP3(继承、封装、多态,重写、final、abstract、interface ) 一、类的继承面向对象的三大特性之一:继承性!利于代码的扩展和重用 伟大的程序员都懒!都要在两个字上下功夫:”简”,”易”! 继承:一个类从另外一个已有的类获得其成员特性,就叫作继承!extends 几个概念:派生,父类(基类)parent、子类(派生类)、扩展、单继承、继承链条 单继承:在PHP中,一个类只能继承自一个其他的类,不同同时继承多个类,单继承也是大多数面向对象语言的特性(C++支持多继承) 几点强调
} } $stu=new Student; $stu->set_age(10.5);//调用类中公开的接口 //echo $stu-> stu_age;//报错! Fatal error: Cannot access private property Student::$stu_age,改为public则可以访问 var_dump($stu);//非法的年龄信息…… //可以有效控制用户的行为--封装优点 //当set_age()10;时object(Student)#1 (2) { ["stu_age":"Student":private]=> int(10) ["stu_name":"Student":private]=> NULL },可以看到但类外不能访问 四、提高MySQLDB类的封装性 私有化属性,私有化方法 给MySQLDB类增加三个公开的方法: fetchAll:得到所有的记录(比较适合查询结果是多行多列的情况) fetchRow:得到一条记录(比较适合查询结果是单行的结果集) fetchColumn:得到一条记录的第一个字段(比较适合查询结果是单行单列的结果集) 五、final最终类 类有两个“极端”: final类:也叫作最终类,不能被继承,只能实例化对象 final最终类其实就是实际开发过程中的一种语法上的规范! 最终方法final method 当一个类还需要继承,但是不希望该类中的某些方法被重写,可以使用最终方法。 当该类被其他的类所继承的时候,该最终方法不能被重写! 六、abstract类:抽象类,不能实例化对象,只能被继承 抽象类其实就是不完整的类,所以无法实例化一个真实的对象!需要下一级的类去实现(完善方法体)! 而继承它的类也只有两种选择:1要么完成父类(抽象类)中的抽象方法(完善方法体)2要么继续做抽象类! abstract class Animal{ public function move(){ } } class Bird extends Animal{ public function move(){ echo "I can fly!<br/>"; } } class Snake extends Animal{ public function move(){ echo "I can creep!<br/>"; } } $bird=new Bird; $bird->move();//I can fly! $snake=new Snake; $snake->move();//I can creep! 特别强调
class Math{ //PHP不支持重载,但是可以利用其它方式实现类似重载的功能。 public function __call($name,$arr){ if ($name=="f1") {//判断用户调用的方法是否为f1 $length=count($arr);//根据参数的额个数进行业务逻辑处理 if ($length<1||$length>3) { echo "非法的参数个数"; }elseif ($length==1) { return $arr[0]*$arr[0]; }elseif ($length==2) { return $arr[0]*$arr[0]+$arr[1]*$arr[1]; }elseif ($length==3) { return $arr[0]*$arr[0]*$arr[0]+$arr[1]*$arr[1]*$arr[1]+$arr[2]*$arr[2]*$arr[2]; } } } } $obj=new Math; echo $obj->f1(10); //100 echo "<br/>"; echo $obj->f1(10,20); //500 echo "<br/>"; echo $obj->f1(10,20,30);//36000 二、MySQLDB类的重载 完善属性重载:完善__set(),完善__get(),完善__unset(),完善__isset() 完善方法重载:MySQLDB类的单例模式 第一步:增加一个私有的静态属性,用于保存对象 第二步:把构造方法私有化 第三步:增加一个获得单例的公共方法 第四步:私有化克隆魔术方法 三、后期静态绑定 1、$this是不是永远代表其代码所在类直接实例化出来的对象?不是,$this是要根据上下文的执行环境来决定的! 2、self是不是永远代表其代码所在类的类名?回答:是 总结一下static的功能,一共有三个了:
六、1、数据的存储 也就是数据被持久化!一般的,可以将数据存放到数据库或者文件磁盘介质中! 当PHP脚本运行结束的时候,内存中的数据都会丢失,脚本的资源也都会消失(包括脚本中的数据),所以,如果想 实现数据存储,就应该在脚本运行结束之前进行数据的持久化! 在将数据自动转换成字符串的时候,同时在字符串内记录原数组的值和类型等相关的信息,目的就是在 得到数据的时候,能根据存储的信息(包含数据类型)转换成原始数据! 这个工作就是由数据的序列化与反序列化来完成的! 2、数据的序列化与反序列化 数据的序列化: 将原始数据转换成可以用于保存和传输的字符串数据!(不仅仅记录原数组的值,还记录原数据的类型等相关信息) serialize():序列化---在数据存放到文件之前先进行序列化: 数据的反序列化:将序列化后的字符串数据,转换成原始数据! unserialize():反序列化---在读取数据之前进行反序列化: 注意: 数据的序列化与反序列化适用于除了资源类型之外的任何的数据类型!包括对象和字符串本身! 1在将对象存储到文件之前进行序列化操作,在输出对象之前进行反序列化时对象数据有问题? 反序列化的时候,也需要先找到对象所属的类,如果找不到,则对象会被反序列化成一个名字叫作__PHP_Incomplete_Class的类!这是一个系统预定义的类! 解决方案:只需要在反序列化的时候找到这个对象所属的类就行了:手动载入!或自动载入! 2序列化的时候,资源型的属性$link被转换成了整型数据0! 解决方法:在序列化的时候不存储资源型数据,在反序列化的时候再打开相应的资源! __sleep() 是在序列化一个对象的时候自动调用!该方法用于规定哪些属性应该被序列化,实现的方式为: 返回一个索引数组,数组内的元素为需要被序列化的属性名的集合! __wakeup()是在一个对象反序列化的时候自动调用的!主要用来对对象进行相关的初始化操作!
//在MySQLDB类中增加魔术方法__sleep()和__wakeup() public function __sleep(){ return array("host","port","user","pass","charset","dbname"); } public function __wakeup(){//初始化数据库三部曲 $this->my_connect();//连接数据库 $this->my_charset();//选择默认字符集 $this->my_dbname();//选择默认的数据库 }
function __autoload($class_name){//系列化 if (file_exists("./".$class_name.".class.php")) { include_once "./".$class_name.".class.php"; }else{ die("系统错误,没有找到相关的类!"); } } $arr=array( "pass"=>"123456", "dbname"=>"whereit" ); $data=MySQLDB::getInstance($arr); echo "<pre>"; var_dump($data); $s_data=serialize($data);//写入文件之前先将数据进行序列化 echo file_put_contents("./38.txt",$s_data);//返回值是写入的字符串的长度
function __autoload($class_name){//在反序列化的时候找到这对象所属的类就行:手动载入!自动载入! if (file_exists("./".$class_name.".class.php")) { include_once "./".$class_name.".class.php"; }else{ die("系统错误,没有找到相关的类!"); } } $data=file_get_contents("./38.txt"); $u_data=unserialize($data);//在读数据之前进行反序列化 echo "<pre>"; var_dump($u_data); PHP-OOP5(类的魔术方法、魔术常量、对象遍历,类型约束,类和对象的相关函数 ,命名空间) 一、魔术方法:名字由系统定义,而方法体由用户自己编写的方法! 最大特点是:不需要用户手动调用,而是当特定的情况发生时,系统自动调用相关的魔术方法! 注意:__autoload不算是魔术方法,但是其语法形式很类似于魔术方法! 类的魔术方法 __construct(),__destruct(),__clone(),__get(),__set(),__unset(),__isset(),__call(),__callstatic(),__sleep(),__wakeup() __invoke() 当我们把对象当做一个函数(或方法)来调用的时候,会自动执行该魔术方法 之所以可以使用匿名函数$func闭包对象成功地调用函数,就是因为闭包对象里面有一个__invoke魔术方法 __toString() 当我们把一个对象当成是一个字符串来使用的时候,会自动的执行该模仿方法! public function __toString(){ return serialize($this);}//返回值可以是该对象序列化成字符串的结果! 二、类的魔术常量 __LINE__ 文件中的当前行号 __TRAIT__trait的名称,trait是PHP实现代码复用的一种方法,类似于接口。(5.4开始支持) __CLASS__:代表的是当前的类名! 注意与self的区别:例return new __CLASS__;是错误的,无法new self是指该类的本身(一种结构,不仅仅包括类名),而__CLASS__只是一个类名(类名只是类的一部分!) 但是:$classname=__CLASS__; return new $classname;是可以new的,这里是可变类名的一种语法。 __METHOD__:代表当前的方法名!---在类里echo __METHOD__;//结果A::showCLassName __FILE__文件的完整路径和文件名, __DIR__文件所在的目录 __FUNCTION__函数的名称 __NAMESPACE__当前命名空间的名称 三、对象的遍历使用foreach语句! 对象的自定义遍历
-
- 明确的使用unset函数销毁一个变量
- 脚本运行结束之后,也会自动销毁
- 改变对象变量的值,也会自动销毁
1、include,include_once,requice,requice_one常规加载
2、__autoload() 3、spl_autoload_register() 函数名:__autoload() 触发情况:当php找不到类文件的时候//注意触发条件,如果本页面内有该类名,无法加载 function __autoload($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } $stu=new Studet; //本页无Student类,则会自动去Student.class.php中找Student类。 为何要使用自定义的类文件自动加载函数? 因为随着项目的扩展,可能后期会出现多个自动加载函数,这时候就出现了函数的重名问题,因此我们要自己注册自动加载函数 八-9.1注册其他的自动加载函数 实现步骤:第一步:定义一个可以加载类文件的普通函数 第二步:使用spl_autoload_register(函数名)来实现注册spl_autoload_register(‘函数名’); 注意: 1.注册一定要发生在需要某个类之前 2.可以注册多个,在需要的类文件载入成功之前,系统会依次调用 3.一旦注册成功,系统默认的__autoload就会失效,如果想继续使用,就需要像注册其他普通函数一样重新注册 function f1($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } spl_autoload_register("f1"); $obj=new A;//本页无A类,则会自动去A.class.php中找A类。 八-9.2 注册自动加载方法 在面向对象的编程风格中,我们一般会将用户自定义的自动加载函数封装到一个类中! 1如果自动加载函数为静态方法 语法形式1为spl_autoload_register(array(类名,方法名))spl_autoload_register(array("Common","hhh")); 语法形式2为spl_autoload_register("类名::方法名")spl_autoload_register("Common::hhh"); 2如果自动加载函数为非静态方法 先实例化对象,再注册。语法形式为spl_autoload_register(array(对象,"方法名")) $stu=new Common; spl_autoload_register(array($stu,"hhh")); class Common{ //public static function hhh($class_name){ public function hhh($class_name){ if (is_file("./$class_name.class.php")) { include_once("./$class_name.class.php"); }else{ die("./$class_name.class.php不存在"); } } } // spl_autoload_register(array("Common","hhh")); //静态方法注册 $stu=new Common; //1实例化方法对象并注册该方法 spl_autoload_register(array($stu,"hhh"));//非静态方法注册 $obj = new A; //2自动去A.class.php中找A类,这样就可以使用A类中的函数了。 PHP-OOP3(继承、封装、多态,重写、final、abstract、interface ) 一、类的继承面向对象的三大特性之一:继承性!利于代码的扩展和重用 伟大的程序员都懒!都要在两个字上下功夫:”简”,”易”! 继承:一个类从另外一个已有的类获得其成员特性,就叫作继承!extends 几个概念:派生,父类(基类)parent、子类(派生类)、扩展、单继承、继承链条 单继承:在PHP中,一个类只能继承自一个其他的类,不同同时继承多个类,单继承也是大多数面向对象语言的特性(C++支持多继承) 几点强调
-
- 属性和方法都可以被继承
- 继承的本质,不是把父类中的代码复制到子类的内部,而是通过继承链条,找到相应的成员!
} } $stu=new Student; $stu->set_age(10.5);//调用类中公开的接口 //echo $stu-> stu_age;//报错! Fatal error: Cannot access private property Student::$stu_age,改为public则可以访问 var_dump($stu);//非法的年龄信息…… //可以有效控制用户的行为--封装优点 //当set_age()10;时object(Student)#1 (2) { ["stu_age":"Student":private]=> int(10) ["stu_name":"Student":private]=> NULL },可以看到但类外不能访问 四、提高MySQLDB类的封装性 私有化属性,私有化方法 给MySQLDB类增加三个公开的方法: fetchAll:得到所有的记录(比较适合查询结果是多行多列的情况) fetchRow:得到一条记录(比较适合查询结果是单行的结果集) fetchColumn:得到一条记录的第一个字段(比较适合查询结果是单行单列的结果集) 五、final最终类 类有两个“极端”: final类:也叫作最终类,不能被继承,只能实例化对象 final最终类其实就是实际开发过程中的一种语法上的规范! 最终方法final method 当一个类还需要继承,但是不希望该类中的某些方法被重写,可以使用最终方法。 当该类被其他的类所继承的时候,该最终方法不能被重写! 六、abstract类:抽象类,不能实例化对象,只能被继承 抽象类其实就是不完整的类,所以无法实例化一个真实的对象!需要下一级的类去实现(完善方法体)! 而继承它的类也只有两种选择:1要么完成父类(抽象类)中的抽象方法(完善方法体)2要么继续做抽象类! abstract class Animal{ public function move(){ } } class Bird extends Animal{ public function move(){ echo "I can fly!<br/>"; } } class Snake extends Animal{ public function move(){ echo "I can creep!<br/>"; } } $bird=new Bird; $bird->move();//I can fly! $snake=new Snake; $snake->move();//I can creep! 特别强调
- 如果一个类继承自一个抽象类,而其自身不是一个抽象类,则必须实现父类中的所有的抽象方法!
- 抽象类中,不但可以包括抽象方法,还可以包括其他任意的普通成员(属性、常量、非抽象方法),都可以被子类所继承
- 可以完成普通类的继承,为其他的类提供公共的代码!
- 抽象类往往用于规定子类中必须要完成的方法或者成员,规定子类的方法结构,有时候为了保证完成一系列功能相似的多种操作类的结构一致,我们要求这些类都继承自一个相同的抽象类!
- 实现该接口中所有的公开的抽象方法(完善方法体)
- 如果该类没有实现接口中的部分(或全部)公开的抽象方法,就应该把该类声明成抽象类,然后等待更下一级的类去实现!此时,没有被实现的方法最好继续声明成抽象方法!
- 接口不是类(需要用interface来进行声明,需要其他类用implements实现 ),但抽象类是类(需要class进行声明,需要用extends继承 )
- 从逻辑或结构上看,接口可以看成是抽象类的一个“子集”,比抽象类更“抽象”,只有抽象方法和常量没有其他的普通的方法
- 类只支持单继承,而接口支持多实现。这也是接口和抽象方法的本质区别。
class Math{ //PHP不支持重载,但是可以利用其它方式实现类似重载的功能。 public function __call($name,$arr){ if ($name=="f1") {//判断用户调用的方法是否为f1 $length=count($arr);//根据参数的额个数进行业务逻辑处理 if ($length<1||$length>3) { echo "非法的参数个数"; }elseif ($length==1) { return $arr[0]*$arr[0]; }elseif ($length==2) { return $arr[0]*$arr[0]+$arr[1]*$arr[1]; }elseif ($length==3) { return $arr[0]*$arr[0]*$arr[0]+$arr[1]*$arr[1]*$arr[1]+$arr[2]*$arr[2]*$arr[2]; } } } } $obj=new Math; echo $obj->f1(10); //100 echo "<br/>"; echo $obj->f1(10,20); //500 echo "<br/>"; echo $obj->f1(10,20,30);//36000 二、MySQLDB类的重载 完善属性重载:完善__set(),完善__get(),完善__unset(),完善__isset() 完善方法重载:MySQLDB类的单例模式 第一步:增加一个私有的静态属性,用于保存对象 第二步:把构造方法私有化 第三步:增加一个获得单例的公共方法 第四步:私有化克隆魔术方法 三、后期静态绑定 1、$this是不是永远代表其代码所在类直接实例化出来的对象?不是,$this是要根据上下文的执行环境来决定的! 2、self是不是永远代表其代码所在类的类名?回答:是 总结一下static的功能,一共有三个了:
-
- 定义静态局部变量(和变量的生命周期相关)
- 定义静态成员(静态方法和静态属性)
- 代表“当前类”
六、1、数据的存储 也就是数据被持久化!一般的,可以将数据存放到数据库或者文件磁盘介质中! 当PHP脚本运行结束的时候,内存中的数据都会丢失,脚本的资源也都会消失(包括脚本中的数据),所以,如果想 实现数据存储,就应该在脚本运行结束之前进行数据的持久化! 在将数据自动转换成字符串的时候,同时在字符串内记录原数组的值和类型等相关的信息,目的就是在 得到数据的时候,能根据存储的信息(包含数据类型)转换成原始数据! 这个工作就是由数据的序列化与反序列化来完成的! 2、数据的序列化与反序列化 数据的序列化: 将原始数据转换成可以用于保存和传输的字符串数据!(不仅仅记录原数组的值,还记录原数据的类型等相关信息) serialize():序列化---在数据存放到文件之前先进行序列化: 数据的反序列化:将序列化后的字符串数据,转换成原始数据! unserialize():反序列化---在读取数据之前进行反序列化: 注意: 数据的序列化与反序列化适用于除了资源类型之外的任何的数据类型!包括对象和字符串本身! 1在将对象存储到文件之前进行序列化操作,在输出对象之前进行反序列化时对象数据有问题? 反序列化的时候,也需要先找到对象所属的类,如果找不到,则对象会被反序列化成一个名字叫作__PHP_Incomplete_Class的类!这是一个系统预定义的类! 解决方案:只需要在反序列化的时候找到这个对象所属的类就行了:手动载入!或自动载入! 2序列化的时候,资源型的属性$link被转换成了整型数据0! 解决方法:在序列化的时候不存储资源型数据,在反序列化的时候再打开相应的资源! __sleep() 是在序列化一个对象的时候自动调用!该方法用于规定哪些属性应该被序列化,实现的方式为: 返回一个索引数组,数组内的元素为需要被序列化的属性名的集合! __wakeup()是在一个对象反序列化的时候自动调用的!主要用来对对象进行相关的初始化操作!
//在MySQLDB类中增加魔术方法__sleep()和__wakeup() public function __sleep(){ return array("host","port","user","pass","charset","dbname"); } public function __wakeup(){//初始化数据库三部曲 $this->my_connect();//连接数据库 $this->my_charset();//选择默认字符集 $this->my_dbname();//选择默认的数据库 }
function __autoload($class_name){//系列化 if (file_exists("./".$class_name.".class.php")) { include_once "./".$class_name.".class.php"; }else{ die("系统错误,没有找到相关的类!"); } } $arr=array( "pass"=>"123456", "dbname"=>"whereit" ); $data=MySQLDB::getInstance($arr); echo "<pre>"; var_dump($data); $s_data=serialize($data);//写入文件之前先将数据进行序列化 echo file_put_contents("./38.txt",$s_data);//返回值是写入的字符串的长度
function __autoload($class_name){//在反序列化的时候找到这对象所属的类就行:手动载入!自动载入! if (file_exists("./".$class_name.".class.php")) { include_once "./".$class_name.".class.php"; }else{ die("系统错误,没有找到相关的类!"); } } $data=file_get_contents("./38.txt"); $u_data=unserialize($data);//在读数据之前进行反序列化 echo "<pre>"; var_dump($u_data); PHP-OOP5(类的魔术方法、魔术常量、对象遍历,类型约束,类和对象的相关函数 ,命名空间) 一、魔术方法:名字由系统定义,而方法体由用户自己编写的方法! 最大特点是:不需要用户手动调用,而是当特定的情况发生时,系统自动调用相关的魔术方法! 注意:__autoload不算是魔术方法,但是其语法形式很类似于魔术方法! 类的魔术方法 __construct(),__destruct(),__clone(),__get(),__set(),__unset(),__isset(),__call(),__callstatic(),__sleep(),__wakeup() __invoke() 当我们把对象当做一个函数(或方法)来调用的时候,会自动执行该魔术方法 之所以可以使用匿名函数$func闭包对象成功地调用函数,就是因为闭包对象里面有一个__invoke魔术方法 __toString() 当我们把一个对象当成是一个字符串来使用的时候,会自动的执行该模仿方法! public function __toString(){ return serialize($this);}//返回值可以是该对象序列化成字符串的结果! 二、类的魔术常量 __LINE__ 文件中的当前行号 __TRAIT__trait的名称,trait是PHP实现代码复用的一种方法,类似于接口。(5.4开始支持) __CLASS__:代表的是当前的类名! 注意与self的区别:例return new __CLASS__;是错误的,无法new self是指该类的本身(一种结构,不仅仅包括类名),而__CLASS__只是一个类名(类名只是类的一部分!) 但是:$classname=__CLASS__; return new $classname;是可以new的,这里是可变类名的一种语法。 __METHOD__:代表当前的方法名!---在类里echo __METHOD__;//结果A::showCLassName __FILE__文件的完整路径和文件名, __DIR__文件所在的目录 __FUNCTION__函数的名称 __NAMESPACE__当前命名空间的名称 三、对象的遍历使用foreach语句! 对象的自定义遍历
- 对象的遍历受属性的访问控制的限制!
- 对象毕竟是有“生命力”的,可以自定义遍历!
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: php面向对象详解
- 下一篇: libcurl的API详解