克隆对象
php的对象是引用类型,变量名往往指代的是一个指针,这点与js很相似,直接将$spot
对象赋值给$al
对象,这俩个对象指向的内存中的同一个对象,所以改变一个另外一个也会受到影响,但是php4中却不是这样的。
class Dog{
public $name;
function __construct($name) {
$this->name = $name;
}
}
$sopt = new Dog("haha");
$al = $sopt;
$al->name = "wangwang";
echo $sopt->name; // wangwang
在php4中$spot
中的成员变量并不会被改变,php5中的这样非常像js。php中有一个clone
关键字,这个关键字可以为对象新开辟内存,使之成为俩个不同的对象。
class Dog{
public $name;
function __construct($name) {
$this->name = $name;
}
}
$sopt = new Dog("haha");
$al = clone $sopt;
$al->name = "wangwang";
echo $sopt->name; // haha
比较对象
interface IAnimal{};
class Dog implements IAnimal{
public $name;
function __construct($name) {
$this->name = $name;
}
}
$sopt = new Dog("haha");
$al = clone $sopt;
// 对象比较
// "=="号表示对象值相等,"==="表示对象值相等,地址也相等这点与js非常不同啊,js中的俩个不同对象永远不可以相等啊,因为地址不同啊
var_dump($al == $sopt); // true
var_dump($al === $sopt); // false
// php不能echo出来bool值啊
// 对象检测 instanceof,这个和js的作用是一样的
// intanceof可以检测当前对象是属于哪个类
var_dump($al instanceof Dog); // true
var_dump($al instanceof IAnimal); // true
魔术方法
__clone()在调用clone时会调用的方法
class Dog {
public $name;
function __construct($name) {
$this->name = $name;
}
function __clone() {
echo "被克隆啦";
}
}
$dog = new Dog("haha");
$al = clone $dog;
__set()
写入不存在或者不可见得成员变量时,php会执行__set()
方法俩个参数,变量名称和变量值;
__get()
在读取不存在或者不可见得成员变量时,php会执行__get()
,__get()
有一个参数,参数就是需要读取的变量名;
class Student {
private $name;
public $job = "student";
function __construct($name) {
$this->name = $name;
}
public function __set($age,$value) {
$this->age = $value;
}
public function __get($type) {
echo "__get()被调用了";
return $this->$type;
}
}
$stu = new Student("zp");
$stu->age = 19;
echo $stu->name;
echo $stu->age;
echo $stu->job; // 调用可见的public成员变量时,并不会调用__get
__call()
方法,调用不存在或者不可见得成员方法时,php会先调用,__call()
方法来存储方法名及其参数,__call()方法有俩个参数,即为方法么和方法参数,方法参数以数组存在
class Student {
private $name;
function __construct($name) {
$this->name = $name;
}
private function getName ($name) {
return $this->name.$name;
}
public function __call ($foo,$arg) {
echo "__call()被调用了";
var_dump($arg);
}
}
$stu = new Student("zp");
echo $stu->getName('haha');
__toString()
方法,echo
对象时将调用这个方法,并且这个方法必须,返回一个字符串
class Student {
private $name;
function __construct($name) {
$this->name = $name;
}
public function __toString () {
echo "__toString()被调用了";
return $this->name;
}
}
$stu = new Student('zp');
echo $stu;
__sleep
在对象序列化时会调用,__wakeup
在对象反序列化时会调用
class Student{
public $name;
public $age;
function __construct($name,$age) {
$this->name = $name;
$this->age = $age;
}
public function __sleep() {
echo "在序列化时会调用";
}
public function __wakeup() {
echo "在反序列化时会调用";
}
}
$obj = new Student('zp',19);
var_dump(serialize($obj));
var_dump(unserialize($obj));
__autoload
可以调用自动实例化需要使用的类
我在同一目录下,建立了一个文件,这个文件内就是一个Test类,文件名为Test.class.php
class Test{
private $cont;
public function __construct($cont) {
$this->cont = $cont;
}
public function __toString() {
return $this->cont;
}
}
在另外一个php中利用__autoload
来自动实例化需要的test类
function __autoload($class_name) {
$class_path = $class_name.'.class.php';
if (file_exists($class_path)) {
include_once($class_path);
} else {
echo "类路径错误";
}
}
$test = new Test("这是一个测试啊");
echo $test;