Seagull Framework DebuggingIdeas 有助于调试的一些建议
2010-01-25 09:47:26   来源:   评论:0 点击:

简介

Seagull框架使用/trunk/lib/SGL/ErrorHandler.php取代了PHP的默认出错处理。错误基本上是分成两种类型,由系统发出的错误和由开发者发出的错误。除了这些区别之外,一个错误可以是一个PHP错误,如,来自PHP引擎或由开发者通过PHP的trigger_error()函数发出的错误,也可以是一个PEAR错误。

错误

 

出错处理的几种类型

Seagull的出错处理允许你通过在应用程序配置中定义极限来自定义任何出错类型错误的输出。如果发生错误,则执行下列操作:

  • 隐藏错误输出不让它显示到页面。除非发生一个解析的错误导致脚本无法执行, 因此出错处理无法起作用。
  • 在配置文件中如果日志记录是激活的,当错误达到你定义的极限时, 它将被记录到你所选择的目标中如文件,db等
  • 将达到SGL_EMAIL_ADMIN_THRESHOLD的错误邮寄给管理员。虽然把它设置成PEAR_LOG_EMERG适合于开发,但是对于一个正在使用的站点设置它给PEAR_LOG_WARNING是个不错的意见。发给管理员的邮件保存了许多有用的额外信息:最后的查询,客户端的细节等
  • 开发者可以初始化一个调试session,这个SESSION发送已格式化的出错信息给浏览器(不管是PEAR还是PHP的)。如果启用此项功能, 只有可信的IP才有权使用这些特性。要开始一个调试session,发送以下的参数给$_GET,也就是,在URI中:

/debug/on/ 传递'/debug/off'来结束调试session.

哪些代码执行这些工作

至于代码,PHP出错由seagull/lib/SGL/ErrorHandler.php处理。这个类主要是通过在SGL_Task_SetupPearErrorCallback()任务使用set_error_handler()函数,而PEAR错误由在SGL_Task_SetupPearErrorCallback()任务调用pearErrorHandler()函数处理。通过下列代码回调:

PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'pearErrorHandler')

错误的严重性被动态地传给logs,严重性的等级通过简单的PHP/PEAR映射到PEAR::Log的等级,查看ErrorHandler?的构造函数以获得详细信息。

如果你使用LINUX系统,你通过取消ErrorHandler类中highlight_file的注释来启用此功能,不幸的在windows上这是无效的。

充分利用日志文件

日志文件会在错误/反馈发生时自动为所有的linux用户进行交互式跟踪捕捉,然而,window用户就不能使用这个功能,但也并不是说毫无办法,window用户可以利用很多的unix仿真模拟工具,虽然比较复杂,但可以取得相同的效果.MSYS是一个理想的轻量包,体积小,容易安装,并提供同样的UNIX跟踪功能.

tail -f [path-to-seagull]/var/log/php_log.txt

其它模仿tail的Windows程序:mTAIL

要启用日志,请进入配置界面,选择‘logs’标签并选择启用。debug优先等级提供最多的反馈信息。

如何处理Notices

E_NOTICE级别出错报告默认是激活的。Seagull将错误等级设置为E_ALL,而且让你的类工作在这个错误等级是个不错的意见。如果你想禁用notice,只需简单地注释掉/seagull/lib/SGL/Error Handler.php中errorType数组的 'notice'元素。

额外,如果你的代码可能会抛出notices错误,你可以使用下面代码隐藏错误:

SGL::setNoticeBehaviour(SGL_NOTICES_DISABLED);

//  code that throws notices

SGL::setNoticeBehaviour(SGL_NOTICES_ENABLED);

开发者触发的错误

要抛出错误,鼓励开发者使用Seagull的静态方法:

SGL::raiseError('message text', [SGL_ERROR_CONST], [PEAR_ERROR_DIE])

