读书人

PHP Chain 链式编程的应用之异常处理

发布时间: 2012-10-27 10:42:26 作者: rapoo

PHP Chain 链式编程的应用之错误处理


链式编程使用起来非常惬意,本文尝试在PHP下实现一种链式编程的应用
我们知道在new class后调用method,在常规PHP编程下每次调用都要

class CChain{private $instance=null;private $haserror=false;public function __construct($instance) {if(!method_exists($instance,'getError'))die('Instance does not have a method getError().');$this->instance=$instance;}public function __call($m,$a) {if($this->haserror)return $m=='getError'?$this->haserror:$this;$this->haserror=&$this->instance->getError()?:false;if($this->haserror)return $m=='getError'?$this->haserror:$this;$ret=&call_user_func_array(array(&$this->instance, $m),$a);$this->haserror=&$this->instance->getError()?:false;if($this->haserror)return $m=='getError'?$this->haserror:$this;if($m=='getError') return $this->haserror;if($ret===null)return $this;return $ret;}public function __get($n) {return $this->instance->$n;}public function __set($n,$v) {$this->instance->$n=$v;}}class test {public $error=false;public function getError() {return $this->error;}public function setError($v) {$this->error=$v;}public function m0() {/* someting without return*/}public function m1() {/* someting without return*/}public function m2($foo=null) {if($foo) {return $this->setError('error '.__METHOD__);}/* someting without return*/}}$test=new CChain(new test);print_r( $test->m0()->m1()->m2(1) );echo($test->error);



当然如果想更详细的跟踪错误发生在那个method也很容易,改造__call记录下$m就好了。


?

1 楼 yeaha 2011-06-14 搞复杂了,method()如果没错就返回$this,否则抛出异常,外面在合适的地方搞一个try{} catch {}完事 2 楼 achun 2011-06-14 yeaha 写道搞复杂了,method()如果没错就返回$this,否则抛出异常,外面在合适的地方搞一个try{} catch {}完事
try是解决问题的一种方法
但是try要放到那里呢?
是全局做一个还是,需要的地方都inline部署?
做全局灵活性没有了,而且try会打断程序流,也许被打断的后面还有相应的处理
inline部署,那要写多少啊?
用这种错误chain的话就成这种情况了
if(false===$ret=obj->m1()-m2->m3->mn()){
error(....)
} 3 楼 yeaha 2011-06-14 如果要关心到链的中间被打断,自行做后续处理,还不如把可能被打断的地方分为两块

fn1 {
method1();
method2();
return ...;
}

fn2 {
method3();
method4();
}

if (fn1()) {
fn2();
} else {
// if error
}

可读性也会好很多

try {
$obj->m1()->m2()->m3()->...;
} catch (Exception $ex) {
}

这是两种业务流程,按需组织就得了,不需要专门去搞“精巧”的机制,读代码的人需要理解你的代码的前提条件越少越容易懂

而且你那个写法里面有一些所谓的getError这样的硬编码,用这种机制就非得写getError(),无端产生了一条约束,底层架构约束越少,依赖越少,越灵活 4 楼 yeaha 2011-06-14 每个不同的method其实都可能从属不同的类,每个method抛出不同的Exception其实也可以达到对不同的步骤出现的错误做针对性处理的目的

try {
$obj->m1()->m2()->m3()->...;
} catch (FooException $ex) {
// 从m1()抛出
} catch (BarException $ex) {
// 从m2()或者m3()抛出

$code = $ex->getCode();

if ($code == 401) {

} elseif ($code == 403) {

}
} 5 楼 achun 2011-06-16 yeaha 写道每个不同的method其实都可能从属不同的类,每个method抛出不同的Exception其实也可以达到对不同的步骤出现的错误做针对性处理的目的

try {
$obj->m1()->m2()->m3()->...;
} catch (FooException $ex) {
// 从m1()抛出
} catch (BarException $ex) {
// 从m2()或者m3()抛出

$code = $ex->getCode();

if ($code == 401) {

} elseif ($code == 403) {

}
}
你说的也很有道理,我之所以有这样的想法,出发点是
1.不想写那么多的try,想达到无try的地步
2.引入try,就要求对Exception做统一的规划
这本来没什么错的,OOP的设计都这样要求
可是我想做基于lib组装成框架的设计,因此要求lib都是自完备的
也就是说我对于现在很多的框架的灵活性不是很认同,一旦用了一个框架
就被框住了

我试图通过一些手段解除这个框。
到底这个想法是否符合真是代码环境,我运用到实际当中尝试下
6 楼 achun 2011-06-16 yeaha 写道搞复杂了,method()如果没错就返回$this,否则抛出异常,外面在合适的地方搞一个try{} catch {}完事
想明白了,我确实把问题搞复杂了
Exception就是用来必须被捕获的,这是一种安全措施
我的想法会产生新的问题,并不能解决根本问题,成本并没有减少,甚至增加了不安全性

读书人网 >编程

热点推荐