成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

手把手教你開發(fā)現(xiàn)代PHP框架

raise_yang / 3402人閱讀

摘要:本文將從零開始搭建一個現(xiàn)代化的框架,該框架會擁有現(xiàn)代框架的一切特征,如單入口,路由,依賴注入,類自動加載機(jī)制等等,如同時下最流行的框架一樣。執(zhí)行控制器文件中的邏輯代碼,最終將數(shù)據(jù)通過對應(yīng)的視圖層顯示出來。

本文將從零開始搭建一個現(xiàn)代化的PHP框架,該框架會擁有現(xiàn)代框架的一切特征,如單入口,路由,依賴注入,composer類自動加載機(jī)制等等,如同時下最流行的Laravel框架一樣。

一、開發(fā)環(huán)境搭建 1、開發(fā)環(huán)境搭建

這里我們使用 Homestead 來作為我們的集成開發(fā)環(huán)境,里邊集成了PHP、MySQL我們需要的軟件環(huán)境,或者也可以用Xampp集成環(huán)境來開發(fā),只要你安裝PHP、MySQL即可,我這里用Homestead做為開發(fā)環(huán)境。

homestead.yaml配置:

atom ~/.homestead/Homestead.yaml
---
ip: "192.168.10.10"
memory: 2048
cpus: 1
provider: virtualbox

authorize: ~/.ssh/id_rsa.pub

keys:
    - ~/.ssh/id_rsa

folders:
    - map: ~/Code
      to: /home/vagrant/Code

sites:
 
    - map: framework.app # <--- 這里,第五個項(xiàng)目,框架學(xué)習(xí)開發(fā)
      to: /home/vagrant/Code/php-framework # <--- 這里

databases:
    - php-framework

variables:
    - key: APP_ENV
      value: local

# blackfire:
#     - id: foo
#       token: bar
#       client-id: foo
#       client-token: bar

# ports:
#     - send: 50000
#       to: 5000
#     - send: 7777
#       to: 777
#       protocol: udp

重啟vagrant
修改完 Homestead.yaml 文件后,需要重新加載配置文件信息才能生效。

?  ~ cd Homestead
?  Homestead git:(7924ab4) vagrant reload --provision

修改hosts配置文件
Hosts配置域名在mac的位置: /etc/hosts

192.168.10.10 digtime.app
2、開發(fā)工具

我們可以選擇 Sublime,Atom,PHPStorm 這些IDE。

二、第一版-實(shí)現(xiàn)最基本的功能

現(xiàn)在,我們先創(chuàng)建一個簡單的框架,實(shí)現(xiàn)MySQLPDO的連接,查詢,創(chuàng)建引導(dǎo)文件,創(chuàng)建項(xiàng)目的配置文件(包括連接數(shù)據(jù)庫的用戶名和密碼等)

第一版本GitHub地址

三、第二版本-單一入口和mvc架構(gòu)

我們對目錄進(jìn)行重構(gòu),按照MVC功能劃分:

├── index.php
├── config.php
├── controllers
├── core
│   ├── bootstrap.php
│   └── database
│       ├── Connection.php
│       └── QueryBuilder.php
├── models
│   └── Task.php
└── views

現(xiàn)在我們再來添加兩張頁面about.php和contact.php, 按照之前我們說的邏輯層和視圖層分離的原則,我們還需要建立about.view.php和contact.view.php, 并在about.php和contact.php中引入它們的視圖文件。然后我們可以通過http://framework.app/about.php 或 http://framework.app/contact.php 之類的 uri 來訪問這些頁面, 像這種方式我們稱為多入口方式,這種方式對于小型項(xiàng)目還能管理,項(xiàng)目過大了,管理起來就會比較麻煩了。

