Yii 2.x MVC初體驗

一、我們先介紹控制器 C(controller)

在這裏插入圖片描述
上圖中我們可以看到 yii 2.x高級版的 控制器所在目錄

  1. 在 frontend\controllers\ 目錄下新建 TestController.php 文件
<?php
namespace frontend\controllers;

use yii\web\Controller;

class TestController extends Controller
{
    public function actionIndex () {}

    public function actionCreate () {}
}
  1. 輸出Hello world
<?php
namespace frontend\controllers;

use yii\web\Controller;

class TestController extends Controller
{
    public function actionIndex () {
        echo "Hello World!";
    }
    public function actionCreate () {}
}
  1. 如何動態的輸出 Hello Ketty,Hello Anmy?
public function actionIndex ($name) 
{ 
    echo "Hello {$name}!"; 
}

此時瀏覽器訪問鏈接:http://advanced.dev/index.php?r=test/index&name=Kitty這裏的域名根據自己配置的爲準

二、視圖 V(view)的認識

  1. frontend\views下面創建與控制器名一致的目錄來保存視圖文件,比如控制器名爲:TestController, 那麼視圖文件的目錄名爲:test,如此一來才方便我們對很多文件進行管理
如果視圖文件爲AAController,那麼文件夾的名字應爲a-a
  1. 創建index.php視圖文件
<div class="test-index">
    <h1>Hello World!</h1>
</div>
  1. 引用視圖
public function actionIndex ($name) {
//        echo "Hello {$name}!";
        return $this->render('index');
    }
我們調用的是controller的render方法,該方法用於渲染布局。
所謂的渲染布局指的是加載公共的頭尾以及我們指定的視圖文件 index.php 

如下圖可以看到紅色框中的公共頭部和尾部
在這裏插入圖片描述

  1. 在視圖中動態的輸出 Hello xx, 即將 C 中的參數傳入 V 中
// 控制器中的修改
public function actionIndex ($name)
{
    // echo "Hello {$name}!";
    return $this->render('index', [
        'name' => $name,
    ]);
}

// 頁面的修改
<div class="test-index">
    <h1>Hello <?= $name ?>!</h1>
</div>

訪問 http://advanced.dev/index.php?r=test/index&name=Kitty
查看頁面
在這裏插入圖片描述
5. 簡單的談了一下如何避免XSS跨站攻擊
在這裏插入圖片描述
上圖中可以看到並沒有輸出 Hello
視圖修改:

<div class="test-index">
    <h1>Hello <?= yii\helpers\Html::encode($name) ?>!</h1>
</div>

查看視圖輸出
在這裏插入圖片描述

三、模型 Model 的創建以及認識

·1. 創建遷移文件

// 使用 yii migrate 命令生成 member 對應的數據表遷移:
D:\www\Yii2\advanced>yii migrate/create create_member_table
Yii Migration Tool (based on Yii v2.0.30)

Create new migration 'D:\www\Yii2\advanced\console/migrations\m191205_070353_create_member_table.php'? (yes|no) [no]:yes
New migration created successfully.

D:\www\Yii2\advanced>

生成的遷移文件位於 advanced\console\migrations 目錄
在這裏插入圖片描述
2. 編輯遷移文件: 添加更多的列到數據表中

<?php

use yii\db\Migration;

/**
 * Handles the creation of table `{{%member}}`.
 */
