一步步編寫簡單的PHP的Framework(五)

 上一次我講到使用自動導入能夠實現一個類的延遲加載,這一次我想講一下配置文件。php

       不知道你們注意了沒有,前幾篇文章我都沒有涉及到配置文件,但是在一個項目中,配置文件又是比不可少的。數組

       如今假設將Route.php中的默認控制器和Action變爲可配置的,怎麼弄呢?框架

       咱們使用最簡單的方式:函數

 

<?php
 $defaultController = 'Index';
 $defaultAction = 'index';

 

      而後在Route.php中include這個文件:code

 

<?php
include APP_PATH . '/config.php';
$controller = empty($_GET['c']) ? $defaultController : trim($_GET['c']); //設置了默認的控制器
$action = empty($_GET['a']) ? $defaultAction : trim($_GET['a']); //設置了默認的Action

固然也可使用這種方式:對象

 

 

<?php
return array(
       'defaultController' => 'Index',
       'defaultAction' => 'index'
);

     仍是在Route.php中include:blog

 

 

<?php
$config = include APP_PATH . '/config.php';
$controller = empty($_GET['c']) ? $config['defaultController'] : trim($_GET['c']); //設置了默認的控制器
$action = empty($_GET['a']) ? $config['defaultAction'] : trim($_GET['a']); //設置了默認的Action

 

      可是因爲配置文件頗有可能在整個框架運行過程的各個類都有用到,而前兩種方式都只能在某一個類裏面的某一個方法中使用,怎麼讓它在各個類均可以使用呢?ip

      咱們能夠可使用一個static方法來解決,好比專門定義一個Config類來存放配置信息,Config::get來讀取配置信息,Config::set來設置配置信息,具體作法讀者能夠本身去嘗試一下。字符串

      固然我不許備採用這種方式,可能當時我看Thinkphp源碼的時候被它優雅的特殊函數C迷住了吧,後面我在寫Toper的時候也使用了一些特殊的函數,而C主要是負責設置和讀取配置信息,我的觀點,面向對象是必要的,可是不是什麼都要面向對象,因此我準備定義一個function.php來存放一些公有的函數,我把它稱爲公有函數庫。get

      因爲有了公有函數庫,咱們能夠將上一篇裏面的自動導入(__autoload)也轉移到這個文件中,由於在Route.php出現一段__autoload的代碼仍是挺詭異的!!

      好了,怎麼實現剛纔咱們說的經過一個函數來實現配置信息的設置和讀取呢?

      好了,先展現我在Toper中的實現吧:

      

function C($name = null,$val = null) {
	static $_config = array();
	if(empty($name)) {
		return $_config;
	} elseif(is_string($name)) {
		if(empty($val)) {
			if(!strpos($name,'=>')) {
				//一維
				return isset($_config[$name]) ? $_config[$name] : null;
			} else {
				//目前只支持二維
				$name = explode('=>',$name);
				return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
			}
		} else {
			if(!strpos($name,'=>')) {
				//直接設置
				$_config[$name] = $val;
			} else {
				//設置二維
				$name = explode('=>',$name);
				$_config[$name[0]][$name[1]] = $val;
			}
		}
	} elseif(is_array($name)) {
		foreach($name as $key=>$value) {
			$_config[$key] = $value;
		}
		return ;
	} else {
		throw new Exception('參數類型出錯');
		return ;
	}
}

 

         看着代碼挺長的,實際上原理很簡單,若是傳遞的參數只有一個,那麼第二個參數就調用默認參數,即NULL,再識別是否第一個參數是不是字符串,那麼這個函數就識別爲讀取,若是第二個參數不爲空或第一個參數爲數組,那麼就識別爲設置!!

         因爲我本身如今比較懶,並且我用這個函數用的函數蠻順手的,因此在這兒我就直接用這個函數來做爲例子了,更多內容能夠查看Toper的/Library/Toper/function.php。

         好比如今要讀取defaultController,那麼只要使用C('defaultController')便可,若是要設置,那麼使用C('defaultController','Index')!!!

          如今咱們只須要在入口文件中導入這個function.php便可:

 

<?php
defined('APP_PATH') || define('APP_PATH',dirname(__FILE__) . '/..');
defined('FRAMEWORK_PATH') || define('FRAMEWORK_PATH',APP_PATH . '/Library/Test');
defined('MODULES_PATH') || define('MODULES_PATH',APP_PATH . '/UserApps/Modules');
include FRAMEWORK_PATH . '/function.php';
include FRAMEWORK_PATH . '/Route.php';
Route::run();

         你們可能注意到了,C函數最開始的時候,裏面沒有存聽任何元素,那麼咱們怎麼樣進行初始化,將配置文件的內容寫入C函數呢?

 

          以前咱們將配置文件存放在項目根目錄,這樣其實是不符合以前咱們的約定的規範,因此如今講這個配置文件剪切到/UserApps/Configs目錄下面,爲了更方便的使用這個路徑,咱們定義一個CONFIGS_PATH來指向配置文件的路徑。

        如今咱們看看入口文件變成了什麼樣了:

 

<?php
defined('APP_PATH') || define('APP_PATH',dirname(__FILE__) . '/..');
defined('FRAMEWORK_PATH') || define('FRAMEWORK_PATH',APP_PATH . '/Library/Test');
defined('MODULES_PATH') || define('MODULES_PATH',APP_PATH . '/UserApps/Modules');
defined('CONFIGS_PATH') || define('CONFIGS_PATH',APP_PATH . '/UserApps/Configs');
include FRAMEWORK_PATH . '/function.php';
C(include CONFIGS_PATH . '/config.php'); //寫入配置信息
include FRAMEWORK_PATH . '/Route.php';
Route::run();

      而後咱們修改一下Route.php

 

 

<?php
class Route {
	public static function run() {
		$controller = empty($_GET['c']) ? C('defaultController') : trim($_GET['c']); //設置了默認的控制器
		$action = empty($_GET['a']) ? C('defaultAction') : trim($_GET['a']); //設置了默認的Action
		$controllerBasePath = APP_PATH . '/UserApps/Modules/Controllers/';
		$controllerFilePath = $controllerBasePath . $controller . 'Controller.php';
		if(is_file($controllerFilePath)) {
			include $controllerFilePath;
			$controllerName = $controller . 'Controller';
			if(class_exists($controllerName)) {
				$controllerHandler = new $controllerName();
				if(method_exists($controllerHandler,$action)) {
					$controllerHandler->$action();
				} else {
					echo 'the method does not exists';
				}
			} else {
				echo 'the class does not exists';
			}
		} else {
			echo 'controller not exists';
		}
	}
}

      今天的例子 點此下載

相關文章
相關標籤/搜索