У меня спор с коллегой по поводу правильного использования (если есть) 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
?