第二十节:类与对象-魔术方法-重载-对象的迭代
魔术方法
1.__get、__set
这两个方法在为类和他们的父类中没有声明的属性设计的。
◆__get($property)当调用一个未定义的属性时,此方法会被触发,传递的参数是被访问的属性名。
◆__set($property,$value)给一个未定义的属性赋值时,此方法会被触发,传递的参数是被设置的属性名和值。
这里的没有声明包括当使用对象调用时,访问控制为protected,private的属性(即没有权限访问的属性)。
2.__isset __unset
◆__isset($property)当在一个未定义的属性上调用isset()函数时调用此方法。
◆__unset($property)当在一个未定义的属性上调用unset()函数时调用此方法。
与__get方法和__set方法相同,这里的没有声明包括当使用对象时,
3. __call
__call($method.$arg_arry)当调用一个未定义的方法是调用此方法。
这里的未定义的方法包括没有权限访问的方法;如果方法不存在就去父类找这个 方法,如果父类中也不存在就去调用本来的__call()方法,如果本类中不存在__call()方法就去找父类的__call()方法。
4.__autoload
__autoload函数,它会试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在PHP出错失败前有了最好一个机会加载类。
1 <?php 2 function __autoload($class){ 3 require_once 'class/'.$class.'.class.php': 4 } 5 ?>
5.__construct 、__destruct
◆__construct 构造方法,当一个对象创建时调用此方法,相对应PHP4使用此方法的好处是:可以使构造方法有一个独一无二的名称。无论它所在的类的名称是什么,这样你在改变类的名称时,就不需要改变构造方法的名称。
◆__destruct 析构方法,PHP将在对象被销毁前(既从内存中清除前)调用这个方法。默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源,析构函数允许你在一个对象执行之后执行任意代码来清除内存。当PHP决定你的脚本不再与对象相关时,析构函数将被调用。
在一个函数的命名空间内,这会发生在函数return的时候。对于全局变量,这发生于脚本结束的时候。如果你想明确地销毁一个对象,你可以给指向该对象的变量分配任何其它值.通常将变量赋值勤为NULL或者调用unset。
6.__clone
PHP 5中的对象赋值是使用的引用赋值,如果想复制一个对象则需要clone方法,在调用此方法是对象会自动调用__clone 魔术方法,如果在对象复制需要执行某些初始化操作,可以在__clone方法实现。
7.__toString
__toString方法在将一个对象转化成字符串时自动调用,比如使用 echo打印对象时。
8.__callStatic
它的工作方式类似于__call()魔术方法,___callStatic()是为了处理静态方法调用。
PHP确实加强对_callStatic()方法的定义;它必须是公共的,并且必须被声明为静态的。同样,__call()魔术方法必须定义为公共的,所有其他的魔术方法必须如此。
魔术方法在MVC的使用 讲数据封装在data数组内
1 <?php 2 $con=mysql_connect('localhost','root','password'); 3 mysql_select_db('newdb',$con); 4 class Model{ 5 protected $data=array(); 6 function __set($k,$v){ 7 $this->data[$k]=$v; 8 } 9 function __get($property){ 10 return $this->data[$property]?$this->data[$property]:NULL; 11 } 12 function __isset($property){ 13 return isset($this->data[$property])?true:false; 14 } 15 function __unset($property){ 16 unset($this->data[$property]); 17 } 18 function add(){ 19 reset($this->data); 20 $i=0; 21 while(list($k,$v)=each($this->data)): 22 $key[$i]="`$k`"; 23 $value[$i]="'$v'"; 24 $i++; 25 endwhile; 26 var_dump($key); 27 var_dump($value); 28 $key=implode(",",$key); 29 $value=implode(",",$value); 30 $sql="insert into `think_user` ($key) values ($value)"; 31 $re=mysql_query($sql)or mysql_error(); 32 } 33 } 34 //实例化 35 $obj=new Model(); 36 //$obj->username='lishi'; 37 $obj->password='1234455'; 38 //写入数据库 39 //$obj->add(); 40 //调用__get方法 41 var_dump($obj->username);// echo NULL 42 //调用__isset方法 43 var_dump(isset($obj->password));//return ture 44 //调用__unset方法 45 unset($obj->password); 46 var_dump($obj->password) 47 ?>
对象的迭代
对象的迭代就是用foreach遍历数组,但是注意 外部迭代只能迭代 可访问属性,也就是public,想迭代所有属性,需要内部跌打,代码如下
1 <?php 2 class Foo{ 3 public $name='lishi'; 4 public $age='23'; 5 protected $money='1000'; 6 private $email='323@qq,com'; 7 function bar(){ 8 echo 'Mybar'; 9 } 10 private function other(){ 11 echo 'Myother'; 12 } 13 function iter(){ 14 echo "Foo::iter():<br/>"; 15 foreach ($this as $key=>$value){ 16 print "$key=>$value<br/>"; 17 } 18 } 19 } 20 $foo=new Foo(); 21 //外部迭代 22 foreach($foo as $key => $value){ 23 print "$key => $value <br/>";//name => lishi age => 23 24 } 25 //内部迭代 26 $foo->iter();//name=>lishi age=>23 money=>1000 email=>323@qq,com 27 ?>