之前對PHP中的魔術方法一直有了解,但是對于具體的使用場景則是模模糊糊的。今天了解到了一種使用魔術方法的場景,整理了一下寫出來。
假如一個類中具有較多的變量,對于每一個變量編寫set/get方法是一件非常繁瑣的事情,尤其對于資料庫的查詢結果,有時候字段可以很多。但是直接讓程式調用類中的字段又不被推薦,這時候可以通過對__get、__set和__call方法的使用來解決這個問題。
<?php
class Basic {
protected $_properties;
/**
* Basic constructor.
* @param $val
*/
public function __construct ($val = array()) {
$this->_properties = $val;
}
/**
* @param $key
* @param $val
*/
public function __set ($key, $val) {
$this->_properties[$key] = $val;
}
/**
* @param $key
* @return
*/
public function __get ($key) {
return isset($this->_properties[$key]) ? $this->_properties[$key] : null;
}
/**
* @param $_method
* @param $args
* @return
*/
public function __call ($_method, $args) {
if(method_exists($this, $_method)) {
return $this->$_method($args);
}
if(substr($_method, 0, 3) == 'get') {
return $this->_get($_method);
}
if(substr($_method, 0, 3) == 'set') {
$this->_set($_method, $args);
}
return null;
}
/**
* @param $_method
* @return
*/
private function _get ($_method) {
$_method = substr($_method, 3, strlen($_method));
$key = implode('_', preg_split('#(?=[A-Z])#', lcfirst($_method)));
$key = strtolower($key);
return isset($this->_properties[$key]) ? $this->_properties[$key] : null;
}
/**
* @param $_method
* @param null $args
*/
private function _set ($_method, $args = null) {
$_method = substr($_method, 3, strlen($_method));
$key = implode('_', preg_split('#(?=[A-Z])#', lcfirst($_method)));
$key = strtolower($key);
$this->_properties[$key] = $args[0];
}
}
$student = array(
'name' => '張三',
'age' => 18,
'sex' => 'male',
'score' => 99
);
$basic = new Basic($student);
$basic->level = 'A';
var_dump($basic->name);//string(6) "張三"
var_dump($basic->getLevel());//string(1) "A"
$basic->setLevel('B');
var_dump($basic->level);//string(1) "B"
通過代碼中的方式,相當于對于每個字段預設實作了get/set方法,在對象中可以直接通過getKeyName和setKeyName方法的方式來操作對象的字段值。