`
achun
  • 浏览: 314299 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

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

    博客分类:
  • PHP
阅读更多


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

$instance->method1();
$instance->method1();



这样无尽的写N多,如果中间有错误判断那就成这样了

if($instance->method1())
if($instance->method2())
$instance->method3();
//or
$instance->method1();
if($instance->hasError()) die('error');
$instance->method2();
if(....) ...;


看上去很烦,写起来更烦,特别是在开发期,那简直是噩梦。
如果能保证这样执行

if($instance->m0()->m1()->m2()->hasError()) die('error');


那就安逸了,实现这个,方法其实很简单就是在这种可以链式进行的方法中包含错误判断,无论如何都返回this, 当然类似hasError这样的方法是不返回this的,这一类方法总是出现在最后,但是在开发期,我们在方法里面复制粘贴N多的

if($this->hasError())
  return $this
//someting..
return $this;



这样也够烦人的,当然如果定型了,那嵌入这些代码也无所谓。开发期就烦死人了。
可以利用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就好了。


 

0
0
分享到:
评论
6 楼 achun 2011-06-16  
yeaha 写道
搞复杂了,method()如果没错就返回$this,否则抛出异常,外面在合适的地方搞一个try{} catch {}完事

想明白了,我确实把问题搞复杂了
Exception就是用来必须被捕获的,这是一种安全措施
我的想法会产生新的问题,并不能解决根本问题,成本并没有减少,甚至增加了不安全性
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都是自完备的
  也就是说我对于现在很多的框架的灵活性不是很认同,一旦用了一个框架
  就被框住了

我试图通过一些手段解除这个框。
到底这个想法是否符合真是代码环境,我运用到实际当中尝试下
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) {

   }
}
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(),无端产生了一条约束,底层架构约束越少,依赖越少,越灵活
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(....)
}
1 楼 yeaha 2011-06-14  
搞复杂了,method()如果没错就返回$this,否则抛出异常,外面在合适的地方搞一个try{} catch {}完事

相关推荐

    widget_chain:链式编程,而不是小部件嵌套构造函数。 立即摆脱带有闪亮扩展的嵌套地狱!

    链式编程,而不是小部件嵌套构造函数。 Container buildItem ( String name) { return Icon ( Icons .phone) . addNeighbor ( Text (name)) . intoRow (crossAxisAlignment : CrossAxisAlignment .center,) . ...

    Object C 错误处理

    iOS开发中,Objective-C语言作为一种面向对象的编程语言,具备成熟的错误处理机制。错误处理是程序设计中非常关键的一环,尤其是在开发过程中需要妥善处理各种异常情况。在Apple官方文档中详细介绍了如何在Cocoa框架...

    php脚本链式操作文件

    在PHP编程中,链式操作是一种常见的编程技巧,它允许我们连续调用同一个对象的多个方法,使得代码更简洁易读。在这个特定的场景中,我们讨论的是如何在PHP中实现一个简单的文件操作链式处理,这通常涉及到数据库操作...

    stepchain 通用业务流程流水线处理框架

    stepchain 通用业务流程流水线处理框架。 类似于Commons Chain和Commons Pipeline这样的Java Pipeline Step Chain用于组织复杂处理流程执行的流行技术。支持通用业务job、services子流程无限制拆分。支持业务子流程...

    前端开源库-script-chain

    总的来说,"script-chain"是一个针对前端脚本处理的开源库,它通过链式调用和灵活配置,帮助开发者构建高效、流畅的前端应用。结合"fliphub"可能提供的页面翻转功能,它能为用户带来更加丰富和动态的交互体验。在...

    IOS应用源码——Zanneth-Chain-Disaster-8832785.rar

    本文将深入探讨名为“Zanneth Chain Disaster”的iOS应用源码,通过对源码的剖析,我们可以了解到该应用的核心设计、编程技巧以及iOS开发中的关键知识点。 1. **项目结构**: - iOS应用的项目结构通常包含多个模块...

    Chain of thought 链式思考扩展Transformer解码器计算能力的研究

    内容概要:本文探讨了链式思考或中间计算步骤对变换器(transformers)模型的影响,在理论层面揭示了不同数目中间解码步骤对其表达能力和解决问题能力的影响。研究发现,线性数量级的中间计算步长可以使变换器模型...

    Bayesian and Markov chain

    总之,《Bayesian and Markov chain》一文深入浅出地介绍了贝叶斯方法与马尔可夫链的基本原理及其在统计建模中的应用,为读者提供了一个全面而系统的视角。通过学习和掌握这些知识,我们能够在面对复杂不确定性的...

    commons chain api

    - **Web应用过滤器**:Commons Chain可以用于构建Web应用的请求处理链,每个Command代表一个过滤器或处理器。 - **业务逻辑层**:在服务端,它可以组织复杂的业务逻辑,使得各个步骤能够独立、有序地执行。 - **...

    Chain of Responsibility模式

    Chain of Responsibility模式是GOF(GoF,Gang of Four)在他们的经典著作《设计模式:可复用面向对象软件的基础》中提出的23种设计模式之一,属于行为模式类别。这个模式的主要目的是允许在对象之间传递请求,同时...

    前端开源库-chain-able

    在前端开发领域,开源库是开发者们常用的工具,它们提供了丰富的功能,帮助我们高效地构建Web应用。"链-能"(Chain-Able)是一种设计模式,它在前端开源库中广泛采用,尤其是在处理异步操作和数据流时。这个模式使得...

    swift-YQChainTaskSwift链式调用50行不到代码实现的链式任务调用

    在Swift编程语言中,链式调用是一种优雅的编程风格,它可以使得代码更加简洁、易读,特别是当处理多个连续操作时。`YQChainTask`项目就是为了解决这一问题,它提供了一种轻量级的方式来实现链式任务调用,而且全部...

    test chain

    【标题】:“test chain”可能是指在编程或数据科学领域中使用的一种技术——马尔科夫链(Markov Chain)。 【描述】:虽然提供的描述部分只包含了一串重复的字母"aaaaaaaaaaaaaaaaaaaaa",这并没有提供实质性的...

    veriloge应用_chain9ba_fpga_

    在电子设计领域,FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,它允许用户根据需求自定义硬件电路。"verilogE"是硬件描述语言Verilog的一个变体,用于编写数字系统的逻辑描述,进而实现这些设计在...

    Supply_Chain_Guru选址

    Supply Chain Guru is cutting edge software that allows you to perform both supply chain simulation and optimization. This enables you to directly solve problems involving supply chain strategic ...

    markov chain monte carlo in practice

    这本书是MCMC领域的经典之作,对想要深入理解并应用MCMC算法的读者提供了宝贵的资源。在本文中,我们将详细解析MCMC的基本概念、工作原理以及它在实践中的应用。 Markov Chain Monte Carlo是一种统计计算方法,其...

    jdchain 企业级区块链框架系统java源码

    3. **高性能**:优化的并发处理和数据存储策略,使得jdchain能够处理大规模的交易请求,满足企业级应用的需求。 4. **API接口**:提供全面的API接口,方便与其他系统集成,实现业务流程自动化。 5. **跨链互操作性...

    前端开源库-bench-chain

    总的来说,`bench-chain`是前端开发者手中的一把利器,它能帮助我们更好地理解和优化代码性能,提高应用的运行效率。通过深入理解并熟练运用此库,开发者可以持续提升前端项目的性能,为用户提供更流畅的体验。

    Lincoln Chain

    Lincoln Chain

    Boosting Chain Learning for Object Detection

    ### 提升链(Boosting Chain)在目标检测中的应用 #### 概述 提升链(Boosting Chain)是一种被提出用于目标检测问题的通用分类框架。该方法的主要贡献在于引入了一个“链式”结构,旨在将历史知识整合到连续的...

Global site tag (gtag.js) - Google Analytics