Ich habe eine Debatte mit einem Kollegen über den korrekten Gebrauch (falls vorhanden) von trigger_error
im Zusammenhang mit magischen Methoden . Erstens denke ich, dass trigger_error
dies bis auf diesen einen Fall vermieden werden sollte .
Angenommen, wir haben eine Klasse mit einer Methode foo()
class A {
public function foo() {
echo 'bar';
}
}
Nehmen wir nun an, wir möchten die exakt gleiche Schnittstelle bereitstellen, verwenden jedoch eine magische Methode, um alle Methodenaufrufe abzufangen
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
Beide Klassen reagieren auf die gleiche Weise foo()
, unterscheiden sich jedoch beim Aufrufen einer ungültigen Methode.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
Mein Argument ist, dass magische Methoden aufgerufen werden sollten, trigger_error
wenn eine unbekannte Methode abgefangen wird
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;
}
}
}
Damit verhalten sich beide Klassen (fast) identisch
$a->badMethod(); //Call to undefined method A::badMethod() in [..] on line 28
$b->badMethod(); //Call to undefined method B::badMethod() in [..] on line 32
Mein Anwendungsfall ist eine ActiveRecord-Implementierung. Ich benutze __call
, um Methoden zu fangen und zu handhaben, die im Wesentlichen dasselbe tun, aber Modifikatoren wie Distinct
oder haben Ignore
, z
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
oder
insert()
replace()
insertIgnore()
replaceIgnore()
Methoden wie where()
, from()
, groupBy()
usw. sind hartcodiert.
Mein Argument wird hervorgehoben, wenn Sie versehentlich anrufen insret()
. Wenn meine aktive Datensatzimplementierung alle Methoden fest codiert, wäre dies ein Fehler.
Wie bei jeder guten Abstraktion sollte der Benutzer die Implementierungsdetails nicht kennen und sich ausschließlich auf die Schnittstelle verlassen. Warum sollte sich die Implementierung, die magische Methoden verwendet, anders verhalten? Beides sollte ein Fehler sein.
4.something
?