`
bardo
  • 浏览: 371554 次
  • 性别: Icon_minigender_1
  • 来自: 上海
博客专栏
D1407912-ab64-3e76-ae37-b31aa4afa398
浅述PHP设计模式
浏览量:11591
9d6df9f7-91da-3787-a37c-0e826525dd5d
Zend Framewor...
浏览量:9967
85b628bd-a2ed-3de2-a4b1-0d34985ae8b6
PHP的IDE(集成开发环...
浏览量:9326
社区版块
存档分类
最新评论

Zend Framework的缺陷(连载之1)

    博客分类:
  • PHP
阅读更多
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;
    }
}
2
1
分享到:
评论
3 楼 rtxbc 2011-03-26  
bardo 写道
zend framework有没有生成静态页面的方法
freedomstyle 写道
不知道zend framework有没有生成静态页面的方法

那是没有的。静态页面规则较为复杂。这方面倒现在没有统一的方案。
另一方面,zend不会推出,因为,它不会排斥官方的smarty,这个是能生成页面缓存的。


在controller类里面使用$html =  $this->view->render('xml/codec.xml') ;可以把渲染后的结果放入到$html里,然后你可以用file_put_content()或者其他文件操作方式,生成你所需要的文件.
2 楼 bardo 2010-05-26  
zend framework有没有生成静态页面的方法
freedomstyle 写道
不知道zend framework有没有生成静态页面的方法

那是没有的。静态页面规则较为复杂。这方面倒现在没有统一的方案。
另一方面,zend不会推出,因为,它不会排斥官方的smarty,这个是能生成页面缓存的。
1 楼 freedomstyle 2010-05-24  
不知道zend framework有没有生成静态页面的方法

相关推荐

Global site tag (gtag.js) - Google Analytics