我不喜欢拥有数百个天真的Setter和Getters,但我希望能够获得一些数据的Setter和Getters,因为我可能需要对它们进行消毒等。
我有两个想法如何做到这一点:
class Test {
private $value = "Value received from: ";
private $value2 = "Value2 received from: ";
function __get($property) {
if (method_exists($this, "get".$property)) {
return $this->getValue();
}
return $this->$property."__get()";
}
public function getValue() {
return $this->value."getValue()";
}
}
$obj = new Test();
echo $obj->value; // Returns: Value received from: getValue()
echo $obj->value2; // Returns: Value2 received from: __get()
和
class Test {
private $value = "Value received from: ";
private $value2 = "Value2 received from: ";
public function __call($method, $args) {
if (substr($method, 0, 3) == "get") {
// Sanitizing so no functions should get through
$property = preg_replace("/[^0-9a-zA-Z]/", "", strtolower(substr($method, 3)));
if (isset($this->$property)) {
return $this->$property."__call";
}
}
}
public function getValue() {
return $this->value."getValue()";
}
}
$obj = new Test();
echo $obj->getValue(); // Returns: Value received from: getValue()
echo $obj->getValue2(); // Returns: Value2 received from: __call
基本上唯一的区别在于魔术方法__call
和__get
。我遗漏了__set
,因为很明显我会怎么做。
真正的问题是哪一个更好?性能?可读性?安全
答案 0 :(得分:2)
根据PHP Manual: Overloading,魔术方法__get()
用于重载属性,而__call()
用于方法。由于您正在使用方法,因此应使用适合其设计用途的方法。因此,对于可读性,__call()
获得了我的投票。
就安全性而言,我认为任何重载都是同样安全的,也就是说根本不是真的,因为它是关于创建未明确声明的属性和方法
我还没有测试过它的 Performance 方面。我认为方法__call()
会更好,因为它是为方法使用而设计的,但您可能需要microtime(true)
几个测试以确定它是否重要。
老实说,我不使用__call()
因为我没有需要在我的应用程序中重载方法,否则应该说我总是在我的对象类中声明方法。
答案 1 :(得分:-1)
使用__call:
class AbstractEntity
{
/**
* Overloading.
*
* Esse método não é chamado diretamente. Ele irá interceptar chamadas
* a métodos não definidos na classe. Se for um set* ou get* irá realizar
* as ações necessárias sobre as propriedades da classe.
*
* @param string $metodo O nome do método quer será chamado
* @param array $parametros Parâmetros que serão passados aos métodos
* @return mixed
*/
public function __call($metodo, $parametros)
{
$prefixo = substr($metodo, 0, 3);
$var = String::camelcase2underscore(strtolower(substr(str_replace($prefixo, '', $metodo), 0, 1)) . substr($metodo, 4, strlen($metodo)));
if (property_exists($this, $var)) {
// se for set*, "seta" um valor para a propriedade
if (strcasecmp($prefixo, 'set') == 0) {
$this->$var = $parametros[0];
// se for get*, retorna o valor da propriedade
} elseif (strcasecmp($prefixo, 'get') == 0) {
return $this->$var;
}
} else {
echo 'Propriedade ' . $var . ' não existe.';
}
}
public static function camelcase2underscore($name){
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $name));
}
}
示例:
class usuario extends AbstractEntity
{
protected $nm_usuario;
}
$usuario = new Usuario();
$usuario->setNmUsuario('aparagerebacanga');
echo $usuario->getNmUsuario(); //print "aparagerebacanga"