現(xiàn)在的框架基本都是采用單一入口的模式,什么是單一入口,其實(shí)就是整個站點(diǎn)只有 index.php 這一個入口,我們訪問的任何 uri 都是先經(jīng)過 index.php 頁面,然后在index.php中根據(jù)輸入的 uri 找到對應(yīng)的文件或者代碼運(yùn)行,然后返回數(shù)據(jù)。

單一入口思路:
1.訪問http://framework.app/about.php這條路徑時,先進(jìn)入到 index.php
2.然后在 index.php 中會通過一些方法去找到與這條路由對應(yīng)需要執(zhí)行的文件,一般我們會把這些文件放到控制器中。
3、執(zhí)行控制器文件中的邏輯代碼,最終將數(shù)據(jù)通過對應(yīng)的視圖層顯示出來。

事實(shí)上,我們訪問 http://framework.app/about.php 這個路由時,它真正的路由是 http://framework.app/index.ph...然后通過Apache或者是Nginx做路由跳轉(zhuǎn),就可以實(shí)現(xiàn)成類式 http://framework.app/about.php 這樣的路由了。

重寫Nginx服務(wù)器路由(Homestead 下重寫):
nginx配置url重寫
// Homestead 對每個域名都分配不同的配置

我們對framework.app的Nginx配置進(jìn)行路由重寫:

cd /etc/nginx/sites-available
vagrant@homestead:/etc/nginx/sites-available$ sudo vim framework.app

重寫:

server {
    listen 80;
    listen 443 ssl http2;
    server_name framework.app;
    root "/home/vagrant/Code/php-framework";
    ## 重寫路由
    rewrite ^(.*) /index.php?action=$1 last;
    index index.html index.htm index.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    access_log off;
    error_log  /var/log/nginx/framework.app-error.log error;

    sendfile off;

    client_max_body_size 100m;

    location ~ .php$ {
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    location ~ /.ht {
        deny all;
    }

    ssl_certificate     /etc/nginx/ssl/framework.app.crt;
    ssl_certificate_key /etc/nginx/ssl/framework.app.key;
}

重啟服務(wù)器:

sudo service nginx restart;

重寫路由地址后,我們可以直接用 http://framework.app/about 來訪問了:

Nginx 服務(wù)器會將訪問的路徑http://framework.app/about 重寫為:http://framework.app/index.php?action=about

如果你的服務(wù)器是Apache,則可以在根目錄下增加.htaccess 文件即可:


RewriteEngine On
#如果文件存在就直接訪問目錄不進(jìn)行RewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
#如果目錄存在就直接訪問目錄不進(jìn)行RewriteRule
RewriteCond %{REQUEST_FILENAME} !-d
#將所有其他URL重寫到 index.php/URL
RewriteRule ^(.*)$ index.php?action=$1 [PT,L]

編寫路由類 Router

Router.php

 [],
        "POST"  => []
    ];
    public function get($uri, $controller)
    {
        $this->routes["GET"][$uri] = $controller;
    }
    // 當(dāng)定義POST路由時候,把對應(yīng)的$uri和$controller以健值對的形式保存在$this->routes["POST"]數(shù)組中
    public function post($uri, $controller)
    {
        $this->routes["POST"][$uri] = $controller;
    }
    /**
     * 賦值路由關(guān)聯(lián)數(shù)組
     * @param $routes
     */
    public function define($routes)
    {
        $this->routes = $routes;
    }
    /**
     * 分配控制器路徑
     * 通過用戶輸入的 uri 返回對應(yīng)的控制器類的路徑
     * @param $uri
     * 這里的 $requestType 是請求方式,GET 或者是 POST
     * 通過請求方式和 $uri 查詢對應(yīng)請求方式的數(shù)組中是否定義了路由
     * 如果定義了,則返回對應(yīng)的值,沒有定義則拋出異常。
     * @return mixed
     * @throws Exception
     */
    public function direct($uri, $requestType)
    {
        if(array_key_exists($uri, $this->routes[$requestType]))
        {
            return $this->routes[$requestType][$uri];
        }
       // 不存在,拋出異常,以后關(guān)于異常的可以自己定義一些,比如404異常,可以使用NotFoundException
        throw new Exception("No route defined for this URI");
    }
    public static function load($file)
    {
        $router = new static;
        // 調(diào)用 $router->define([]);
        require ROOT . DS . $file;
        // 注意這里,靜態(tài)方法中沒有 $this 變量,不能 return $this;
        return $router;
    }
}

