製做本身的MVC框架(二)——啓動

本身寫了個框架,取名爲「PrimusPHP」,就3個文件夾,log中是日誌文件,會自動生成。php

app中就是控制器和視圖,public中是入口文件和靜態資源,library中既有框架的核心類,還有工具類,數據操做類等。nginx

這個框架會用到命名空間,PHP版本若是不能用命名空間,將不能執行。git

 

1、單一入口

index.php」就是入口文件,「defined.php」設置一些通用常量,例如絕對目錄,而且引入了初始化庫。github

define('ROOT', dirname(dirname(__FILE__)));
define('DS', DIRECTORY_SEPARATOR);

require_once LIB_PATH . DS . 'init.php';

index.php」就是在執行初始化方法。正則表達式

require_once '../defined.php';
define('APP_NAME', 'weixin');
define('CONFIG_PATH', APP_PATH . DS . APP_NAME . DS . 'conf');

InitPrimus::getInstance();

 

2、初始化

private function __construct() {
        $this->environment();//環境配置
        $this->reporting();//錯誤報告
        self::loadFunction(self::$config['autoload']['helper']);//加載輔助函數
        $this->_autoload();//自動載入
        self::openLog(); //開啓log
        self::loadClass('\library\core\Router');//路由
}

1)環境配置數組

一般會有三個配置環境,本地、測試和正式。服務器

之前曾經把三個環境的參數寫在一個文件中,而後版本控制的時候忽略文件,這樣作很不方便。微信

尤爲是在發佈版本的時候,若是要變裏面的參數,還得記得在哪裏改。微信開發

如今直接分三個文件,各自管各自的,誰也影響不到誰。app

library」中有三個配置文件,在「app」中也放在「conf」方便自行控制。

 

如何判斷當前環境是本地、測試仍是正式環境呢?

這裏我將這個變量埋在了「.htaccess」中,若是是nginx,也能夠配置。

RewriteEngine on
SetEnv ENVIRONMENT local

 

2)錯誤報告

錯誤提示在調試的時候頗有用,能定位到具體的行數,能提升修正效率。

在網上搜索了一下,找到了一些代碼,再借鑑了CI的錯誤代碼,嫁接到這個框架裏。

set_error_handler('exception_error_handler');//追蹤錯誤棧
register_shutdown_function('catch_fatal_error');//致命錯誤

exception_error_handler」和「catch_fatal_error」是兩個函數,寫在了「core/Common.php」中。

在「library/view」中預留了三種錯誤的模版頁面。

在URL中輸入「index/sign」錯誤的樣子以下:

 

3)加載輔助函數

框架中,常常會有一些函數或類,在一開始就被載入進來,這裏的這個輔助函數就是這個道理。

在配置文件中預先寫好要載入的文件名。

public static function loadFunction($name) {
        if(is_array($name)) {
            foreach ($name as $key) {
                include_once HELPER_LIB_PATH .  DS . $key . '_helper.php';
            }
        }else {
            include_once HELPER_LIB_PATH .  DS . $name . '_helper.php';
        }
}

 

4)自動載入

當「new \library\xx()」某個類的時候,會自動進入到「spl_autoload_register」函數中。

在回調函數中將「\library\xx」修改成具體路徑,在「include_once」進來,就初始化好了。

private function _autoload() {
        //$className是經過命名空間獲取的
        spl_autoload_register(function ($className) {
            $dir = false;
            $classNames = explode('\\', $className);//分割爲數組
            $autoDirs = self::$autoDirs;
            foreach ($autoDirs as $path) {
                $tmpInfo = pathinfo($path);
                if(in_array($tmpInfo['basename'], $classNames)) {
                    $dir = $tmpInfo['dirname'];
                    break;
                }
            }

            if($dir) {
                $file = $dir . DS . dir_replace_ds($className) . '.php';
                include_once($file);
            }
        });
}

 

5)日誌

平時開發的時候,我喜歡將查詢語句直接打印到日誌中,當將代碼放到線上了,也能調試各個語句的結果。

最近在作微信開發,有不少請求微信的服務器,這些請求的結果只能經過打印日誌看到。

日誌的類放在了「util/Log.php」中。

public function write($txt) {
        if(empty($txt) || !DEVELOPMENT_ENVIRONMENT) {
            return;
        }
        $name = date('Y-m-d') . '.log';
        if(!file_exists(LOG_PATH)) {
            mkdir(LOG_PATH, 0777, true);
        }
        $path = LOG_PATH . DS . $name;
        $content = date('Y-m-d H:i:s') . ' ' . $txt . "\n";
        file_put_contents($path, $content, FILE_APPEND);
}

 

3、路由

1)路由選擇

路由支持兩種,一種就是「index/index」,另一種是「v1/index/index」。

第二種能夠用於客戶端接口,當客戶端更新版本的時候,可能就須要新的接口,而老的接口又不能丟,就能夠新開一個模塊文件夾。

$params = explode('/', $uri);
        if(count($params) == 2) {
            $controller = $params[0];//控制器
            $action = $params[1];//操做方法
        }elseif(count($params) == 3) {
            $module = $params[0]; //模塊
            $controller = $params[1];//控制器
            $action = $params[2];//操做方法
        }else {
            $controller = 'index';
            $action = 'index';
        }

 

2)路由重定向

之前沒注意到重定向,最近在作微信開發的配置文件的時候就發現這個功能。

訪問「bridge.js」實際上是訪問了某個控制器的「action」,怪不得我在想那些微信token都是經過服務器獲取的,這個js文件是怎麼搞到的。

重定向規則能夠用正則表達式。

$init_conf['rewrite'] = array(
    '/new_bridge.js/' => 'index/config',
    '/new_bridge2.js/' => 'index/config2',
    '/p\/(\d+)/' => 'index/ticket?p=$1'
);

下面是正則匹配:

public function rewrite() {
        $config = \InitPrimus::getConfig('rewrite');
        foreach ($config as $src => $redirect) {
            //$pattern = '@^\/?' . $src . '\/?$@';
            if (\preg_match($src, $this->uri)) {
                $this->uri = \preg_replace($src, $redirect, $this->uri);
                break;
            }
        }
}

 

框架地址:

https://github.com/pwstrick/PrimusPHP

相關文章
相關標籤/搜索