所有其他魔术方法都必须是公共的,否则无效。
构造方法:__construct
自动输出于首部
- 出发时机:在每次创建新对象时先调用此方法,该方法无返回值。
- 作用:初始化一批参数,定义后new类()中传值
<?php
class test
{
public $user = '小明';
public function __construct($config = [],$tip='')
{
isset($config['user']) ? $this->user = $config['user'] : '';
}
}
$test = new test();
echo $test->user; //小明
$config['user'] = '小黑';
$test = new test($config);
echo $test->user; //小黑
析构方法 __destruct()
PHP将在对象被销毁前(即从内存中清除前)调用这个方法。默认情况下,PHP仅仅释放对象属性所占用的内存并销毁对象相关的资源,析构函数允许你在使用一个对象之后执行任意代码来清除内存。当PHP决定你的脚本不再与对象相关时,析构函数将被调用。
- 没有参数
<?php
class test
{
public $name = '小明';
public function __construct()
{
$this->name = "小黑";
}
public function __destruct()
{
echo "再见" . $this->name, "<br>";
}
}
$test = new test(); //再见小黑
__get
方法有一个参数,表示要调用的变量名。方法有一个参数,表示要调用的变量名。
- 当程序试图调用一个未定义或不可见的成员变量时,
<?php
class test
{
private $type; // 或者 protected $type;
//tip:为使进入__get方法中
public function __get($property)
{
if (isset($this->$property)) {
echo '变量' . $property . '的值为:' . $this->$property . '<br>';
} else {
echo '变量' . $property . '未定义,初始化为<br>';
$this->$property=111;
}
}
}
$test = new test();
$test->type; //变量type未定义,初始化为
$test->type; //变量type的值为:111
__SET
__set()方法包含两个参数,分别表示变量名称和变量值,两个参数都不可省略。
- 当程序试图写入一个不存在或者不可见的成员变量时
<?php
class test
{
protected $type ;
public function __set($name, $value)
{
if (isset($this->$name)) {
$this->$name = $value;
echo '变量' . $name . '赋值为:' . $value . '<br>';
} else {
$this->$name = $value;
echo '变量' . $name . '被初始化为:' . $value . '<br>';
}
}
}
$test = new test();
$test->type = 'DIY'; //变量type被初始化为:DIY
$test->type = 'YID'; //变量type赋值为:YID
__isset
在类外部使用isset(),测定成员是否存在时自动调用。
- 当程序试图调用一个未定义或不可见的成员变量时
<?php
class test
{
public $sex = '女';
private $name = '男';
private $age = '18';
public function __isset($content)
{
echo isset($this->$content) ? 1 : 0, ": ";
echo "当在类外部使用isset()函数测定私有成员{$content}时,自动调用";
}
}
$test = new test();
echo isset($test->sex), "<br>"; //1
echo isset($test->name), "<br>"; //1: 当在类外部使用isset()函数测定私有成员name时,自动调用
echo isset($test->age), "<br>"; //1: 当在类外部使用isset()函数测定私有成员age时,自动调用
echo isset($test->other), "<br>"; //0: 当在类外部使用isset()函数测定私有成员other时,自动调用
__unset
在类外部使用unset(),销毁成员时自动调用。
- 当程序试图销毁一个未定义或不可见的成员变量时
<?php
class test
{
public $sex = '女';
private $name = '男';
private $age = '18';
public function __unset($content)
{
echo "当在类外部使用unset()函数销毁私有成员{$content}时,自动调用","<br>";
}
}
$test = new test();
unset($test->sex);
echo $test->sex; //Notice: Undefined property: test::$sex
unset($test->name); //当在类外部使用unset()函数销毁私有成员name时,自动调用
unset($test->age); //当在类外部使用unset()函数销毁私有成员age时,自动调用
unset($test->other); //当在类外部使用unset()函数销毁私有成员other时,自动调用
__call与__callStatic
在类外部使用unset(),销毁成员时自动调用。
- 当程序试图调用一个未定义或不可见的方法时
- 如果方法不存在就去父类中找这个方法,如果父类中也不存在就去调用本类的__call()方法
- 可配合call_user_func、call_user_func_array实现加工后连贯操作等
- __callStatic在PHP5.3.0以上版本有效
<?php
class test
{
function __call($method, $arg_array)
{
var_dump($method);
var_dump($arg_array);
}
static function __callStatic($method, $arg_array)
{
var_dump($method);
var_dump($arg_array);
}
}
$test = new test();
$test->func('a', 'b', [1, 2, 3]);
$test::func('a', 'b', [1, 2, 3]);
//输出相同:
//:string 'func' (length=4)
//:array (size=3)
0 => string 'a' (length=1)
1 => string 'b' (length=1)
2 =>
array (size=3)
0 => int 1
1 => int 2
2 => int 3
<?php
class test
{
private $value;
function __construct($value)
{
$this->value = $value;
}
function __call($function, $args)
{
$this->value = call_user_func($function, $this->value, $args[0]);
return $this;
}
function strlen()
{
return strlen($this->value);
}
}
$str = new test(" ab AB 0 ");
echo $str->trim(' ')->strlen(); //7
__invoke
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。
- 本特性只在 PHP 5.3.0 及以上版本有效。
<?php
class test
{
function __invoke()
{
var_dump(func_get_args()); //array (size=1) 0 => string 'a' (length=1)
echo '这可是一个对象哦'; //这可是一个对象哦
}
}
$test = new test();
$test('a');
__clone
如果想复制一个对象则需要使用clone方法,在调用此方法是对象会自动调用__clone魔术方法,
- 如果在对象复制需要执行某些初始化操作,可以在__clone方法实现。
- 如果禁止克隆可以,私有化__clone方法。
<?php
class test
{
public $ID ;
function setID($num)
{
$this->ID = $num;
}
function getID()
{
return $this->ID;
}
public function __clone()
{
$this->status=1;
}
}
$test1 = new test();
$test11->setID("12345");
echo $test1->status, "<br />"; //0
$test2 = clone $test1;
echo $test2->status, "<br />"; //1
$test2->setID("67890");
echo "drone1 ID: " . $test1->getID() . "<br />"; //drone1 ID: 12345
echo "drone2 ID: " . $test2->getID() . "<br />"; //drone2 ID: 67890
echo "drone1 ID: " . $test1->getID() . "<br />"; //drone1 ID: 12345
__toString
在将一个对象转化成字符串时自动调用,比如使用echo打印对象时。
- PHP 5.2.0之前,__toString方法只有结合使用echo() 或 print()时 才能生效。PHP 5.2.0之后,则可以在任何字符串环境生效(例如通过printf(),使用%s修饰符)
- 从PHP 5.2.0,如果将一个未定义__toString方法的对象 转换为字符串,会报出一个E_RECOVERABLE_ERROR错误。
<?php
class test
{
public function __toString()
{
return "对象不能输出哦";
}
}
$test = new test;
echo $test; //对象不能输出哦
__debugInfo
打印所需调试信息,var_dump()打印对象,print_r()打印__debugInfo()内容。
- 该方法在PHP 5.6.0及其以上版本才可以用,
<?php
class test
{
private $prop;
public function __construct($val)
{
$this->prop = $val;
}
public function __debugInfo()
{
$this->prop = 100;
return [
'propSquared' => $this->prop**2,
];
}
}
var_dump(new test(6)); /*object(C)[1]
private 'prop' => int 6 */
print_r(new test(6)); //C Object ( [propSquared] => 10000 )