怎麼一步步編寫簡單的PHP的Framework(八)

      昨天我寫到咱們使用前端控制器來控制全部請求,今天咱們繼續這個話題。 php

       既然前端控制器控制一切,那麼咱們能夠用它來作更多的事情!! 前端

       咱們知道,在windows裏面默認php.ini中display_errors默認開啓,而在linux中默認是關閉的,那麼這樣對於程序的調試時很麻煩的,因此咱們能夠在配置文件中設置一個debug屬性,它表明是否調試打開,若是打開調試,程序出現任何異常,那麼會輸出不少調試信息。在這兒,我只是很簡單的設置一下,真正的框架調試功能確定不是這樣簡單的。 linux

       先咱們實現若是debug開啓,那麼顯示調試信息debug mode:這樣一個字符串,而且若是程序有語法或其餘錯誤,顯示錯誤信息,若是調試關閉,那麼任何錯誤信息都不顯示。 windows

       如今修改FrontController的__construct函數: session


private function __construct() {
		C(Config::factory(Config::PHP)); //寫入配置信息
		session_start();
		if(true === C('debug')) {
			echo 'debug mode:';
			ini_set('display_errors','On');
			error_reporting(C('errorReporting'));
		} else {
			error_reporting(0);
			ini_set('display_errors','Off');
		}
	}
         在這個函數中,主要就新增了調試功能而且默認打開了session,因爲PHP中關於錯誤的配置主要有error_reporting函數和php.ini中的display_errors這一項,因此只須要設置這兩項,無論操做系統是什麼樣的,均可以好好的控制住調試信息了。


         寫過PHP程序的人可能都會知道,PHP默認的時區不是中國的,因此若是你使用date函數取出當前時間戳的時候,會發現不對,因此須要明確指定時區,其實這個工做就能夠徹底由框架完成,只要在配置文件中寫入時區的值,而後框架調用date_default_timezone_set這個函數設置時區便可。 框架

         這樣的話,FrontController的__construct這個函數就變成了下面這樣了: 函數

 

private function __construct() {
		C(Config::factory(Config::PHP)); //寫入配置信息
		session_start();
		date_default_timezone_set(C('timeZone'));
		if(true === C('debug')) {
			echo 'debug mode:';
			ini_set('display_errors','On');
			error_reporting(C('errorReporting'));
		} else {
			error_reporting(0);
			ini_set('display_errors','Off');
		}
	}


          若是你們看過Toper的源碼的FrontController.class.php這個文件的話,就會注意到這個文件代碼也仍是挺多的,並不像我如今這兒寫的這樣,只有二十多行,這其實是由於一個Framework的FrontController還須要作不少其餘的事情,好比防止CSRF攻擊,支持自定義配置項等,而這些因爲篇幅緣由我寫不了。 操作系統

          設置debug模式在真實的Framework也不是隻輸出debug mode:這樣一個字符串而已,這點你們必需要清楚。 debug

           學過Java的人都知道在Java中全部對象都有一個基類Object,在框架中是否也可使用一個基類呢? 調試

           這個基類作一些什麼功能呢,好比當調用了一個類的不存在 的方法,那麼它會調用__call這個魔術方法,若是咱們在基類中覆蓋這個方法,那麼其餘全部類繼承這個類,調用這些類的方法的時候,若是不存在,天然也就轉到了這個方法,在這個方法中能夠作一些補救措施,這樣總比直接輸入方法不存在要好一些。

            咱們暫時就把這個基類稱爲Base,在Toper中,這個基類叫Tp。

             先貼出Base.php的源碼:


<?php
class Base {
	public function __call($name,$arguments) {
		if(true === C('debug')) {
			echo 'not exists method:';
			echo 'the name is :';
			var_dump($name);
			echo 'the arguments is :';
			var_dump($arguments);
		}
		throw new Exception('not exists method');
	}
}
           暫時功能寫簡單一點,若是調試打開,那麼就把不存在的方法名和參數輸出來,這樣對於開發者更容易找到錯誤發生的位置,固然,無論調試是否打開,Exception確定是要拋出的。固然,在線上的時候,若是出現這種問題,能直接把異常信息展示在頁面上嗎,不能,最好是能將異常信息輸出到日誌文件,而後頁面跳轉到錯誤頁,那這樣最好咱們自定義一套異常處理的類,這些類繼承自Exception,而後斷定是否debug開啓,若是開啓debug,那麼直接輸出信息,不然,將異常信息輸出到日誌文件,而後跳轉到錯誤頁,具體怎麼作,你能夠本身試一試!!!


           不知道你們注意到沒有,全部我寫的php文件我都沒有寫php的結束符?>,這是爲何呢?

           實際上很簡單,我舉一個例子:

            如今有a.php和b.php,a.php的源碼是這樣:


<?php
//這個地方貌似沒有輸出哦
?>
 
             而後b.php的源碼是這樣: 



<?php
include a.php
session_start();
?>
             若是你們運行一下,會發現它會拋出警告說header already send out ,爲何呢?


             主要是a.php在PHP結束符調用以後還有幾行空白,那麼PHP會認爲它是HTML代碼,這樣是否是在調用session_start以前,就已經有header輸出了嘛,咱們知道,調用session_start以前,是不能有任何輸出的,因此程序就會拋出警告。

              若是使用?>,那麼咱們可能會在不經意間犯這個錯誤,當項目大,代碼量大以後,要找到這樣一個問題是很難的,這樣給代碼的維護帶來很嚴重的問題,因此,最好在PHP文件最後不要寫?>,這也是zend官方推薦的作法。

              今天的代碼點此下載

相關文章
相關標籤/搜索