class m191205_070353_create_member_table extends Migration
{
    /**
     * {@inheritdoc}
     */
    public function safeUp()
    {
        $this->createTable('{{%member}}', [
            'id' => $this->primaryKey(),
            'name'=> $this->string(20)->notNull()->defaultValue(""),
            'mobile'=> $this->string(11)->notNull()->defaultValue(""),
            'gender'=> $this->tinyInteger(1)->notNull()->defaultValue(0),
            'create_time'=> $this->dateTime(),
            'update_time'=> $this->dateTime(),
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function safeDown()
    {
        $this->dropTable('{{%member}}');
    }
}
  1. 運行遷移文件
yii migrate

遷移文件運行過程以及結果圖
4. 查看數據庫
在這裏插入圖片描述

  1. 使用gii生成AR模型和CRUD

     dev模式下gii是默認開啓的
    

請根據自己配置的網站路由訪問
在這裏插入圖片描述
在這裏插入圖片描述
6. 查看model
在這裏插入圖片描述
注意在創建model時的命名空間的選擇,這裏選擇common/models是爲了之後backend以及frontend項目可以共同使用

四、使用gii創建CURD

在這裏插入圖片描述

  1. 點擊 Grenerate
  2. 訪問 http://advanced.dev/index.php?r=member
    在這裏插入圖片描述
  3. 點擊 Create Member 按鈕
    在這裏插入圖片描述
  4. 輸入信息,點擊save
    在這裏插入圖片描述
  5. 查看
    在這裏插入圖片描述
  6. 對比數據表
    在這裏插入圖片描述

五、創建項目專屬的 Models

拷貝common\models\Member.php到frontend\models\MemberForm.php後,打開MemberForm.php文件稍作修改:

1. 命名空間修改爲 namespace frontend\models; 因爲文件目錄變了,自然需要修改
2. 增加需要繼承的父類 use common\models\Member;
3. 類名修改爲MemberForm
4. 繼承類修改爲Member

打開frontend\controllers\MemberController.php文件,對其進行如下修改:

1. 添加 use frontend\models\MemberForm;
2. 修改actionCreate方法$model實例化的類爲MemberForm, 即 $model = new MemberForm();

點擊Create Member ,看到的輸入框說明全是英文,修改MemberForm

 public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => '姓名',
            'mobile' => '手機號',
            'gender' => '性別',
            'create_time' => '創建時間',
            'update_time' => '修改時間',
        ];
    }

在修改MemberForm

