Я маю дискусію з колегою щодо правильного використання (якщо воно є) trigger_error
у контексті магічних методів . По-перше, я вважаю, що цього trigger_error
слід уникати, окрім цього одного випадку.
Скажімо, у нас є клас з одним методом foo()
class A {
public function foo() {
echo 'bar';
}
}
Тепер скажімо, що ми хочемо надати той самий інтерфейс, але використовувати магічний метод, щоб спіймати всі виклики методу
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
Обидва класи однакові за тим, як вони реагують, foo()
але відрізняються при виклику недійсного методу.
$a->doesntexist(); //Error
$b->doesntexist(); //Does nothing
Мій аргумент полягає в тому, що магічні методи повинні викликати, trigger_error
коли невідомий метод потрапляє
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;
}
}
}
Так що обидва класи поводяться (майже) однаково
$a->badMethod(); //Call to undefined method A::badMethod() in [..] on line 28
$b->badMethod(); //Call to undefined method B::badMethod() in [..] on line 32
Мій випадок використання - це реалізація ActiveRecord. Я використовую , __call
щоб перехоплювати і обробляти методи , які в основному роблять те ж саме , але мають модифікатори , такі як Distinct
або Ignore
, наприклад ,
selectDistinct()
selectDistinctColumn($column, ..)
selectAll()
selectOne()
select()
або
insert()
replace()
insertIgnore()
replaceIgnore()
Такі методи , як where()
, from()
, groupBy()
і т.д. жорстко закодовані.
Мій аргумент підкреслюється, коли ви випадково телефонуєте insret()
. Якщо моя активна реалізація запису зашифрувала всі методи, то це буде помилкою.
Як і будь-яка добра абстракція, користувач повинен не знати про деталі реалізації та покладатися виключно на інтерфейс. Чому реалізація, яка використовує магічні методи, повинна вести себе інакше? В обох має бути помилка.
4.something
?