routes.php 路由文件

get("", "controllers/index.php");
$router->get("about", "controllers/about.php");
$router->get("contact", "controllers/contact.php");
$router->post("tasks", "controllers/add-task.php");

index.php 入口文件

direct(Request::uri(), Request::method());

我們來看一下入口文件index.php,先加載路由文件routes.php,該文件是不是和我們Laravel的一樣呢,根據(jù)請求類型進(jìn)行控制器分配,先把所有請求的路徑根據(jù)類型劃分到不同的請求類型屬性(GET,POST)中,然后,再根據(jù)請求的路徑來加載對應(yīng)的控制器。

加載過程詳解
http://framework.app/about通過GET請求訪問頁面:

1: Router::load("routes.php"),加載所有路由

routes.php

$router->get("", "controllers/index.php");
$router->get("about", "controllers/about.php");
$router->get("contact", "controllers/contact.php");
$router->post("tasks", "controllers/add-task.php");

路由類Router.php

public static function load($file)
    {
        $router = new static;

        // 調(diào)用 $router->define([]);
        require ROOT . DS . $file;

        // 注意這里,靜態(tài)方法中沒有 $this 變量,不能 return $this;
        return $router;
    }
    
  此方法等價于:
public static function load($file)
    {
        $router = new static;

        // 調(diào)用 $router->define([]);
        // require ROOT . DS . $file;
        
        // 這里調(diào)用get,post方法進(jìn)行$routes屬性賦值
        $router->get("", "controllers/index.php");
        $router->get("about", "controllers/about.php");
        $router->get("contact", "controllers/contact.php");
        $router->post("tasks", "controllers/add-task.php");

        // 注意這里,靜態(tài)方法中沒有 $this 變量,不能 return $this;
        return $router;
    }

加載路由文件routes.php之后Router.php的$routes屬性結(jié)果為:

protected $routes = [
        "GET"   => [
          ""        => "controllers/index.php",
          "about"   => "controllers/about.php",
          "contact" => "controllers/contact.php",
        ],
        "POST"  => ["tasks" => "controllers/add-task.php"]
    ];

然后再根據(jù) direct($uri, $requestType)方法獲取對應(yīng)路徑的控制器路徑,然后 require controllers/about.php.

四、使用composer進(jìn)行類自動加載

我們現(xiàn)在的項(xiàng)目中使用了一堆的require語句, 這樣的方式對項(xiàng)目管理并不是很好,現(xiàn)在有人為 php 開發(fā)了一個叫做 composer 的依賴包管理工具,非常好用,我們將其集成進(jìn)來,composer 官方地址 https://getcomposer.org/ 按照提示進(jìn)行全局安裝即可。
我們先將 bootstrap.php 中的下面4句類引入代碼注銷

// require "core/Router.php";
// require "core/Request.php";
// require "core/database/Connection.php";
// require "core/database/QueryBuilder.php";

然后在根目錄下建立 coomposer.json 的配置文件,輸入以下內(nèi)容:

{
    "autoload": {
        "classmap": [
            "./"
        ]
    }
}

上面的意思是將根目錄下的所有的類文件都加載進(jìn)來, 在命令行執(zhí)行 composer install 后,在根目錄會生成出一個vendor的文件夾,我們以后通過 composer 安裝的任何第三方代碼都會被生成在這里。

