我正在与一位同事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
?