当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

Zend Framework的缺陷(连载之1)

发表于: 2010-05-03   作者:bardo   来源:转载   浏览次数:
摘要: Zend Framework的缺陷 从现在开始,将抽空发一个长篇的找抽的文章。专门谈一谈PHP官方的Zend Framework的一些设计缺陷。欢迎大家拍砖! (1)Exception类的缺陷: Zend Framework中的Exception看起来设计得非常精巧,实质上,那是由于它了解PHP的源码,强行为了适应php5.2和php5.3而写出的这样的怪胎。 其根本目的,是为了能够向用户
Zend Framework的缺陷
从现在开始,将抽空发一个长篇的找抽的文章。专门谈一谈PHP官方的Zend Framework的一些设计缺陷。欢迎大家拍砖!
(1)Exception类的缺陷:
Zend Framework中的Exception看起来设计得非常精巧,实质上,那是由于它了解PHP的源码,强行为了适应php5.2和php5.3而写出的这样的怪胎。
其根本目的,是为了能够向用户提供链式的Exception。然而,可悲的是:此类中,并没有提供一个函数,能够直接向用户提供链式的Exception信息。
也许,很多衩学者不解,链式的Exception信息有什么用处?
我们还是从错误与异常的处理的基本知识着眼讲解一下:
  * 什么时间用 @
  * 什么时间用 return FALSE
  * 什么时间用 exit die
  * 什么时间用 trigger_error
  * 什么时间用 throw 抛出异常
return FALSE 只是在程序无论结果如何,用户都能清楚,不需要了解错误详情,并且,也不需要对程序进行任何处理的情况下使用当程序能够直接退出,并且程序是在调试状态时,则可以用exit和die,因为,exit和die能够简单地向输出目标,比如浏览器页面,或控制台,或重定向后的文件输出你所指定的信息。但exit和die没有抛出错误或异常,所以,你无法通过集中重定向到格式化的页面。@本质是封住相关的错误与警告信息。最终使代码能够平安地return FALSE。
trigger_error 可以使用的情况则是,能够确定,这个地方是在运行时绝对不能错的,程序一但调试好,那么,也就不会再出错的, trigger_error 也是在程序调试与正式运行时,向用户报告信息。trigger_error 目标是程序必须中断。而不能继续。并且,可以被errhandle程序捕获。不同于exit和die,它们是直接退出。
exit和die是在正式使用时,是程序需要直接退出,与错误无关。
用throw 抛出异常,则是你这一段程序中出现的问题交给用户处理,由用户来决定,程序是否继续的一种方法。当然,在此情况下,也就存在了另一种危险。那就是,如果用户不清楚哪里会抛出了异常,那么,有异常就不能被捕获,造成真实的错误中断。
用throw 抛出异常时,如果程序中使用set_exception_handler,则与程序中使用set_error_handler的结果一样,会把异常集中处理。但通常是,异常是要分开处理的。而错误则是要集中处理的。 有监于这一点,用户自定义异常类是很有必要的。
在处理异常之时,我们直接判断类型,那是最方便的。所以,一般情况下,是定义不同类型的异常 类,然后,可以直接用instanceof判断。但是,这虽然方便,却有另外一个问题,那就是我们需要定义相当多的类,以用于我们不同情况下的需要。
异常是否需要支持链式异常?链式异常的好处是可以知道异常的来龙去脉,为什么要了解这些?
一旦有所了解,就能够清楚,我们在编码时,在哪些地方必须要使用异常捕获管理。这样,代码就不会留下后患。但正式支持链式异常也只有php5.30才开始,所以,低于这样的版本需要框架提供代码来实现。因为开发者正常查看框架的源码的机会比较少。甚致也不会遵循代码示例。可见,链式异常最大的好处是能够让用户了解并清楚异常的来龙去脉。

从上面这些,我们可以发现,如果我们能够向用户提供链式异常的详细信息才是最为重要的。
如何提供呢?
php5.2的中文手册中有这么一个用户注解。代码虽较为初级,但却实现了实际的需求。
/* Author : Romain Boisnard */
/* Liscenced under the LGPL GNU Lesser General Public Liscence, report the actual liscence for details.

/* LinkedException */
// Java-like exception with a cause

class LinkedException extends Exception {
    private $cause;
    
    function __construct($_message = null, $_code = 0, Exception $_cause = null) {
        parent::__construct($_message, $_code);
        $this->cause = $_cause;
    }
    
    public function getCause() {
        return $this->cause;
    }
    
