我一直很纠结于有没有使用__get和__set对于如此访问/设置对象成员有何区别?
$instance->member
实际上不还是对外暴露了吗?等同于将访问修饰符改为public了。
代码解读:包的封装之Get,Set技巧
在 KO3 的 Pagination Module 的核心库 pagination class 之中涉及到了 Get,Set 使用,或许很多人不知道 Get,Set,这就要从 Java 说起:
java三大特性:封装,继承,多态
其中 get(),set() 方法就体现出了封装的特性,对类的内部数据进行隐藏。主要是对类的私有属性进行操作。Java 程序一般将A类的属性修饰符设置为private,这是为了更好的封装数据。要想在B类里引用该属性,就可以在A类里定义修饰符为public的set,get方法以设置和获取private型的属性值
对此,请看下面摘自 pagination 中的代码:
class Kohana_Pagination {
// Current page number
protected $current_page;
// Total item count
protected $total_items;
// How many items to show per page
protected $items_per_page;
// Total page count
protected $total_pages;
// Item offset for the first item displayed on the current page
protected $current_first_item;
// Item offset for the last item displayed on the current page
protected $current_last_item;
// Previous page number; FALSE if the current page is the first one
protected $previous_page;
// Next page number; FALSE if the current page is the last one
protected $next_page;
// First page number; FALSE if the current page is the first one
protected $first_page;
// Last page number; FALSE if the current page is the last one
protected $last_page;
public function __get($key)
{
return isset($this->$key) ? $this->$key : NULL;
}
/**
* Updates a single config setting, and recalculates pagination if needed.
*
* @param string config key
* @param mixed config value
* @return void
*/
public function __set($key, $value)
{
$this->setup(array($key => $value));
}
}
大家可以看到此类使用全部都是受保护的属性变量,但是通过 __get(),__set() 方法却又可以从外部调用的时候进行赋值,使用方法:
// 控制器 $pagination = Pagination::factory(); echo '共计页面:'.$pagination->total_pages;
如何类中的属性是私有的还是受保护的通过 __get(),__set() 都可以从外部类中调用和设置其属性变量,这样就很好的做好的类的封装 ![]()
如果大家不行,可以把下面的代码分别删去__get(),__set()和保留试试结果:
class User {
protected $name;
private $age;
public function __get($key)
{
return isset($this->$key) ? $this->$key : NULL;
}
public function __set($key, $value)
{
return isset($this->$key) ? ($this->$key = $value) : NULL;
}
$user = new User;
$user->name = 'icyleaf';
$user->age = 22;
echo 'User name is '.$user->name.'('.$user->age.')';
}我一直很纠结于有没有使用__get和__set对于如此访问/设置对象成员有何区别?
$instance->member
实际上不还是对外暴露了吗?等同于将访问修饰符改为public了。
实际上,上面是一种方式,不过在PHP里,常用的是这样的:
class User {
private $data = array();
public function __set($name, $value) {
$this->data[$name] = $value;
}
public function __get($name) {
if (array_key_exists($name, $this->data)) {
return $this->data[$name];
}
else
{
return FALSE;
}
}@zwws
使用__set和__get,可以在用户设置或获取变量时提供一个统一的入口,对变量作进一步的处理。比如当用户设置password时,自动md5 password等等,出了问题追查起来也比较方便。
OK, 原始需求差不多可以理解为:
1. 代码的隔离控制,解耦
2. 代码的易维护性
谢谢二位,:)
发表讨论