Sto avendo un dibattito con un collega sull'uso corretto (se esiste) di trigger_error
nel contesto dei metodi magici . In primo luogo, penso che trigger_error
debba essere evitato tranne per questo caso.
Supponiamo di avere una classe con un metodo foo()
class A {
public function foo() {
echo 'bar';
}
}
Ora diciamo che vogliamo fornire la stessa identica interfaccia ma usare un metodo magico per catturare tutte le chiamate di metodo
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
Entrambe le classi sono identiche nel modo in cui rispondono a foo()
, ma differiscono quando chiamano un metodo non valido.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
La mia tesi è che i metodi magici dovrebbero chiamare trigger_error
quando viene catturato un metodo sconosciuto
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;
}
}
}
Quindi entrambe le classi si comportano (quasi) identicamente
$a->badMethod(); //Call to undefined method A::badMethod() in [..] on line 28
$b->badMethod(); //Call to undefined method B::badMethod() in [..] on line 32
Il mio caso d'uso è un'implementazione ActiveRecord. Io uso __call
per catturare e gestire metodi che essenzialmente fanno la stessa cosa ma hanno modificatori come Distinct
o Ignore
, ad es.
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
o
insert()
replace()
insertIgnore()
replaceIgnore()
Metodi come where()
, from()
, groupBy()
, ecc. sono hardcoded.
Il mio argomento è evidenziato quando si chiama accidentalmente insret()
. Se la mia implementazione del record attivo ha codificato tutti i metodi, sarebbe un errore.
Come ogni buona astrazione, l'utente dovrebbe essere inconsapevole dei dettagli di implementazione e affidarsi esclusivamente all'interfaccia. Perché l'implementazione che utilizza i metodi magici dovrebbe comportarsi diversamente? Entrambi dovrebbero essere un errore.