在一个类中,可以访问一个特殊的指针——$this。如果当前类的一个属性为$attribute,则当在该类中通过一个操作设置或访问该变量时,可以使用$this->attribute来引用。
如下所示的代码说明了如何在一个类中设置和访问属性:
class classname
{
public$attribute;
function operation($param)
{
$this->attribute=$param
echo$this->attribute;
}
}
是否可以在类的外部访问一个属性是由访问修饰符来确定的,关于访问修饰符将在本章稍后详细介绍。这个例子没有对属性设置限制的访问,因此可以按照如下所示的方式从类外部访问属性:
class classname
{
public$attribute;
}
$a=new classname;
$a->attribute="value";
echo$a->attribute;
通常,从类的外部直接访问类的属性是糟糕的想法。面向对象方法的一个优点就是鼓励使用封装。可以通过使用__get和__set函数来实现对属性的访问。如果不直接访问一个类的属性而是编写访问函数,那么可以通过一段代码执行所有访问。当最初编写访问函数时,访问函数可能如下所示:
class classname
{
public$attribute;
function__get($name)
{
return$this->$name;
}
function__set($name,$value)
{
$this->$name=$value;
}
}
以上代码为访问$attribute属性提供了最基本的功能。__get函数返回了$attribute的值,而__set函数只是设置了$attribute的值。
请注意,__get函数带有一个参数(属性的名称)并且返回该属性的值。__set函数需要两个参数,分别是:要被设置值的属性名称和要被设置的值。
我们并不会直接访问这些函数。这些函数名称前面的双下画线表明在PHP中这些函数具有特殊的意义,就像__construct函数和__destruct函数一样。
这些函数的工作原理是怎样的?如果实例化一个类:
$a=new classname;
可以用__get函数和__set函数来检查和设置任何属性的值。
如果使用如下命令:
$a->$attribute=5;
该语句将间接调用__set函数,将$name参数的值设置为"attribute",而$value的值被设置为5。必须编写__set函数来完成任何所需的错误检查。
__get函数的工作原理类似。如果在代码中引用:
$a->attribute
该语句将间接调用__get函数,$name参数的值为"attribute"。我们可以自己决定编写__get函数来返回属性值。
初看起来,这段代码可能没有什么作用或作用不大。只从表现形式上看,可能的确如此,但是提供访问器函数的理由就是这么简单:我们只使用一段代码来访问特定的属性。
只有一个访问入口,就可以实现对要保存的数据进行检查,这样可以确保被保存的数据是有意义的数据。如果后来发现$attribute属性值应该在0到100之间,我们就可以添加几行代码,在属性值改变之前进行检查。这样,经过修改,__set函数如下所示:
function_set($name,$value)
{
if(($name="attribute")&&($value>=0)&&($value<=100))
$this->attribute=$value;
}
通过单一的访问入口,可以方便地改变潜在的程序实现。如果由于某种原因,需要改变属性$attribute的保存方式,访问器函数允许我们只要修改一处代码即可完成此工作。
我们可能决定不将$attribute保存为一个变量,而只在需要的时候将它从数据库中取出,或者在要求计算的时候计算出其最新值,或者从其他属性的值推断出它的值,或者将其数据转为更小的数据类型。无论需要做什么样的改变,只要修改访问器函数即可。只要保证这个访问器函数仍然接收并返回程序的其他部分期望的数据类型,那么程序的其他部分代码就不会受影响。