第一个参数是你希望发出的信息;第二个参数是可选的,定义在constants.php中,是seagull出错的常量中的任何一种;第三个参数PEAR_ERROR_DIE是可选的,将中断程序的执行.如果使用第三个参数,那么第一个参数消息会被发送给界面而不管调试是否是激活的。

许多熟悉DB_DataObject的开发者将会注意到相似点,方法签名1)是一样的,功能性差不多完全相同,不过它的实现更简单。

SGL出错常量

  // SGL::raiseError()使用的错误代码,为了不与PEAR::DB错误代码冲突,从-100开始
  * SGL_ERROR_INVALIDARGS', -101 // 传给函数的错误参数
  * SGL_ERROR_INVALIDCONFIG', -102 // 配置出错
  * SGL_ERROR_NODATA', -103 // 没有可用的数据
  * SGL_ERROR_NOCLASS', -104 // 类不存在
  * SGL_ERROR_NOMETHOD', -105 // 方法不存在
  * SGL_ERROR_NOAFFECTEDROWS', -106 //没有被update/insert/delete受影响的行 
  * SGL_ERROR_NOTSUPPORTED', -107 // 在无支持的数据库上限制查询
  * SGL_ERROR_INVALIDCALL', -108 // 超载getter/setter失败
  * SGL_ERROR_INVALIDAUTH', -109
  * SGL_ERROR_EMAILFAILURE', -110
  * SGL_ERROR_DBFAILURE', -111
  * SGL_ERROR_DBTRANSACTIONFAILURE',-112
  * SGL_ERROR_BANNEDUSER', -113
  * SGL_ERROR_NOFILE', -114
  * SGL_ERROR_INVALIDFILEPERMS', -115
  * SGL_ERROR_INVALIDSESSION', -116
  * SGL_ERROR_INVALIDPOST', -117
  * SGL_ERROR_INVALIDTRANSLATION', -118
  * SGL_ERROR_FILEUNWRITABLE', -119
  * SGL_ERROR_INVALIDMETHODPERMS', -120
  * SGL_ERROR_INVALIDREQUEST', -121
  * SGL_ERROR_INVALIDTYPE', -122
  * SGL_ERROR_RECURSION', -123

调试

 

使用Zend调试器

捕捉问题的最好方法之一是使用像Zend IDE提供的调试器。有些捕捉你要经常访问需要身份验证的页面。因此,你必开始一个session,登录,然后导航回到问题所在的页面。避开这种问题的一种简单的方法是,将配置文件的'Enable authentication' 选项设置为'no'。这样才能允许你访问框架里的任何资源,就如同你是管理用户,无须登录。

你的服务器对应的Zend debugger扩展二进制包可以从这里下载:http://downloads.zend.com/pdt/server-debugger/

安装是很简单的(查看上面链接中压缩文档的readme.txt)

Zend Debugger installation instructions
---------------------------------------

1. Locate ZendDebugger.so or ZendDebugger.dll file that is compiled for the
   correct version of PHP (4.3.x, 4.4.x, 5.0.x, 5.1.x, 5.2.x) in the 
   appropriate directory.

2. Add the following line to the php.ini file:
   Linux and Mac OS X: zend_extension=/full/path/to/ZendDebugger.so
   Windows:            zend_extension_ts=/full/path/to/ZendDebugger.dll

3. Add the following lines to the php.ini file:
   zend_debugger.allow_hosts=<ip_addresses>
   zend_debugger.expose_remotely=always 

4. Place dummy.php file in the document root directory.

5. Restart web server.

Debug sesssions

  • debug sessions 在Seagull 0.6.3以上版本中才可用

开发人员还可以调用一个拥有特权的debug session -这个特性在已经发布的站点2)上是可用的。概念是很简单的,只要开发人员知道密钥并做为参数传送给session,那么他就可以使用调试信息。当某些错误只会在处理实际数据发生这种方法是非常方便的。要设置一个debug session,请按下列步骤:

 1. 在Config -> Debug screen, 将'enable debug session'设为true
 2. 在Config -> General 在'admin key'设置一个密钥以用来调用调试session。
 3. 登出
 4. 通过下列URL启动带有特权的session
    http://example.com/index.php?adminKey=my_secret_key
 5. 下面条件输出任何变量或数据将被显示
    if (SGL_Config::get('debug.sessionDebugAllowed')) {
        echo 'this is debug';
    }

