Sto discutendo con un collega sull'uso corretto (se presente) di trigger_error
nel contesto dei metodi magici . In primo luogo, penso che trigger_error
dovrebbe essere evitato, tranne per questo caso.
Supponiamo che abbiamo 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 uguali nel modo in cui rispondono foo()
ma differiscono quando si chiama 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;
}
}
}
In modo che entrambe le classi si comportino (quasi) in modo identico
$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 di ActiveRecord. Uso __call
per catturare e gestire metodi che essenzialmente fanno la stessa cosa ma hanno modificatori come Distinct
o Ignore
, ad esempio
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
o
insert()
replace()
insertIgnore()
replaceIgnore()
Metodi come where()
, from()
, groupBy()
, ecc, sono hard-coded.
Il mio argomento viene evidenziato quando si chiama accidentalmente insret()
. Se l'implementazione del mio record attivo codificasse tutti i metodi, sarebbe un errore.
Come per ogni buona astrazione, l'utente dovrebbe essere ignaro dei dettagli di implementazione e fare affidamento esclusivamente sull'interfaccia. Perché l'implementazione che utilizza metodi magici dovrebbe comportarsi diversamente? Entrambi dovrebbero essere un errore.
4.something
?