Prowadzę debatę z kolegą na temat prawidłowego użycia (jeśli w ogóle) trigger_errorw kontekście magicznych metod . Po pierwsze, uważam, że trigger_errornależy tego unikać, z wyjątkiem tego jednego przypadku.
Powiedzmy, że mamy klasę z jedną metodą foo()
class A {
public function foo() {
echo 'bar';
}
}
Powiedzmy teraz, że chcemy zapewnić dokładnie ten sam interfejs, ale użyj magicznej metody, aby przechwycić wszystkie wywołania metod
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
Obie klasy są takie same pod względem odpowiedzi, foo()ale różnią się przy wywoływaniu niepoprawnej metody.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
Moim argumentem jest, że magiczne metody powinny wywoływać, trigger_errorgdy zostanie złapana nieznana metoda
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;
}
}
}
Tak, aby obie klasy zachowywały się (prawie) identycznie
$a->badMethod(); //Call to undefined method A::badMethod() in [..] on line 28
$b->badMethod(); //Call to undefined method B::badMethod() in [..] on line 32
Mój przypadek użycia to implementacja ActiveRecord. Używam __calldo chwytania i obsługi metod, które zasadniczo robią to samo, ale mają modyfikatory takie jak Distinctlub Ignorenp
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
lub
insert()
replace()
insertIgnore()
replaceIgnore()
Metody takie jak where(), from(), groupBy(), itd. Są zakodowane.
Mój argument jest podkreślony, gdy przypadkowo dzwonisz insret(). Gdyby moja aktywna implementacja rekordu zapisała wszystkie metody na stałe, byłby to błąd.
Jak w przypadku każdej dobrej abstrakcji, użytkownik powinien nie znać szczegółów implementacji i polegać wyłącznie na interfejsie. Dlaczego implementacja korzystająca z magicznych metod powinna zachowywać się inaczej? Oba powinny być błędem.
4.something?