abstract:首先,我們來說一下,為什么要?jiǎng)?chuàng)建自己的框架?為什么要?jiǎng)?chuàng)建自己的框架呢?如果你跟周圍的人討論,每個(gè)人都會(huì)告訴你重復(fù)發(fā)明輪子是一件糟糕的事情,你最好選擇一個(gè)已有的框架,忘掉“創(chuàng)建自己的框架”這種想法。大部分情況,他們是正確的,但是我想到了幾個(gè)創(chuàng)建自己的框架的好處:了解更多框架的底層架構(gòu)創(chuàng)建一個(gè)能滿足你特殊需求的框架(但首先要確定你的需求真的是很特別)因?yàn)闃啡ざ囍鴮懸粋€(gè)框架(為了“學(xué)習(xí)然后拋棄”的目的
首先,我們來說一下,為什么要?jiǎng)?chuàng)建自己的框架?
為什么要?jiǎng)?chuàng)建自己的框架呢?如果你跟周圍的人討論,每個(gè)人都會(huì)告訴你重復(fù)發(fā)明輪子是一件糟糕的事情,你最好選擇一個(gè)已有的框架,忘掉“創(chuàng)建自己的框架”這種想法。大部分情況,他們是正確的,但是我想到了幾個(gè)創(chuàng)建自己的框架的好處:
了解更多框架的底層架構(gòu)
創(chuàng)建一個(gè)能滿足你特殊需求的框架(但首先要確定你的需求真的是很特別)
因?yàn)闃啡ざ囍鴮懸粋€(gè)框架(為了“學(xué)習(xí)然后拋棄”的目的)
想利用新的開發(fā)技術(shù)以及最佳實(shí)踐重構(gòu)已經(jīng)存在的項(xiàng)目
向世界證明自己也是可以寫出框架的(......但只需那么一點(diǎn)點(diǎn)付出)
我將一步步的,循序漸進(jìn)的引導(dǎo)你創(chuàng)建一個(gè)框架。每一步你得到的都是一個(gè)完全能使用的框架。我們將從一個(gè)簡單的框架開始,然后一點(diǎn)點(diǎn)的給它加功能。最后,你將能得到一個(gè)完整的web框架。
上面的原因是摘來的使用Symfony2的組件創(chuàng)建自己的PHP框架,覺得說的不錯(cuò)就直接拿過來用了。
我們先建立一個(gè)目錄,然后進(jìn)入該目錄
mkdir simple-framework cd simple-framework
然后分別建立放置controller/model/view等的目錄
mkdir controllers models views public
public用來存放統(tǒng)一的入口,在里面建立index.php,大部分框架現(xiàn)在都是單一入口。
然后我們需要支持以下composer,我們希望第三方的包都能通過composer來管理。如果你還不知道composer是什么,請(qǐng)查看composer。
在simple-framework文件夾下執(zhí)行 composer init,然后填寫相應(yīng)內(nèi)容,生成一個(gè)composer.json文件,其內(nèi)容大概如下:
{ "name": "craryprimitiveman/simple-framework", "description": "A simple php framework", "license": "MIT", "authors": [ { "name": "harrysun", "email": "sunguangjun@126.com" } ], "require": {} }
讓后修改以下,結(jié)果如下:
{ "name": "craryprimitiveman/simple-framework", "description": "A simple php framework", "license": "MIT", "authors": [ { "name": "harrysun", "email": "sunguangjun@126.com" } ], "require": {}, "autoload": { "psr-4": { "sf\\": "src/", "app\\": "" } }, "repositories": [ {"type": "composer", "url": "http://packagist.phpcomposer.com"}, {"packagist": false} ] }
其中的autoload是為了支持我們自己項(xiàng)目的文件加載,其中sf下的是framework的code,而app下的是正常業(yè)務(wù)羅輯的code, 其中的repositories是為了解決在國內(nèi)使用composer下載,下載不下來的問題,如果在國外,或者有VPN做代理,可以直接去掉。
然后執(zhí)行composer install。
這樣基本的目錄結(jié)構(gòu)就構(gòu)建好了。
在入口文件public/index.php中,引入autoload文件,如下:
<?php require_once __DIR__ . '/../vendor/autoload.php';
然后我們定義我們的url是這樣的http://localhost/simple-framework/public/index.php?r=site/test,之后會(huì)加相應(yīng)的nginx或apache的rewrite,是url變簡潔好看,但暫時(shí)先這樣。
這個(gè)url訪問了SiteController中的actionTest,下面我們來簡單實(shí)現(xiàn)這個(gè)功能。
<?php require_once __DIR__ . '/../vendor/autoload.php'; $router = $_GET['r']; list($controllerName, $actionName) = explode('/', $router); $ucController = ucfirst($controllerName); $controllerName = 'app\\controllers\\' . $ucController . 'Controller'; $controller = new $controllerName(); return call_user_func_array([$controller, 'action'. ucfirst($actionName)];
上面的code未添加任何的錯(cuò)誤處理,只是一個(gè)簡單的功能實(shí)現(xiàn)。
然后在controllers文件夾中添加SiteController.php文件,內(nèi)容如下:
<?php namespace app\controllers; class SiteController { public function actionTest() { echo 'success!'; } }
然后訪問之前的url http://localhost/simple-framework/public/index.php?r=site/test,你會(huì)看到打印出了success!
然后我們?cè)趤韺懸粋€(gè)actionView方法去渲染一個(gè)頁面。actionView的代碼如下:
public function actionView() { $body = 'Test body information '; require '../views/site/view.php'; }
我們還需要在views下面添加site文件夾,并在site文件夾下創(chuàng)建view.php文件,其內(nèi)容如下:
<html> <head> <title>title</title> <head> <body> <?php echo $body;?> </body> </html>
最后訪問http://localhost/simple-framework/public/index.php?r=site/view,會(huì)得到如下頁面: