上面的幾章都講概念了,沒有怎麼講到實踐的東西,可能會有些枯燥,這很正常的,概念仍是須要慢慢啃的,尤爲是官網其餘的部分,須要狠狠的啃。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裏面配置一個可供遠程訪問的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