php面向对象封装之__set()方法
一般来说,总是把类的属性定义为private,这更符合现实的逻辑。但是,对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数“__get()”和“__set()”来获取和赋值其属性,以及检查属性的“__isset()”和删除属性的方法“__unset()”。我们为每个属性做了设置和获取的方法,在PHP5中给我们提供了专门为属性设置值和获取值的方法,“__set()”和“__get()”这两个方法,这两个方法不是默认存在的,而是我们手工添加到类里面去的,像构造方法(__construct())一样,类里面添加了才会存在。
3.1__set()方法
在类中声明很多个为私有属性重新赋值的访问接口则会加大工作量,而且还不容易控制。而使用魔术方法__set()则可以解决这个问题。该方法能够控制在对象外部只能为私有的成员属性赋值,不能获取私有属性的值。用户需要在声明类时自己将它加到类中才可以使用。声明格式如下:
void __set(string name,mixed value)
该方法的作用是在程序运行过程中为私有的成员属性设置值,它不需要有任何返回值。但它需要两个参数,第一个参数需要传入在为私有属性设置值时的属性名,第二个参数则需要传入为属性设置的值。而且这个方法不需要我们主动调用,可以在方法前面也加上private关键字修饰,以防止用户直接去调用它。这个方法是在用户值为私有属性设置时自动调用的。如果不在类中添加这个方法而直接为私有属性赋值,则会出现“不能访问某个私有属性”的错误。
实例操作如下:
class Person { //声明一个人类Person,其中包含的三个成员属性被封装起来
//下面是声明人的成员属性,全都使用了private关键字封装
private $name; //第一个成员属性$name定义人的名子,此属性被封装
private $sex; //第二个成员属性$sex定义人的性别,此属性被封装
private $age; //第三个成员属性$age定义人的年龄,此属性被封装
//声明一个构造方法,将来创建对象时,为对象的成员属性赋予初值
function __construct($name="", $sex="男", $age=1) {
$this->name = $name; //使用传入的参数$name为成员属性$this->name赋初值
$this->sex = $sex; //使用传入的参数$sex为成员属性$this->sex赋初值
$this->age = $age; //使用传入的参数$age为成员属性$this->age赋初值
}
//声明魔术方法需要两个参数,真接为私有属性赋值时自动调用,并可以屏蔽一些非法赋值
private function __set($propertyName, $propertyValue) {
if($propertyName=="sex"){ //如果第一个参数是属性名sex则条件成立
if(!($propertyValue == "男" || $propertyValue == "女")) //第二个参数只能是男或女
return; //如果是非法参数返回空,则结束方法执行
}
if($propertyName=="age"){ //如果第一个参数是属性名age则条件成立
if($propertyValue > 150 || $propertyValue <0) //第二个参数只能在0到150之间的整数
return; //如果是非法参数返回空,则结束方法执行
}
//根据参数决定为那个属性被赋值,传入不同的成员属性名,赋上传入的相应的值
$this->$propertyName = $propertyValue;
}
//下面是声明人类的成员方法,设置为公有的可以在任何地方访问
public function say(){ //在类中声明说话的方法,将所有的私有属性说出
echo "我的名子叫:".$this->name.", 性别:".$this->sex.", 我的年龄是:".$this->age."。
";
}
}
$person1=new Person("张三", "男", 20);
//自动调用了__set()函数,将属性名name传给第一个参数,将属性值”李四”传给第二个参数
$person1->name="李四"; //赋值成功
//自动调用了__set()函数,将属性名sex传给第一个参数,将属性值”女”传给第二个参数
$person1->sex="女"; //赋值成功
//自动调用了__set()函数,将属性名age传给第一个参数,将属性值80传给第二个参数
$person1->age=80; //赋值成功
$person1->sex="保密"; //“保密”是一个非法值,这条语句给私有属性sex赋值失败
$person1->age=800; //800是一个非法值,这条语句私有属生age赋值失败
$person1->say(); //调用$person1对象中的say()方法,查看一下所有被重新设置的新值