PHP基础加强系列五之魔术方法

胡三金 2017-06-15 15:08:05 1054 0 comments

序言:这篇文章主要讲了魔术方法get,set,call,toString,clone的使用;

(1).get,set

通过这两个方法,可以很好的访问或设置私有或者受保护的类属性;同时也能够很好的阻止外部添加不存在的类属性;

在给protected/private或者不存在属性赋值时,set() 会被调用。

读取protected/private或者不存在属性的值时,get() 会被调用。

类似的有

读取protected/private或者不存在的方法时,call()会被调用。

小例子:

image.png

$p1 = new person(‘小明’,’PHP开发工程师’,20000);

echo p1->name;

p1->sex = ‘男’; //由于没有对类进行约束,所以可以在外部动态创建类属性;

echo p1->salary; //由于没有重写get方法,此时访问私有属性时会报错;

改写:

image.png

//此时对类重写类get和set魔术方法,

然后此时再来上面相同的步骤

p2 = new person2(‘小明’,’PHP开发工程师’,20000);

echo p1->name;

p1->sex = ‘男’; //由于对类进行了约束,所以可以在外部不能动态创建类属性;会抛出自定义的异常:属性不存在;

echo $p1->salary; //由于重写get方法,此时访问私有属性时不会报错;会返回20000;


(2).call()

这个方法原理类似:

class monkey{
public $name = ‘’;
protected food = ‘’;
public function
construct(name,$food)
{
$this->name = $name;
$this->food = food;
}
private function walk()
{
echo ‘我在走路’;
}
public function call(method,$parameter)
{
return this->method();
}
}

//此时调用私有方法walk不会报错,因为已经通过call魔术方法进行了处理,call()魔术方法的第二个参数是将外部调用的方法的参数合并到一个数组返回;


(3)toString();

这个魔术方法是当你需要以字符串形式输出一个类时,会被触发;

小例子:

class Person{
public $name = ‘’;
protected $job = ‘’;
private salary = ‘’;
public function construct(name,job,job,salary){
$this->name = $name;
$this->job = $job;
$this->salary = $salary;
}
}

image.png

改写如下:

class Person{
public $name = ‘’;
protected $job = ‘’;
private salary = ‘’;
public function
construct(name,job,job,salary){
$this->name = $name;
$this->job = $job;
$this->salary = $salary;
}
public function toString(){
return $this->name;
}
}


(4).clone();

//可以用它来防止对象克隆;

小例子:

class monkey{
public $name = ‘’;
protected food = ‘’;
public function construct(name,$food)
{
$this->name = $name;
$this->food = food;
}
public function
clone()
{

}
}
monkey = new monkey(‘金丝猴’,’香蕉’);
monkey2 = new monkey(‘金丝猴’,’香蕉’);
monkey3 = monkey;
monkey4 = clone monkey;
if(monkey == monkey4)
{
echo ‘两个对象属性方法都一样
‘;
}
if (monkey !== monkey4)
{
echo ‘这是monkey类的两个实例
‘;
}
if (monkey === monkey3)
{
echo ‘两个对象一样’;
}
var_dump(monkey,monkey2,monkey2,monkey3,monkey4);

输出:

image.png

从结果可以看出:对象是值传递,所以monkey3===monkey,而克隆是创建一个新的实例,通过var_dump来查看3只猴子你会发现他们的对象标识符不一样,一样的表示是同一只猴子,例如monkey3和monkey的对象标识符都是1,monkey2是2,$monkey3是3;

好了,回到正题,通过上面这种不对对象进行约束,在类外部是可以无限克隆对象的,为了防止这种情况,可以在monkey类内部写一个私有的_clone方法,就能防止克隆;

class monkey{
public $name = ‘’;
protected food = ‘’;
public function
construct(name,$food)
{
$this->name = $name;
$this->food = $food;
}
private function __clone()
{

}
}

此时再来clone对象就会报错的;

image.png

这种做法通常用在PHP单例模式;


转载请注明出处,谢谢!



标签
PHP
评论一下

评论列表

暂时没有评论,快来评论吧..