Estou tendo um debate com um colega sobre o uso correto (se houver) trigger_error
no contexto de métodos mágicos . Em primeiro lugar, acho que isso trigger_error
deve ser evitado, exceto neste caso.
Digamos que temos uma classe com um método foo()
class A {
public function foo() {
echo 'bar';
}
}
Agora diga que queremos fornecer exatamente a mesma interface, mas use um método mágico para capturar todas as chamadas de método
class B {
public function __call($method, $args) {
switch (strtolower($method)) {
case 'foo':
echo 'bar';
break;
}
}
}
$a = new A;
$b = new B;
$a->foo(); //bar
$b->foo(); //bar
Ambas as classes são iguais na maneira como respondem, foo()
mas diferem ao chamar um método inválido.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
Meu argumento é que métodos mágicos devem chamar trigger_error
quando um método desconhecido é capturado
class B {
public function __call($method, $args) {
switch (strtolower($method)) {
case 'foo':
echo 'bar';
break;
default:
$class = get_class($this);
$trace = debug_backtrace();
$file = $trace[0]['file'];
$line = $trace[0]['line'];
trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
break;
}
}
}
Para que ambas as classes se comportem (quase) de forma idêntica
$a->badMethod(); //Call to undefined method A::badMethod() in [..] on line 28
$b->badMethod(); //Call to undefined method B::badMethod() in [..] on line 32
Meu caso de uso é uma implementação do ActiveRecord. Eu uso __call
para capturar e manipular métodos que essencialmente fazem a mesma coisa, mas têm modificadores como Distinct
or Ignore
, por exemplo
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
ou
insert()
replace()
insertIgnore()
replaceIgnore()
Métodos como where()
, from()
, groupBy()
, etc. são codificados.
Meu argumento é destacado quando você liga acidentalmente insret()
. Se minha implementação de registro ativo codificasse todos os métodos, seria um erro.
Como em qualquer boa abstração, o usuário deve desconhecer os detalhes da implementação e confiar apenas na interface. Por que a implementação que usa métodos mágicos deve se comportar de maneira diferente? Ambos devem ser um erro.
4.something
?