共计 3008 个字符,预计需要花费 8 分钟才能阅读完成。
php 的语法中,有一些系统自带的方法名,均以双下划线开头,它会在特定的情况下被调用。即所谓的魔法函数。
魔术函数
1。__construct()
实例化对象时被调用,当__construct 和以类名为函数名的函数同时存在时,__construct 将被调用,另一个不被调用。
2。__destruct()当删除一个对象或对象操作终止时被调用。
3。__call()对象调用某个方法,若方法存在,则直接调用;若不存在,则会去调用__call 函数。
4。__get()读取一个对象的属性时,若属性存在,则直接返回属性值;若不存在,则会调用__get 函数。
5。__set()设置一个对象的属性时,若属性存在,则直接赋值;若不存在,则会调用__set 函数。
面向对象编程中使用频率很高的两个方法. 当设置和获取对象的属性不允许访问时性,此方法会被调用。一定注意是不存在或不允许被读写时才会被调用。
因此对于一个对象,其属性不确定时,用这两个方法效果很好。
__get($name) 获取对象不存在的属性或无法访问的属性时调用.$name 表示要获取的属性名
__set($name, $value) 设置对象不存在的属性或无法访问的属性时调用.$name 表示要设置的属性名,$value 表示要设置的值.
// 例如: 我们可以构建一个不确定属性的数据记录类
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;
这两个方法用得比较少些。当调用方法 isset()判断对象是否存在某属性, 调用 unset()注销某属性时。且当这些属性不存在或不可访问时,会分别调用__isset()和__unset()方法
与前面的 __get() 和__set()略同。都是某属性不存在或不可访问时被调用
__isset($name) 当调用方法 isset()方法判断不可访问的类属性时调用.$name 表示属性名.
__unset($name) 当调用方法 unset()方法删除不可访问的类属性时调用.$name 表示属性名.
6。__toString()打印一个对象的时被调用。如 echo $obj; 或 print $obj;
classInfo{
publicfunction__toString()
{
return”info”;
}
}
$info = new Info();
echo $info.PHP_EOL;
7。__clone()克隆对象时被调用。如:$t=new Test();$t1=clone $t;
8。__sleep()serialize 之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。
9。__wakeup()unserialize 时被调用,做些对象的初始化工作。
__sleep() 和 __wakeup()
这两个方法,咋一看,就是睡觉和唤醒嘛。那跟对象有什么关系?有时候该用的时候也想不起来。其实,我们简单点记,在 php 中有一个让对象睡觉的方法, 叫 searialize(),
它会将对象的各属性序列化以方便保存起来。而 unsearialize()方法是将保存的序列化的数据解开变成对象。也叫唤醒。相对应的,当睡觉时,php 会调用__sleep()方法,它
的返回值必须是一个数组,表示需要保存的属性项, 对于文件句柄,数据库连接等资源类型的数据是不能被序列化保存的。同理唤醒对象时,php 会调用__wakeup()方法,
但与__sleep()不同的是,它返回值为空。被保存的属性都会被解开。那它有什么用呢?刚我们说了,searialize 是不能保存资源的。那么唤醒时如果我们想用到这些资源怎么
办?回答很肯定,重新创建?那在哪里创建合适呢?当然是__wakeup()方法里面,因为每次唤醒时都会调用此方法嘛。这下我们很清楚这两个方法的用途了。
__sleep() 当调用 searialize()方法时调用,返回值为数组,表示需要序列化的数据项.
__wakeup() 当调用 unsearizlie()方法时调用。一般用来在唤醒时初始化资源对象.
// 例如我们有一个用户类,用户名和性别都是类属性。用户的密码存在文件中
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;
10。__isset()检测一个对象的属性是否存在时被调用。如:isset($c->name)。
11。__unset()unset 一个对象的属性时被调用。如:unset($c->name)。
12。__set_state()调用 var_export 时,被调用。用__set_state 的返回值做为 var_export 的返回值。
13。__autoload()实例化一个对象时,如果对应的类不存在,则该方法被调用。
魔术常量
1。__LINE__返回文件中的当前行号。
2。__FILE__返回文件的完整路径和文件名。如果用在包含文件中,则返回包含文件名。自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一个相对路径。
3。__FUNCTION__返回函数名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该函数被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
4。__CLASS__返回类的名称(PHP 4.3.0 新加)。自 PHP 5 起本常量返回该类被定义时的名字(区分大小写)。在 PHP 4 中该值总是小写字母的。
5。__METHOD__返回类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。