Zend Framework的缺陷(连载之1)
程序员文章站
2022-05-11 10:15:29
...
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的中文手册中有这么一个用户注解。代码虽较为初级,但却实现了实际的需求。
从现在开始,将抽空发一个长篇的找抽的文章。专门谈一谈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框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法_PHP
-
Zend Framework的PHP编码标准1 php zend framework zend framework mvc zend framework pdf
-
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法_PHP
-
PHP框架之使用Zend Framework中的Zend_Mail发送邮件讲解
-
Zend Framework的缺陷(连载之1)
-
Zend Framework的缺陷(连载之1)
-
zend framework 1的zend db查询结果会变少,甚至没有,有遇到的吗?
-
Zend Framework的PHP编码标准1 php zend framework zend framework mvc zend framework pdf
-
zend framework 1的zend db查询结果会变少,甚至没有,有遇到的吗?
-
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法,zendzend_mail