 public function rules()
    {
        return [
            [['gender'], 'integer'],
            [['create_time', 'update_time'], 'safe'],
            [['name'], 'string', 'max' => 20],
            [['mobile'], 'string', 'max' => 11],
            ['name', 'required', 'message' => '請填寫姓名'],
            ['mobile', 'required', 'message' => '請輸入手機號'],
        ];
    }

修改MemberController.php文件中引入的 Member 以及 MemberSearch,並將對應的創建 Member 實例改爲 MemberForm 實例
效果
在這裏插入圖片描述
在這裏插入圖片描述

六、創建全局可用的自定義方法

全局性的公共類文件位於common/components/Helper.php(components文件夾是我們自己創建的,用於以後單獨存放我們自己的組件類),其內容如下:

namespace common\components;
class Helper
{
    public static function funName($data)
    {
        return $data;
    }
}

如果是在平常,我們可能會這樣使用

use common\components\Helper;
Helper::checkMobile('186xxx');

但是,爲了說明組件化的配置使用,我們需要在配置文件中增加一項對components的配置。你可以在你的 common\config\main.php 文件中添加如下配置

'components' => [
    // other code...
    'helper' => [
        'class' => 'common\components\Helper',
        'property' => '123',
    ],
],

你可以像下面這樣使用

var_dump(Yii::$app->helper->funName('sdfasdf'));

注:在advanced版本中,對一個項目而言,默認有4個配置文件。以frontend引用爲例

frontend\config\main-local.php
frontend\config\main.php
common\config\main-local.php
common\config\main.php

如果我在多個配置文件中都配置了某一項怎麼辦?

從應用的入口文件 frontend\web\index.php 我們瞭解到,最終生效的配置是經過 yii\helpers\ArrayHelper::merge 方法處理的。

$config = yii\helpers\ArrayHelper::merge(
    require __DIR__ . '/../../common/config/main.php',
    require __DIR__ . '/../../common/config/main-local.php',
    require __DIR__ . '/../config/main.php',
    require __DIR__ . '/../config/main-local.php'
);

也就是說這四個文件,優先級分別是 frontend\config\main-local.php > frontend\config\main.php > common\config\main-local.php > common\config\main.php

也就是說如果我們在common\config\main.php 和frontend\config\main.php 文件內都配置了某一項,很顯然frontend\config\main.php 的配置會覆蓋掉 common\config\main.php 的配置。

爲什麼要這麼設計呢?main-local又是什麼鬼?

第一個問題很好理解,很顯然 common下的配置可以多個應用共有,frontend下面的配置只針對當前應用生效。

如果你有使用git的習慣,你會發現在frontend\config目錄下有一個隱藏的 .gitignore 文件,我們知道,這個文件內我們可以忽略某些文件,不允許提交到遠程git地址。你打開後會發現,main-local.php恰好羅列其中。也就是說這個文件只會在我們本地生效。當我們把項目部署到服務器之後,這個文件並不會被提交到遠程服務器,服務器會有他自己的main-local。也就是說不管是在你的測試服務器還是生產服務器,都有自己單獨的main-local.php文件,只針對當前環境的配置。

我們舉一個例子:你可能在生產環境配置的緩存方式是redis緩存,但是爲了節省資源,你本地可能就需要配置爲文件緩存了。爲了達到這一目的,我們可以分別在本地的main-local.php和生產服務器的main-local.php中配置cache組件。

從上面的栗子中不難看出,其配置項的格式大多數情況下只需要指定一個class即可。當然,我們還可以爲配置項(比如說我們配置的全局類)配置屬性、行爲和事件,鑑於理解,我們這裏只對屬性進行了配置,行爲和事件後面我們會再說。

七、關於全局變量或者環境變量的配置

上面介紹了一些組件的配置,那麼關於一些變量的配置又應該怎麼配置呢?

同樣查看 common/config 目錄,可以看到 params.php以及params-local.php 文件:

// params.php 文件的內容
<?php
return [
    'adminEmail' => '[email protected]',
    'supportEmail' => '[email protected]',
    'senderEmail' => '[email protected]',
    'senderName' => 'Example.com mailer',
    'user.passwordResetTokenExpire' => 3600,
];
// params-local.php 文件的內容
<?php
return [
];

這裏以 frontend 項目爲例

查看項目的config/main.php 文件
在這裏插入圖片描述
我們瞭解到,最終生效的配置是經過 array_merge() 方法處理的。所以出現的問題就如同六一樣了。

在項目中使用定義的變量

var_dump(Yii::$app->params['adminEmail']);

同樣,自定義變量的優先級爲:frontend\config\params-local.php > frontend\config\params.php > common\config\params-local.php > common\config\params.php

八、關於網站語言以及時區的設置

設置在 common/config/main.php 文件中,因爲這個應該是全局統一的

    // 配置語言
    'language'=>'zh-CN',
    // 配置時區
    'timeZone'=>'Asia/Chongqing',

九、路由改寫並且隱藏入口文件

路由改寫

因爲對於所有的項目路由我都想改寫,那麼我將該組件配置在 common/config/main.php 文件中,配置如下:

// 在 components 配置下添加一項配置
'urlManager' => [
    'enablePrettyUrl' => false,// 是否開啓美化效果
    'showScriptName' => true,// 是否或略腳本名index.php
    'enableStrictParsing' => false,// 是否開啓嚴格解析路由
    'suffix' => '',// url後綴
    'rules' => [
    ],// 包含了路由的匹配規則列表
],

隱藏入口文件

同時在項目的入口目錄添加文件 .htaccess,.htaccess文件內容如下:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

之後訪問 member 首頁路由由 http://advanced.dev/index.php?r=member 變爲 http://advanced.dev/member/index。
注意:默認 httpd.conf 的 LoadModule rewrite_module modules/mod_rewrite.so 擴展開啓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章