调试Db_DataObject

正如熟悉Db_DataObject包的开发者所知道的,在类中已内置了一个用来显示调试信息的机制。在Db_DataObject配置数组$options中(数组位于init.php的中底部),有个命名为'debug'的Key,它的值默认地设置为0。Db_DataObject识别5个等级的调试信息,5是最详细的–改变这个设置可以发送调试信息给到屏幕。

调试CLI应用程序

请查看下面这个文件以获得Mr. Beaver的一些宝贵意见:

http://greg.chiaraquartet.net/archives/16-Incredible-Zend-ZDE-debugging-trick-for-debugging-CLI-apps.html

实例:

export   QUERY_STRING="start_debug=1&debug_port=10000&debug_fastfile=1&debug_host=192.168.60.1%2C172.16.247.1%2C192.168.2.3%2C127.0.0.1&send_sess_end=1&debug_no_cache=1158079848619&debug_stop=1&debug_url=1&debug_start_session=1&no_remote=1"

调试XML-RPC应用程序

Debugging Ajax应用程序

主要有两种选择:

使用Zend

从Firefox的Zend工具条上选择Debug Menu → Next page。从浏览器激发一个Ajax请求 - 这样就会启动调试session。

使用Unit Tests

  • requires >= Seagull 0.6.3

在unit test中你可以创建Ajax类型的子请求,如调用SGL_Request_Ajax和Ajax特殊的过滤链,使用下列代码

$req = SGL_Request::singleton(true, SGL_REQUEST_AJAX);
$req->set('moduleName', 'foo');
$req->set('action', 'getPersonById');
$req->set('usrId', 1);
SGL_Config::set('debug.authorisationEnabled', false);
SGL_FrontController::run();

检查全局命名空间

经常检查seagull的命名空间是相当有帮助的,它可以知道正在执行中的变量有哪些.$GLOBALS['_SGL']中可以找到许多与框架有关系的变量,查看所取得的数据的最好方法是:

print_r($GLOBALS['_SGL']);

为了改进格式,可随意地包含PRE标签.检查请求对象的性能也是有用的,这样可检查输入的对象来查看你是否已经成功地映射到所需要的,已过滤的数据.为了执行这些你可以在任一个validate()方法的最开始输出请求对象.

$req→debug();

或在任一个validate()方法的末尾输出input对象,来查看哪些数据被返回给controller.

 
print_r($input);

使用Debug Block

对于0.6.1版本,你可以在配置文件中激活[debug][enableDebugBlock], 那么下次你运行维护部分的重构功能时,会在左侧出现一个debug block。它允许你使用重构功能而无须登陆到相关的管理员界面。目前只对管理员启用该功能。

验证输入

print '<pre>'; 
print_r($input); 
print '</pre>';

把上面的代码添加到validate()方法的结尾.你可以查看request上的哪些变量被成功赋值给输入对象

单元测试

这个项目真的应该尽可能多地使用单元测试,但而由于资料的缺乏,只有少数的能够在浏览器上运行的测试存放在

/trunk/tests

更多关于单元测试的信息请查看 Standards/UnitTesting

测试工具

有不同的工具有来测试PHP应用程序,如:

关于单元测试的文章/指南

UAT Testing

有一个Eclipse插件Solex(http://solex.sourceforge.net/)有同样的功能但没有应用提取和替换规则的功能。

1) 方法签名,或函数签名一般是指方法或函数的原型
2) 或者说站点处理发布模式时,可以通过全局配置文件中的配置选项修改设置

相关热词搜索:建议

上一篇:Seagull Framework Logging 如何将事件记录到日志中
下一篇:最后一页

分享到: 收藏
频道总排行
频道本月排行