從本章開始,我們繼續造輪子,去完成一款類似於Laravel的現代化PHP框架,為什麼說是現代化?因為他必須具備一下幾點:
前期做任何一件事情都要有個前期準備工作。
1、作為PSR-4的規定,我們命名空間得有一個祖宗名字,這裡我叫他神聖的 《z_framework》。
2、至少需要一個GITHUB庫來存儲這個項目:https://github.com/CrazyCodes/z_framework。
3、創建一個composer.json文件用於進行包管理,灰常簡單,phpunit搞進來。通過psr-4加載個項目命名。
{
"name": "z framework",
"require-dev": {
"phpunit/phpunit": "^7.0"
},
"autoload": {
"psr-4": {
"Zero\\": "src/Zero",
}
},
"autoload-dev": {
"psr-4": {
"Zero\\Tests\\": "tests/"
}
}
}
最後我們就需要考慮下目錄的結構及其我們第一步要完成的功能,核心的結構(這裡並非只的項目結構哦。是框架的核心結構)暫且是這樣:
- src
- Zero
- Config // 可能存放一些配置文件的解析器
- Container // 容器的解析器
- Http // 請求處理的一些工具
- Routes // 路由處理的一些功能
- Bootstrap.php // 這可能是一個啟動腳本
- Zero.php // 可能是核心的入口文件
- tests // 測試目錄
- .gitignore
- composer.json
- LICENSE
- README.md
路由還記得第一次使用Laravel時我們第一步做的事情嗎?是的,去研究路由,所以我們把路由作為框架的第一步。在研究路由前,我們要知道:
http://www.domain.com/user/create
是如何實現的,php默認是必須請求index.php或者default.php的,上述連結實際隱藏了index.php或default.php ,這是Nginx等服務代理幫我們做到的優雅的連結,具體配置如下,實際與Laravel官方提供無差別:
server {
listen 80;
server_name www.zf.com;
root /mnt/app/z_framework/server/public;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php71:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
通過:
try_files $uri $uri/ /index.php?$query_string;
去解析請求,通過上述可以得出:
http://www.domain.com/user/create
=======
http://www.domain.com/index.php?user/create
好了,明白了其中奧秘後,我們開始路由的編寫,在 src/Routes/Route.php:
namespace Zero\Routes;
class Route
{
}
實現首先我們先創建一個簡單的接口文件 src/Routes/RouteInterface.php:
namespace Zero\Routes;
interface RouteInterface
{
public function Get($url, $callFile);
public function Post($url, $callFile);
public function Put($url, $callFile);
public function Delete($url, $callFile);
}
從Get請求開始:
namespace Zero\Routes;
class Route implements RouteInterface
{
public function Get($url, $callFile)
{
}
}
最後實現Get代碼塊:
if (parent::isRequestMethod("GET")) { // 判讀請求方式
if (is_callable($callFile)) { // 判斷是否是匿名函數
return $callFile();
}
if ($breakUpString = parent::breakUpString($callFile)) { // 獲取Get解析。既/user/create
header('HTTP/1.1 404 Not Found');
}
try {
// 通過反射類獲取對象 $breakUpString[0] = user
$reflectionClass = new \ReflectionClass('App\\Controllers\\' . $breakUpString[0]);
// 實例化對象
$newInstance = $reflectionClass->newInstance();
// 獲取對象中的指定方法,$breakUpString[1] = create
call_user_func([
$newInstance,
$breakUpString[1],
], []);
} catch (\ReflectionException $e) {
header('HTTP/1.1 404 Not Found');
}
} else {
header('HTTP/1.1 404 Not Found');
}
return "";
如果你想測試上述代碼,可使用phpunit,或者傻大粗的方式,這裡便於理解使用傻大粗的方式。
創建一個目錄,隨後按照Laravel的目錄形式創建幾個目錄:
<?php
namespace App\Controllers;
class UserController
{
public function create()
{
var_dump(0);
}
}
最後public/index.php文件中去調用路由:
require_once "../../vendor/autoload.php";
Zero\Zero::Get("user", "UserController@create");
到這裡我們就基本完成了路由的功能,下一章將完善路由的編碼。
致謝感謝你看到這裡,希望本篇可以幫到你。具體代碼在 https://github.com/CrazyCodes/z_framework。
歡迎關注 SegmentFault 微信公眾號 :)