PHP魔法方法/函数详解
引自:
http://blog.csdn.net/inqihoo/article/details/9235103
在php的语法中,有一些系统自带的方法名,均以双下划线开头,它会在特定的情况下被调用。即所谓的魔法函数。
只有当你已经为一个给定类定义了这些魔法方法时,它们才会起作用。还要注意,这些方法不能直接调用,而只能通过要截获的事件来调用。
它们在面向对向编程中起着至关重要的作用。所以个人觉得很有必要整理一下。下面就php的15个魔法函数做一个详细整理:
1. __construct() 和 __destruct()
__construct() 对象初始化时会调用此方法(对于内核而言是指初始化完成后调用此方法).此方法用得比较多。__destruct() 当对象销毁时会调用此方法.那么什么时候对象会销毁呢?一是用户主动销毁对象,二是当程序结束时由引擎自动销毁
[php] view plaincopy
class People { protected $_alive; public function __construct() { $this->_alive = true; echo 'Birth'.PHP_EOL; } public function __destruct() { $this->_alive = false; echo 'Die'.PHP_EOL; } } //主动销毁对象 $test = new Test(); unset($test); sleep(1); //程序完成后自动销毁对象 $test = new Test(); sleep(1);
//例如:我们可以构建一个不确定属性的数据记录类 class Record { protected $_data; public function __get($name) { if (isset($this->_data[$name])) { return $this->_data; } return false; } public function __set($name, $value) { $this->_data = $value; } } $record = new Record(); $record->name = 'andrew'; echo 'My name is '.$record->name.PHP_EOL;
//例如: class People { public $name; public $sex; private $_age; public function __construct($name, $sex, $age) { $this->name = $name; $this->sex = $sex; $this->_age = $age; } public function __isset($name) { echo 'The property '.$name.' not exists'.PHP_EOL; } public function __unset($name) { echo 'The property '.$name.' can not be unset'.PHP_EOL; } } $people = new People('andrew', 'male', 28); isset($people->name); isset($people->real_name); unset($people->_age);
//例如:我们假定人只有跳走两种行为 class People { public function jump() { echo 'I can jump'.PHP_EOL; } public function walk() { echo 'I can walk'.PHP_EOL; } public function __call($method, $args) { echo 'I can not '.$method.PHP_EOL; } //此方法必须是静态方法,且在php5.3版本下可用 public static function __callStatic($method, $args) { echo 'We can not'.$method.PHP_EOL; } } $people = new People(); $people->jump(); $people->walk(); $people->fly(); People::fly();
//例如我们有一个用户类,用户名和性别都是类属性。用户的密码存在文件中 Class User { public $username; public $sex; public $passFile; private $_password; public function __construct($username, $sex, $passFile) { $this->username = $username; $this->sex = $sex; $this->passFile = $passFile; $this->_password = file_get_contents($passFile); } public function getPassword() { return $this->_password; } public function __sleep() { return array( 'username', 'sex', 'passFile', ); } public function __wakeup() { $this->_password = file_get_contents($this->passFile); } } $user = new User('andrew', 'male', 'pass.data'); $serializeData = serialize($user); echo $serializeData.PHP_EOL; $user = unserialize($serializeData); echo $user->getPassword().PHP_EOL;
//例如: class Info { public function __toString() { return "info"; } } $info = new Info(); echo $info.PHP_EOL; echo md5($info).PHP_EOL; echo (String) $info.PHP_EOL; echo substr($info, 0, 2).PHP_EOL;
//例如:以下一个简单的例子 class Data { public $value; public function __clone() { echo "Clone myself".PHP_EOL; } } $data = new Data(); $data->value = 4; $newData = clone $data; $data->value = 5; echo "The data value is: ".$data->value.PHP_EOL; echo "The new data value is: ".$newData->value.PHP_EOL; //对面向对象比较熟的同学,一定对单例模式不陌生。PHP做单例模式的时候要记住把clone方法给禁掉。因为在单例模式中,是不允许复制对象的。如下例 class OnlyOne { //单例对象 private static $_instance; //不允许外部和子类调用初始化方法 private function __construct() {} //不允许复制 public function __clone() { throw new Exception('Not allow to clone me'); } //获取单例对象 public static function getInstance() { if (self::$_instance != null) { return self::$_instance; } self::$_instance = new self(); return self::$_instance; } } $onlyOne = OnlyOne::getInstance(); $newOne = clone $onlyOne;
//我们制订规则类名以目录名加下载线拼接而成。例如:类Model_Config_Xml表示Model/Config/Normal.php文件.我们如何实现自动加载 //有类文件Model/Config/Normal.php内包含类如下: class Model_Config_Normal { public function __construct() { echo "Init Model_Config_Normal".PHP_EOL; } } function __autoload($name) { $classPath = str_replace('_', DIRECTORY_SEPARATOR, $name); require_once("$classPath.php"); } //此时将无需再require('Model/Config/Normal.php') $config = new Model_Config_Normal();
//例如: class Test { public $name; public $age; public static function __set_state($data) { $obj = new Test(); $obj->name = $data['name']; $obj->age = $data['age'] + 1; return $obj; } } $test = new Test(); $test->name = 'andrew'; $test->age = 27; $code =var_export($test, true); echo $code.PHP_EOL; eval('$new='.$code.';'); var_dump($new);
class Invoke { public function __invoke() { echo 'I can run'.PHP_EOL; } } $invoke = new Invoke(); $invoke();