    public function getStackTrace() {
        if ($this->cause !== null) {
            $arr = array();
            $trace = $this->getTrace();
            array_push($arr, $trace[0]);
            unset($trace);
            if (get_class($this->cause) == "LinkedException") {
                foreach ($this->cause->getStackTrace() as $key => $trace) {
                    array_push($arr, $trace);
                }
            }
            else {
                foreach ($this->cause->getTrace() as $key => $trace) {
                    array_push($arr, $trace);
                }
            }
            return $arr;
        }
        else {
            return $this->getTrace();
        }
    }
    
    public function showStackTrace() {
        $htmldoc = "<p style=\"font-family: monospace; border: solid 1px #000000\"><span style=\"font-weight: bold; color: #000000;\">An exception was thrown :<br/></span>";
        $htmldoc.= "Exception code : $this->code<br/>";
        $htmldoc.= "Exception message : $this->message<br/>";
        $htmldoc.= "<span style=\"color: #0000FF;\">";
        $i = 0;
        foreach ($this->getStackTrace() as $key => $trace) {
            $htmldoc.= $this->showTrace($trace, $i);
            $i++;
        }
        $htmldoc.= "#$i {main}<br/>";
        unset($i);
        $htmldoc.= "</span></p>";
        return $htmldoc;
    }
    
    private function showTrace($_trace, $_i) {
        $htmldoc = "#$_i ";
        if (array_key_exists("file",$_trace)) {
            $htmldoc.= $_trace["file"];
        }
        if (array_key_exists("line",$_trace)) {
            $htmldoc.= "(".$_trace["line"]."): ";
        }
        if (array_key_exists("class",$_trace) && array_key_exists("type",$_trace)) {
            $htmldoc.= $_trace["class"].$_trace["type"];
        }
        if (array_key_exists("function",$_trace)) {
            $htmldoc.= $_trace["function"]."(";
            if (array_key_exists("args",$_trace)) {
                if (count($_trace["args"]) > 0) {
                    $args = $_trace["args"];
                    $type = gettype($args[0]);
                    $value = $args[0];
                    unset($args);
                    if ($type == "boolean") {
                        if ($value) {
                            $htmldoc.= "true";
                        }
                        else {
                            $htmldoc.= "false";
                        }
                    }
                    elseif ($type == "integer" || $type == "double") {
                        if (settype($value, "string")) {
                            if (strlen($value) <= 20) {
                                $htmldoc.= $value;
                            }
                            else {
                                $htmldoc.= substr($value,0,17)."...";
                            }
                        }
                        else {
                            if ($type == "integer" ) {
                                $htmldoc.= "? integer ?";
                            }
                            else {
                                $htmldoc.= "? double or float ?";
                            }
                        }
                    }
                    elseif ($type == "string") {
                        if (strlen($value) <= 18) {
                            $htmldoc.= "'$value'";
                        }
                        else {
                            $htmldoc.= "'".substr($value,0,15)."...'";
                        }
                    }
                    elseif ($type == "array") {
                        $htmldoc.= "Array";
                    }
                    elseif ($type == "object") {
                        $htmldoc.= "Object";
                    }
                    elseif ($type == "resource") {
                        $htmldoc.= "Resource";
                    }
                    elseif ($type == "NULL") {
                        $htmldoc.= "null";
                    }
                    elseif ($type == "unknown type") {
                        $htmldoc.= "? unknown type ?";
                    }
                    unset($type);
                    unset($value);
                }
                if (count($_trace["args"]) > 1) {
                    $htmldoc.= ",...";
                }
            }            
            $htmldoc.= ")<br/>";
        }
        return $htmldoc;
    }
}

Zend Framework的缺陷(连载之1)

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
1.和常规开发大致相同,首先下载zend framework1,下载地址如下 http://www.zendframework.com/downl
Zendframework 快速开始 目录 1、 Zend Framework & MVC 介绍 2、 创建你的项目 3、 创建布局(Layo
刚接触了两个礼拜的tp框架,结果项目要使用zend框架,虽说都是php框架,但还是有不少区别。这个贴子
zf 命令行工具 注:新的版本2.0.4结构已经改变,bin文件夹里面没有zf.bat zf.php zf.sh那三个文件,
今天想学一下php框架,就从网上搜索了php的一些比较著名的框架!本想好好地学一下,但是配置却花了
struts2出现的原因:struts1的缺陷 1.支持的表现层技术单一 Struts1只支持JSP作为表现层技术,不提
The Zend Framework MVC Architecture 一、概述: In this chapter, we will cover the following t
中文翻译见: http://phpeye.com/articles/tutorial.html 同时还有中文Zend Php Framework Zend Fra
在使用Zend Framework编写应用项目时,有时会依据项目需要将代码划分为多个不同的模块,以方便日后
http://www.kimbs.cn/2011/07/cron-job-script-in-zend-framework/#codesyntax_1 To create a cron
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号