下面在bootstrap.php添加require "vendor/autoload.php"; 即可。我們可以在vendor/composer/autoload_classmap.php文件中查看生成的文件對應(yīng)關(guān)系。

 $baseDir . "/core/database/Connection.php",
    "QueryBuilder" => $baseDir . "/core/database/QueryBuilder.php",
    "Request" => $baseDir . "/core/Request.php",
    "Router" => $baseDir . "/core/Router.php",
    "Task" => $baseDir . "/models/Task.php",
);

這里的核心思想是使用了一個 spl_autoload_register() 函數(shù),進(jìn)行類按需加載,懶加載,即創(chuàng)建對象,然后再加載對象所需要的類文件,而不是之前那種將所有的類文件全部引入,具體請看 詳解spl_autoload_register()函數(shù)。

如果新添加了類文件,我們需要運(yùn)行下面命令進(jìn)行類自動重新加載:

composer dump-autoload

注意:以上方法只能將類文件自動加載,其他文件不會進(jìn)行引入的,如 function.php不會被引入,如果需要,則仍需要使用手動 require 引入。

五、實(shí)現(xiàn)依賴注入容器 DI Container

什么是依賴注入容器 DI Container? 一個聽上去非常高大上的東西,先不要去糾結(jié)字面的意思,你可以這么想,把我們的 APP 想象成一個很大的盒子,把我們所寫的一些功能,比如說配置,數(shù)據(jù)庫操作等都扔到這個盒子里,在扔進(jìn)去的時候你要給它們貼一個標(biāo)簽,以后可以通過這個標(biāo)簽把它們?nèi)〕鰜碛?。大體就是這個意思

我們來看bootstrap.php 中的代碼, 其實(shí) $app 這個數(shù)組就可以看成是一個容器,我們把配置文件扔到數(shù)組中,貼上config的標(biāo)簽(也就是?。?,把QueryBuilder也扔進(jìn)去了,貼上標(biāo)簽database。之后我們可以通過$app["config"]這樣拿出我們需要的值。

我們?yōu)楹尾话?app數(shù)組做成一個對象呢! 這樣我們以后可以為其添加很多的屬性和方法,會方便很多,需要對象就必須要有類,我們馬上就可以在core文件夾內(nèi)建立一個 App.php 的文件,當(dāng)中包含App類。

下面看看我們需要哪些方法,先看 $app["config"] = require "config.php"; 這一句是把config.php放進(jìn)到App的容器中,現(xiàn)在常用的說法是 注冊config 到App, 或者是綁定config 到App, 那我們需要的方法可能是這樣的。

$app->bind("config", require "config.php");
// 或者
$app->register("config", require "config.php");
// 或者
App::bind(config", require "config.php");
// 或者
App::register("config", require "config.php");

在我們寫類的時候,可能不知道怎么動手,可以先嘗試著調(diào)用假定存在的方法,再回頭去完善類,之前我們也都是這么做的,這樣相對會容易些,上面的幾種方法個人感覺App::bind(config", require "config.php");更好些,然后要取出config可以使用 App::get("config") 方法,下面去實(shí)現(xiàn)這兩個方法。在core/App.php

class App
{
   protected static $registries = [];
   public static function bind($key, $value)
   {
       static::$registries[$key] = $value;
   }
   public static function get($key)
   {
       if (! array_key_exists($key, static::$registries)) {
           throw new Exception("No {$key} is bound in the container.");
       }
       return static::$registries[$key];
   }
}

bootstrap.php 中目前代碼如下:

require "vendor/autoload.php";
App::bind("config", require "config.php");
App::bind("database", new QueryBuilder(
    Connection::make(App::get("config")["database"])
));

將所有使用到$app["config"]和$app["database"]的地方全部用App::get("config")App::get("database")替換過來,毫無疑問的會提示“找不到APP的錯誤”,原因是在我們的autoload_classmap.php文件中并沒有導(dǎo)入App.php文件,我們需要在命令行執(zhí)行 composer dump-autoload 來重新生成autoload_classmap.php文件。

六、重構(gòu)控制器 1.新建控制器類

現(xiàn)在我們的控制器中的代碼還都是一些面條式的代碼, 并沒有使用面向?qū)ο蟮姆绞饺ラ_發(fā),我們來重構(gòu)下,我們需要編寫控制器類,然后讓路由指向到對應(yīng)的控制器的方法,這樣在我們以后的工作流中就會方便很多。

我們在controllers文件夾下建立 PagesController.php 的文件, 編寫以下的代碼,將之前控制器中的文件中的代碼都以方法的形式寫在這個類中

class PagesController
{
    public function home()
    {
        $tasks = App::get("database")->selectAll("tasks", "Task");
        require "views/index.view.php";
    }
    public function about()
    {
        require "views/about.view.php";
    }
    public function contact()
    {
        require "views/contact.view.php";
    }
}

現(xiàn)在可以將controllers文件夾下的index.php, about.php, contact.php都刪除了,將路由文件中的代碼改成下面這樣:

2.更改路由文件
$router->get("", "PagesController@home");
$router->get("about", "PagesController@about");
$router->get("contact", "PagesController@contact");
3.初次修改 direct() 方法

現(xiàn)在我的意圖是這樣的,以about路由舉例,當(dāng)我們訪問about, 就會調(diào)用PagesController類的about方法, 在about方法中直接運(yùn)行邏輯代碼。所以我們需要修改Router.php中的direct()方法。

目前direct()是根據(jù)相對路徑返回對應(yīng)控制器類的路徑,然后在入口頁面將其引入進(jìn)來執(zhí)行,現(xiàn)在我們只需要通過實(shí)例化控制器類,然后調(diào)用對應(yīng)的方法即可。 那direct()的核心代碼應(yīng)該是類式這樣的:(new PagesController)->about(); 我們暫且把這個功能命名為 callAction() 方法,先將定已經(jīng)有了這個方法, 我們先去 direct()方法中調(diào)用它, 如下:

public function direct($uri, $requestType)
{
    if (array_key_exists($uri, $this->routes[$requestType])) {
        return $this->callAction("這里應(yīng)該有參數(shù)");
    }
    throw new Exception("No route defined for this URI");
}
4.實(shí)現(xiàn)私有方法 callAction()

下面考慮下 Router 類中的 callAction() 方法該怎么實(shí)現(xiàn),剛才說了這個方法的核心是 (new Controller)->action(); 不多考慮,我們給這個方法兩個參數(shù),$controller 和 $action, 代碼如下:

private function callAction($controller, $action)
{
    $controllerObj = new $controller;
    if (! method_exists($controllerObj, $action)) {
        throw new Exception(
            "{$controller} does not respond to the {$action} action."
        );
    }
    return $controllerObj->$action();
}
5. ... 運(yùn)算符和 explode() 函數(shù)用法

上面的 method_exists($obj, $action) 方法是判斷一個對象中是否某個方法,那在 direct() 中調(diào)用callAction()的參數(shù)我們該如何獲取呢? 我們現(xiàn)在的 $this->routes$requestType的值是類式于 PagesController@about 這樣的字符串,我們只需將該值拆分為 ["PagesController", "about"] 這樣的數(shù)組,然后使用 php5.6 之后出現(xiàn)的 ...運(yùn)算符,將其作為參數(shù)傳遞,關(guān)于拆分字符串為數(shù)組,php 也給我們提供了一個這樣的函數(shù),叫做 explode(), 我們先看下這個函數(shù)的用法,
打開終端,輸入 php --interactive 進(jìn)入命令行交互模式

好了,現(xiàn)在就可以修改下direct() 這個方法了,如下:

public function direct($uri, $requestType)
{
    if (array_key_exists($uri, $this->routes[$requestType])) {
        return $this->callAction(
            ...explode("@", $this->routes[$requestType][$uri])
        );
    }
    throw new Exception("No route defined for this URI");
}

關(guān)于...explode("@", $this->routes$requestType) 這里的 ... 操作符, 它會把一維數(shù)組中的第一個元素作為參數(shù)1, 第二個元素作為參數(shù)2,以此類推,這是 php5.6 后新出的語法,可以自己查閱文檔。

6.修改入口頁面的代碼

ok, 現(xiàn)在將入口頁面的這句代碼require Router::load("routes.php")->direct(Request::uri(), Request::method());require 去掉吧。再測試之前不要忘記了在命令行運(yùn)行 composer dump-autoload 來重新加載文件。

七、全局函數(shù) view()

下面更改下 PagesController 的 require "views/about.view.php"; 這句代碼,我們改成 return view("about"); 這樣,可讀性會好很多。同時在 psr標(biāo)準(zhǔn)中 也有這樣的規(guī)定,在聲明一個類的文件中是不能存在 require 代碼的。

我們在core下創(chuàng)建一個functions.php的文件,把所有的全局函數(shù)都放在這里,準(zhǔn)確來說幫助函數(shù)的文件不應(yīng)該放在這里,它并不屬于核心文件,但是為了我們這里寫的幫助函數(shù)基本都是給我們的框架使用的,不設(shè)計業(yè)務(wù)開發(fā),所以暫時還是先放這里。view()函數(shù)很簡單,如下:

function view($name)
{
    $name = trim($name, "/");
    
    return require "views/{$name}.view.php";
}

在PagesController的home 方法當(dāng)中有$tasks對象集合, 我們怎么傳遞它到view()函數(shù)中呢? 我們需要給view()設(shè)置第二個數(shù)組形式的參數(shù),調(diào)用view()的時候,將數(shù)據(jù)以數(shù)組的形式傳遞給view()即可,如下:

return view("index", ["tasks" => $tasks]);

現(xiàn)在在view()函數(shù)中會出現(xiàn)問題了,我們傳入的數(shù)據(jù)是一個數(shù)組,而在index.view.php中使用的是$tasks這樣的變量,怎么轉(zhuǎn)化?使用PHP提供的extract()函數(shù)可以做到這點(diǎn),它可以將數(shù)組中的元素以變量的形式導(dǎo)入到當(dāng)前的符號表,這句話不好懂,我們來演示下就明白了,還是進(jìn)入 php 的命令行交互模式, 如下:

使用了extract()函數(shù)就會自動幫我們定義好與數(shù)組 key 同名的變量,并將 key 對應(yīng)的 value 賦值給了該變量,好了,下面我們把view()方法完善下,如下:

function view($name, $data =[])
{
    extract($data);
    return require "views/{$name}.view.php";
}
八、通過 composer 加載不是類的文件

下面自己把控制器中與view()相關(guān)的代碼都更改過來,然后運(yùn)行composer dump-autoload,它還是會提示找不到view()函數(shù),原因在于我們的composer.json中的配置,我們需要將配置改成下面這樣:

{
    "autoload": {
        "classmap": [
            "./"
        ],
        "files": [
            "core/functions.php"
        ]
    }
}

上面的classmap只會加載類文件,要加載普通的文件需要使用 "files": [],好了,最后別忘記了composer dump-autoload.

九、控制器和路由的一些命名規(guī)范及命名空間

控制器和路由我們可以按照Laravel的風(fēng)格:

// tasks 的列表頁
$router->get("tasks", "TasksController@index");

// TasksController.php
class TasksController
{
    public function index()
    {
        $tasks = App::get("database")->selectAll("tasks", "Task");
        return view("index", compact("tasks"));
    }
    public function store()
    {
        App::get("database")->create("tasks", [
            "description" => $_POST["description"],
            "completed"   => 0
        ]);
        return redirect("/");
    }
}

從 PHP5.3 開始就支持命名空間了,關(guān)于命名空間的介紹看官方文檔: http://php.net/manual/zh/lang... 。其實(shí)也很簡單,你把命名空間想象層文件夾就行


本項(xiàng)目Github地址:php-framework
參考文章:論P(yáng)HP框架是如何誕生的?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/30590.html

相關(guān)文章

  • 把手教你搭A(yù)PM之Skywalking搭建指南(支持Java/C#/Node.js)

    摘要:通過跟蹤請求的處理過程,來對應(yīng)用系統(tǒng)在前后端處理服務(wù)端調(diào)用的性能消耗進(jìn)行跟蹤,關(guān)于的介紹可以看這個鏈接,大規(guī)模分布式系統(tǒng)的跟蹤系統(tǒng)作者刀把五鏈接來源知乎著作權(quán)歸作者所有。 手把手教你搭A(yù)PM之Skywalking 前言 什么是APM?全稱:Application Performance Management 可以參考這里: 現(xiàn)代APM體系,基本都是參考Google的Dapper(大規(guī)模...

    ingood 評論0 收藏0
  • 把手教你5分鐘用 PHP 搭建一個高性能服務(wù)化后端框架

    摘要:前言一直以來,因?yàn)闃?biāo)準(zhǔn)應(yīng)用方式是配合或使用,而被認(rèn)為不適合做服務(wù)化后端。下面我就介紹如何用來搭建一個高性能的服務(wù)化后端框架,并且實(shí)現(xiàn)一個客戶端調(diào)用例子。服務(wù)端我使用的框架叫,地址在這里。 前言 一直以來,PHP 因?yàn)闃?biāo)準(zhǔn)應(yīng)用方式是配合 php-fpm 或 apache mod 使用,而被認(rèn)為不適合做服務(wù)化后端。但是隨著 Workerman 和 Swoole 這些常駐進(jìn)程模塊的出現(xiàn),PH...

    Charles 評論0 收藏0
  • 教你在不使用框架的情況下也能寫出現(xiàn)代PHP 代碼

    摘要:畢竟,我們還將在接下來的開發(fā)之旅中使用其他框架開發(fā)者編寫的輔助包。缺乏行業(yè)標(biāo)準(zhǔn)必然意味著,框架中的這些組件高度耦合。如果你嘗試對這個類進(jìn)行單元測試,會發(fā)現(xiàn)根本不可行。在做單元測試的時候,我們可以很好地模擬數(shù)據(jù)庫連接,并將其傳入使用。 showImg(https://segmentfault.com/img/remote/1460000014180802); 我為你們準(zhǔn)備了一個富有挑戰(zhàn)性...

    trigkit4 評論0 收藏0
  • 把手教你基于WordPress搭建自己的個人博客

    摘要:一步一步教你基于搭建自己的個人博客,作為成熟的框架,美觀,方便,插件多,更新頻繁,非常適合個人博客與網(wǎng)站的搭建,適合新手,無需太多的代碼基礎(chǔ)。原文鏈接手把手教你搭建自己的網(wǎng)站購買購買云服務(wù)器為了搭建個人網(wǎng)站,首先肯定需要一個云服務(wù)器。 一步一步教你基于WordPress搭建自己的個人博客,WordPress作為成熟的CMS框架,美觀,方便,插件多,更新頻繁,非常適合個人博客與網(wǎng)站的搭建...

    vpants 評論0 收藏0
  • 后端API從入門到放棄指北

    摘要:菜鳥教程框架中文手冊入門目標(biāo)使用搭建通過對數(shù)據(jù)增刪查改沒了純粹占行用的拜 后端API入門學(xué)習(xí)指北 了解一下一下概念. RESTful API標(biāo)準(zhǔn)] 所有的API都遵循[RESTful API標(biāo)準(zhǔn)]. 建議大家都簡單了解一下HTTP協(xié)議和RESTful API相關(guān)資料. 阮一峰:理解RESTful架構(gòu) 阮一峰:RESTful API 設(shè)計指南 RESTful API指南 依賴注入 D...

    sf190404 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<