Estoy teniendo un debate con un colega sobre el uso correcto (si lo hay) trigger_error
en el contexto de los métodos mágicos . En primer lugar, creo que trigger_error
deberí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_error
cuando 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 __call
para capturar y manejar métodos que esencialmente hacen lo mismo pero que tienen modificadores como Distinct
o 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
?