Maison  >  Article  >  php教程  >  一步步编写PHP的Framework(八)

一步步编写PHP的Framework(八)

WBOY
WBOYoriginal
2016-06-21 08:50:46902parcourir

 

既然前端控制器控制一切,那么我们可以用它来做更多的事情!!

我们知道,在windows里面默认php.ini中display_errors默认开启,而在linux中默认是关闭的,那么这样对于程序的调试时很麻烦的,所以我们可以在配置文件中设置一个debug属性,它代表是否调试打开,如果打开调试,程序出现任何异常,那么会输出很多调试信息。在这儿,我只是很简单的设置一下,真正的框架调试功能肯定不是这样简单的。

先我们实现如果debug开启,那么显示调试信息debug mode:这样一个字符串,并且如果程序有语法或其他错误,显示错误信息,如果调试关闭,那么任何错误信息都不显示。

现在修改FrontController的__construct函数:

01 private function __construct() {

02         C(Config::factory(Config::PHP)); //写入配置信息

03         session_start();

04         if(true === C('debug')) {

05             echo 'debug mode:';

06             ini_set('display_errors','On');

07             error_reporting(C('errorReporting'));

08         } else {

09             error_reporting(0);

10             ini_set('display_errors','Off');

11         }

12     }

在这个函数中,主要就新增了调试功能并且默认打开了session,由于PHP中关于错误的配置主要有error_reporting函数和php.ini中的display_errors这一项,所以只需要设置这两项,不管操作系统是什么样的,都可以好好的控制住调试信息了。

 

写过PHP程序的人可能都会知道,PHP默认的时区不是中国的,所以如果你使用date函数取出当前时间戳的时候,会发现不对,所以需要明确指定时区,其实这个工作就可以完全由框架完成,只要在配置文件中写入时区的值,然后框架调用date_default_timezone_set这个函数设置时区即可。

这样的话,FrontController的__construct这个函数就变成了下面这样了:

01 private function __construct() {

02         C(Config::factory(Config::PHP)); //写入配置信息

03         session_start();

04         date_default_timezone_set(C('timeZone'));

05         if(true === C('debug')) {

06             echo 'debug mode:';

07             ini_set('display_errors','On');

08             error_reporting(C('errorReporting'));

09         } else {

10             error_reporting(0);

11             ini_set('display_errors','Off');

12         }

13     }

 

如果大家看过Toper的源码的FrontController.class.php这个文件的话,就会注意到这个文件代码也还是挺多的,并不像我现在这儿写的这样,只有二十多行,这实际上是因为一个Framework的FrontController还需要做很多其他的事情,比如防止CSRF攻击,支持自定义配置项等,而这些由于篇幅原因我写不了。

设置debug模式在真实的Framework也不是只输出debug mode:这样一个字符串而已,这点大家必须要清楚。

学过Java的人都知道在Java中所有对象都有一个基类Object,在框架中是否也可以使用一个基类呢?

这个基类做一些什么功能呢,比如当调用了一个类的不存在 的方法,那么它会调用__call这个魔术方法,如果我们在基类中覆盖这个方法,那么其他所有类继承这个类,调用这些类的方法的时候,如果不存在,自然也就转到了这个方法,在这个方法中可以做一些补救措施,这样总比直接输入方法不存在要好一些。

我们暂时就把这个基类称为Base,在Toper中,这个基类叫Tp。

先贴出Base.php的源码:

01

02 class Base {

03     public function __call($name,$arguments) {

04         if(true === C('debug')) {

05             echo 'not exists method:';

06             echo 'the name is :';

07             var_dump($name);

08             echo 'the arguments is :';

09             var_dump($arguments);

10         }

11         throw new Exception('not exists method');

12     }

13 }

暂时功能写简单一点,如果调试打开,那么就把不存在的方法名和参数输出来,这样对于开发者更容易找到错误发生的位置,当然,不管调试是否打开,Exception肯定是要抛出的。当然,在线上的时候,如果出现这种问题,能直接把异常信息展现在页面上吗,不能,最好是能将异常信息输出到日志文件,然后页面跳转到错误页,那这样最好我们自定义一套异常处理的类,这些类继承自Exception,然后判定是否debug开启,如果开启debug,那么直接输出信息,否则,将异常信息输出到日志文件,然后跳转到错误页,具体怎么做,你可以自己试一试!!!

 

不知道大家注意到没有,所有我写的php文件我都没有写php的结束符?>,这是为什么呢?

实际上很简单,我举一个例子:

现在有a.php和b.php,a.php的源码是这样:

1

2 //这个地方貌似没有输出哦

3 ?>

 

然后b.php的源码是这样:

1

2 include a.php

3 session_start();

4 ?>

 

如果大家运行一下,会发现它会抛出警告说header already send out ,为什么呢?

主要是a.php在PHP结束符调用之后还有几行空白,那么PHP会认为它是HTML代码,这样是不是在调用session_start之前,就已经有header输出了嘛,我们知道,调用session_start之前,是不能有任何输出的,所以程序就会抛出警告。

如果使用?>,那么我们可能会在不经意间犯这个错误,当项目大,代码量大之后,要找到这样一个问题是很难的,这样给代码的维护带来很严重的问题,所以,最好在PHP文件最后不要写?>,这也是zend官方推荐的做法。



Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn