【Yii系列】最佳實踐以後臺業務框架

緣起

上面的幾章都講概念了,沒有怎麼講到實踐的東西,可能會有些枯燥,這很正常的,概念仍是須要慢慢啃的,尤爲是官網其餘的部分,須要狠狠的啃。php

什麼,你啃不動了?看看官網旁邊的那個在線用戶吧。nginx

你不啃的時候但是有這麼多人在啃知識,若是不想之後被這打擊,趕忙學!!!一如當年大學的我,天天夜裏都抱着一本《算法導論》在啃同樣,自律至關重要。git

這一章我就帶大夥瞭解一下前兩章的概念有啥用,應用到實際,這是臨門一腳,可是,我老是以爲概念的重要性至少要佔70%,臨門的一腳實踐只佔30%,望君能體會~github

環境

操做系統:OS X EI Capitanweb

PHP版本:PHP 5.6.30redis

Yii版本:Yii 2.0算法

編輯器:PHPStorm數據庫

總體框架

首先,咱們作這個框架的目的不是給咱們本身看的,而是給廣大之後會在這套框架中學習工做的人看的,因此,千萬不能融入本身的思想,要儘量的通俗易懂,符合通常的邏輯設計。bootstrap

這張圖是Yii提供給咱們的源代碼,首先,爲了可以更能適合咱們的業務框架,我決定來簡單的修改一下這個文件結構。api

首先,增長業務模塊文件夾modules。用以區分每一個不一樣的業務線。

增長全局基礎類文件夾commons。用以定義application須要使用到的基礎類。

在剛剛建立的Commons文件夾下面建立環境配置文件Config.php和全局方法文件Common.php

Config.php文件用以配置環境和獲取相應環境的配置常量。

Common方法用以定義全局使用到的一些function。【注意,這邊的Common只是用於保存全局的方法,不用作namespace】

 

Common裏面比較重要的一個方法就是獲取配置常量方法,後面在不少配置文件中會用到這個方法。

/**
 * 獲取配置文件
 * @param $key string min;
 * @param string $env $string dev:開發環境
 * @return mixed
 */
function Config($key, $val = null)
{
    return \app\commons\Config::get($key, $val);
}

這邊的Config就是咱們剛纔建立的Config.php文件,具體代碼以下:

<?php
namespace app\commons;

/**
 * 主要實現不一樣文件配置查找擴展 file.param.param1
 *
 * 文件.數組變量.變量
 */
class Config
{
    const ENV_SIT = 'sit';

    const ENV_PRE = 'pre';

    const ENV_PRD  = 'prd';

    private static $_config = null;

    /**
     * 初始化配置,永遠加載prd, 默認加載sit
     * @param type $configPath
     * @param type $env
     * @throws \Exception
     */
    public static function init($configPath = null, $env = self::ENV_SIT)
    {
        if (!is_dir($configPath)) {
            die('配置目錄不存在');
        }

        $paths[] = $configPath . DIRECTORY_SEPARATOR . self::ENV_PRD;

        switch ($env) {
            case self::ENV_PRE:
                $paths[] = $devconfig = $configPath . DIRECTORY_SEPARATOR . self::ENV_PRE;
                break;
            case self::ENV_SIT:
                if (is_dir($configPath . DIRECTORY_SEPARATOR . self::ENV_SIT)) {
                    $paths[] = $configPath . DIRECTORY_SEPARATOR . self::ENV_SIT;
                }
                break;

            default:
                break;
        }

        static::$_config = \Noodlehaus\Config::load($paths);
    }

    public static function get($key, $default = null)
    {
        return static::$_config->get($key, $default);
    }

    public static function set($key, $value)
    {
        return static::$_config->set($key, $value);
    }
}

另外,咱們須要在config文件夾中新增幾個文件,用以區分線上環境【prd】,線上測試環境【pre】,本地開發環境【sit】的配置文件,具體的區分是在config這個文件夾中創建三個對應的目錄,咱們來先建立一下。

每一個目錄下面創建一個app.php的文件,用以存放app的相關配置常量。

那麼,咱們如何區分是哪一個環境呢,以及如何對應到相應的環境配置常量中去呢。

這邊,我給大夥帶來了一個很是好用的配置第三方組件。Noodlehaus。

github地址:https://github.com/hassankhan/config

咱們能夠經過composer去下載和自動加載它。

$ composer require hassankhan/config

這裏面有個問題,不知道是我學識不足,仍是由於這個自動配置文件有問題,這個配置文件加載器始終不讓我來按照文件名去區分配置變量,沒辦法,我暴力的修改了它的一行源代碼。

打開Config的源代碼,vendor/hassankhan/config/src/Config.php

修改構造函數裏面的一行代碼

// Try and load file
$this->data = array_replace_recursive($this->data, array($info['filename'] => (array) $parser->parse($path)));

將本來的(array) $parser->parse($path)修改成:array($info['filename'] => (array) $parser->parse($path))便可。

那麼,爲了保證這邊的代碼可以在第一時間被加載,以便於配置好環境常量,方便下面的操做,咱們須要在入口腳本index.php處加上以下代碼:

//咱們每一個環境的域名都會在Nginx虛擬配置裏面設置,和環境有關
if (empty(getenv('ENV'))) {
    $hostInfo = $_SERVER['HTTP_HOST'];
    $environment = 'prd';
    if (strpos($hostInfo, 'sit') !== false) {
        $environment = 'sit';
    }

    if (strpos($hostInfo, 'pre') !== false) {
        $environment = 'pre';
    }
} else {
    $environment = in_array(getenv('ENV'), array('sit', 'pre', 'prd')) ?
        getenv('ENV') : 'sit';
}

\app\commons\Config::init(__DIR__, $environment);

這段代碼的意思是若是沒有設置環境,咱們就根據_SERVER魔術變量中關於HTTP_HOST的值,去判斷咱們處理的應用主體處於哪一個環境,這是一個靈活的配置,但願你們多思考思考這裏面的思想。

可是,這樣一來,咱們的入口腳本就會變得很冗長,這是咱們不肯意看到的,以前也和你們講過,若是以爲在腳本中有過長的代碼該如何,咱們在config文件中新建一個bootstrap.php文件來存放上面的代碼,包括include須要的兩個文件,那麼總體bootstrap.php的代碼就以下所述:

<?php

ini_set('memory_limit', '128M');

//初始化全局函數
include dirname(__DIR__) . '/Commons/Common.php';
//初始化環境配置
include dirname(__DIR__) . '/Commons/Config.php';

... ... // 上面的代碼

$getDebug = empty($_GET['debug']) ? '' : $_GET['debug'];

bootstrap.php擼完了,咱們須要在入口腳本里面作一些小的改變,具體改變以下:

<?php

require(__DIR__ . '/../vendor/autoload.php');
require(__DIR__ . '/../config/bootstrap.php');

// comment out the following two lines when deployed to production
defined('YII_DEBUG') or define('YII_DEBUG', Config('app.debug'));
defined('YII_ENV') or define('YII_ENV', Config('app.env'));

require(__DIR__ . '/../vendor/yiisoft/yii2/Yii.php');

$config = require(__DIR__ . '/../config/web.php');

(new yii\web\Application($config))->run();

上面這邊已經使用了Config,這個方法是Common.php裏面的一個方法,調用的就是Config.php裏面的get方法,上面已經給大夥演示過啦,若是使用編輯器,應該會直接帶出來,很是方便。

好的,到這邊,咱們對整個環境的區分配置就已經完成。如今就能夠在app.php裏面放置一些變量了~

示例爲prd目錄下app.php的配置代碼。

<?php
/**
 * app.php 線上環境項目配置
 */

return [
    'name' => 'fengye-prd',
    'env' => 'prd',
    'debug' => false,
    'log' => [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning'],
            ],
            [
                'class' => 'yii\log\FileTarget',
                'categories' => ['fengye.info.*'],
                'levels' => ['info'],
                'logVars' => [],
            ]
        ],

    ]
];

其實吧,prd,pre,sit這三個目錄下面還須要配置兩個文件,一個是數據庫配置文件,三個環境要予以區分;還有一個是緩存配置文件,redis,memcache的配置須要三個環境的區分。這會在後面講完數據庫和緩存再和大夥聊聊這邊的配置的事。

對於MVC裏的一些在commons裏的基類,咱們會放在模塊中的MVC一節去講解,看完了總體的一個須要改動的結構,咱們再來看看配置文件的改動吧。

配置相關

在Yii系列基礎框架中咱們提到過一些基礎的配置,至於如何實施,在那一章節中咱們沒有細講,今天,在這一節中,咱們來好好看下應用配置有哪些是必要的,哪些是沒必要要的。

上一節講到,哪些配置是須要區分環境的,下面來說的是通用配置,不須要區分環境的配置。

首先,咱們打開配置文件,web.php。

<?php
$params = require(__DIR__ . '/params.php');

以前的章節中提到過,若是配置項中有太多的屬性,須要列舉到一個文件中,使整個代碼結構更清晰。

這邊,咱們有幾個配置項須要寫到文件中。

在這段代碼後新增

$rules = require(__DIR__ . '/rules.php');
$aliases = require(__DIR__ . '/aliases.php');
$modules = require(__DIR__.'/modules.php');

順帶在當前目錄中【config】新增幾個php文件:rules.php,aliases.php,modules.php

配置rules:

在Yii系列請求處理那一章中咱們講到一個路由規則,在具體的配置中,解析規則一節中咱們提到一個rules配置項,使用正則去解析。

'<module:\w+>/<controller:\w+>/<action:\w+>' => '<module>/<controller>/<action>', //模塊相關規則

前面使用戶的URL,後面是解析到對應的路徑,後面是路徑喲,分別是modules、controller、action。

這邊涉及到一個概念,接口版本的區分,比方說以前的老接口不能支持如今的新業務了,建議在接口action名稱後面新增一個版本號,沒有版本號的爲默認版本,並在註釋中使用註明,關於接口文檔的修改,我以爲並無那麼麻煩,使用swagger自動生成在線文檔便可,在修改接口版本的時候,去舊版本註釋裏面將舊街口標識爲過時便可。

關於swagger的相關內容,我會在後面,Yii系列,第三方工具中詳細講解。

這條規則能知足大部分的狀況,若是每一個module下面有不少的子文件夾,就須要來從新定義一些規則啦。具體的看我到時候發佈到github的源碼吧。

aliases.php用於配置路徑別名,這邊咱們先放一放,之後須要用到的時候再講,這邊暫時用不到。

modules.php文件用於配置各個業務模塊,用以區分業務模塊的代碼區域。

<?php
/**
 * 配置業務模塊
 */
return [
    // 用戶模塊
    'user' => [
        'class' => 'app\modules\user\User',
    ],
    // 商品模塊
    'goods' => [
        'class' => 'app\modules\goods\Goods',
    ],
    // 訂單模塊
    'order' => [
        'class' => 'app\modules\order\Order',
    ],
    // 庫存模塊
    'stock' => [
        'class' => 'app\modules\stock\Stock',
    ],
    // 支付模塊
    'pay' => [
        'class' => 'app\modules\pay\Pay',
    ],
    // 消息模塊
    'message' => [
        'class' => 'app\modules\message\Message',
    ],
];

這是全局配置,若是後面有新增模塊,再往這裏面加便可,新增了這幾個文件,咱們須要先完善這些代碼。

首先,rules.php文件裏面的配置項並沒有須要新增的代碼。

modules裏面定義了每一個module的class,這邊須要新增全部模塊的基礎模塊類。

在modules文件夾裏面新增定義好的幾個module,並採用mvc結構初始化models,views,controllers,以及模塊內的配置文件configs。

這邊以Goods爲例,咱們創建商品模塊。

第一步,在modules下面創建goods文件夾。並在goods目錄下面建立對應的文件和mvc文件夾。

Goods.php文件爲上面modules.php配置文件中goods模塊的基類。用以引導goods模塊,具體代碼以下:

<?php

namespace app\modules\goods;

use Yii;

class Goods extends \yii\base\Module
{
    public $controllerNamespace = 'app\modules\goods\controllers';

    public function init()
    {
        parent::init();

        Yii::configure($this, require(__DIR__ . '/config.php'));
    }
}

兩個功能,指定controller namespace,加載配置文件。

config.php文件代碼以下:

<?php
return [
    'components' => [
        // list of component configurations
    ],
    'params' => [
        // list of goods params
    ],
];

用以配置goods模塊須要用到的配置項。

其餘模塊相似goods能夠都建立一套相應的模板。

到此爲止,相應的modules配置大功告成,之後擼代碼就常常在這裏面了。

回到配置文件,咱們繼續往下講。加載了這麼多文件,如何配置進去呢,不急,慢慢來。

首先,咱們配置一下appid

這邊咱們是這麼去配置的

'id' => Config('app.name'),

Config方法來源於Common.php文件定義的全局函數。

設置語言

'language' => 'zh-CN',

配置modules

'modules' => $modules,

配置別名

'aliases' => $aliases,

配置components,記得,這邊已經到components裏面啦。

配置urlManager,將上面的規則引到這邊的配置項中

'urlManager' => [
            'showScriptName' => false,
            'enablePrettyUrl' => true,
            'rules' => $rules
        ],

配置log,按照咱們上節講到的區分環境配置。

'log' => [
            'traceLevel' => Config('app.log.traceLevel'),
            'targets' => Config('app.log.targets'),
        ],

關於cache和db的配置,咱們會到對應的章節中再作詳解。

最後,須要將web/assets文件夾的權限設爲可寫,將runtime文件夾的權限設爲可寫。

至此,全部關於入口腳本的配置文件項和基礎框架均已搭建完畢。

再次訪問你的那個遠程ip地址,出現下面這個頁面表示成功。

建立接口

搭好了上面的框架,下面咱們就先來建立一個接口試驗一下吧。

首先,在User這個module下面的controller裏面新建一個InfoController.php,用以獲取用戶的基本信息。

在InfoController.php裏面,咱們新建一個action,叫actionBaseInfo()。

具體代碼以下:

<?php
namespace app\modules\user\controllers;

use Yii;
use yii\web\Controller;

class InfoController extends Controller
{
    public function actionBaseInfo()
    {
        echo 'hello world!';
    }
}

Nginx虛擬主機配置

到這邊,全部的準備工做都完成啦,如今,咱們須要在Nginx裏面配置一個可供遠程訪問的host。

首先,咱們來到nginx的安裝目錄

#cd /usr/www/nginx/

進入配置文件夾

#cd conf

新建一個文件夾,用以存放vhost虛擬主機配置文件。

#mkdir vhosts

進入vhosts目錄,新增sit.fengye.conf虛擬主機配置文件。

編輯一下內容到該文件裏。

server {
        charset utf-8;
        client_max_body_size 128M;

        listen       80;
        server_name  www.sit.fengye.com;

        index index.php;
        root /usr/www/app/yii-basic/web;
        location / {
                # 若是找不到真實存在的文件,把請求分發至 index.php
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                include fastcgi.conf;
                fastcgi_pass   127.0.0.1:9000;
                fastcgi_param ENV 'sit';
                include fastcgi_params;
                #fastcgi_pass unix:/var/run/php5-fpm.sock;
                try_files $uri =404;
        }

        location ~ /\.(ht|svn|git) {
                deny all;
        }

        access_log  /var/log/nginx/sit.fengye.access.log;
        error_log  /var/log/nginx/sit.fengye.error.log;
}

這些行表明什麼意思,我會在Nginx的後續章節給大夥詳解。

保存退出,須要讓nginx在啓動的時候加載虛擬主機配置,咱們須要在剛纔的conf目錄下面的nginx.conf文件裏面加一行。

include /usr/local/nginx/conf/vhosts/*.conf;

添加到http屬性的最後一行便可。

保存退出,重啓Nginx。

#service nginx restart

編輯你遠程服務器的hosts和本地的hosts,讓www.sit.fengye.com進入到hosts中,以便你順暢的訪問。

遠程服務器編輯/etc/hosts,新增下一行

127.0.0.1   www.sit.fengye.com

本地編輯/etc/hosts【OS X】,新增下一行

服務器IP   www.sit.fengye.com

至此,在瀏覽器中輸入下面的連接,看到hello world,你就成功啦!!!

http://www.sit.fengye.com/user/info/base-info

結束語

好了,到此爲止,證實以前的配置沒有任何問題,路由規則也是可以搞通的,perfect!

關於數據庫和緩存還有後續的框架內容,我仍是會按照以前的方式,先講概念,再講實踐。

關於本章的代碼,以及後續的代碼,楓爺都已發佈到github上,供大夥下載,感興趣的朋友別忘了Fork和Star一下我哈~感謝。

github地址:https://github.com/ifengye/yii-basic

相關文章
相關標籤/搜索