Estoy teniendo un debate con un colega sobre el uso correcto (si lo hay) trigger_erroren el contexto de los métodos mágicos . En primer lugar, creo que trigger_errordebería evitarse a excepción de este caso.
Digamos que tenemos una clase con un método foo()
class A {
public function foo() {
echo 'bar';
}
}
Ahora digamos que queremos proporcionar exactamente la misma interfaz pero usar un método mágico para capturar todas las llamadas a métodos
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 clases son iguales en la forma en que responden, foo()pero difieren cuando se llama a un método no válido.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
Mi argumento es que los métodos mágicos deberían llamar trigger_errorcuando se detecta un método desconocido
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 clases se comporten (casi) de manera 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
Mi caso de uso es una implementación de ActiveRecord. Utilizo __callpara capturar y manejar métodos que esencialmente hacen lo mismo pero que tienen modificadores como Distincto Ignore, por ejemplo
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
o
insert()
replace()
insertIgnore()
replaceIgnore()
Métodos como where(), from(), groupBy(), etc. están codificadas.
Mi argumento se resalta cuando accidentalmente llamas insret(). Si mi implementación de registro activa codificara todos los métodos, sería un error.
Como con cualquier buena abstracción, el usuario debe desconocer los detalles de implementación y confiar únicamente en la interfaz. ¿Por qué la implementación que usa métodos mágicos debería comportarse de manera diferente? Ambos deberían ser un error.
4.something?