非常粗略的例子,我想象仍会有一些代码行中的每个方法
<?php
class Chain {
private $_register = array();
public function foo() {
$this->register(__METHOD__);
return $this;
}
public function bar() {
$this->register(__METHOD__);
return $this;
}
public function some() {;
$this->verify('foo'); // foo() should be called before some();
$this->register(__METHOD__);
echo 'it\'s ok';
return $this;
}
public function verify($method) {
if(array_key_exists($method, $this->_register) && $this->_register[$method] == true) {
return true;
}
else {
throw new Exception('Some exception');
}
}
public function register($method) {
$method = str_replace(__CLASS__.'::', '', $method);
$this->_register[$method] = true;
}
}
我们做什么在这里 - 我们有一个register()
和verify()
方法。 (也可以是助手,但是对于当前的目的我加入他们的类。
之前,它的返回值的寄存器本身每个方法都应该有。拨打国际长途foo()
$this->register(__METHOD__)
将私人数组中添加'foo' => true
。 的verify()
方法检查foo
是否作为数组键存在,如果其值为true
。如果是 - 脚本将继续,否则 - 抛出异常。
在这种情况下:
$chain = new Chain();
$chain->bar()->some()->foo(); //throws an exception
Fatal error: Uncaught exception 'Exception' with message 'Some exception' in ...
$chain = new Chain();
$chain->foo()->some()->foo(); // ok
it's ok
这里的问题是,我们建立了 “公约”。您需要将__METHOD__
传递给注册函数,因此在替换类名后,它只会在数组中添加方法名称。所以后来,在你需要验证,如果一个或多个功能在此之前调用的函数,你需要使用方法名作为字符串即$this->verify('foo');
Ofcourse,你可以不剥离,并与strpos()
测试或添加扮演不同的场景()
之后的方法名称更容易识别,如果您正在验证方法或其他人。
但至少这将节省您进行每种方法,不同的变量,以填补即
function foo() {
$this->_foo = true;
return $this;
}
function bar() {
$this->_bar = true;
return $this;
}
如果你不想叫'栏()''如果foo的()'不叫之前,除了检查返回值之外没有别的办法。你可以做一个代理方法(包装器),它可以完成所有的工作,只需在'bar()'中指定参数'foo()', –