首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

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

2012-10-27 
PHP Chain 链式编程的应用之错误处理链式编程使用起来非常惬意,本文尝试在PHP下实现一种链式编程的应用我

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就是用来必须被捕获的,这是一种安全措施
我的想法会产生新的问题,并不能解决根本问题,成本并没有减少,甚至增加了不安全性

热点排行