亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄 搜尋
閱讀前篇 簡介 Yii 是什么 從 Yii 1.1 升級 入門 安裝 Yii 運行應(yīng)用 第一次問候 使用Forms 數(shù)據(jù)庫應(yīng)用 使用 Gii 生成代碼 進階 應(yīng)用結(jié)構(gòu) 概述 入口腳本 應(yīng)用(Applications) 應(yīng)用組件(Application Components) 控制器(Controllers) 模型(Models) 視圖(views) 模塊(Modules) 過濾器(Filters) 小部件(Widgets) 前端資源(Assets) 擴展(Extensions) 請求處理 運行概述 啟動引導(dǎo)(Bootstrapping) 路由和創(chuàng)建URL 請求(Requests) 響應(yīng)(Responses) Sessions 和 Cookies 錯誤處理(Handling Errors) 日志(Logging) 關(guān)鍵概念 組件(Component) 屬性(Property) 事件(Events) 行為(Behaviors) 配置(Configurations) 別名(Aliases) 類自動加載(Autoloading) 服務(wù)定位器(Service Locator) 依賴注入容器(Dependency Injection Container) 配合數(shù)據(jù)庫工作 數(shù)據(jù)庫訪問 (Data Access Objects) 查詢生成器(Query Builder) 活動記錄(Active Record) 數(shù)據(jù)庫遷移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用戶數(shù)據(jù) 創(chuàng)建表單(Creating Forms) 輸入驗證(Validating Input) 文件上傳(Uploading Files) 收集列表輸入(Collecting Tabular Input) 多模型的復(fù)合表單(Getting Data for Multiple Models) 顯示數(shù)據(jù) 格式化輸出數(shù)據(jù)(Data Formatting) 分頁(Pagination) 排序(Sorting) 數(shù)據(jù)提供器(Data Providers) 數(shù)據(jù)小部件(Data Widgets) 客戶端腳本使用(Working with Client Scripts) 主題(Theming) 安全 認證(Authentication) 授權(quán)(Authorization) 處理密碼(Working with Passwords) 客戶端認證(Auth Clients) 最佳安全實踐(Best Practices) 緩存 概述 數(shù)據(jù)緩存 片段緩存 頁面緩存 HTTP 緩存 RESTfull Web服務(wù) 快速入門(Quick Start) 資源(Resources) 控制器(Controllers) 路由(Routing) 格式化響應(yīng)(Response Formatting) 授權(quán)認證(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 錯誤處理(Error Handling) 開發(fā)工具 調(diào)試工具欄和調(diào)試器 使用Gii生成代碼 生成API文檔 測試 概述(Overview) 配置測試環(huán)境(Testing environment setup) 單元測試(Unit Tests) 功能測試(Function Tests) 驗收測試(Acceptance Tests) 測試夾具(Fixtures) 高級專題 高級應(yīng)用模板 創(chuàng)建自定義應(yīng)用程序結(jié)構(gòu) 控制臺命令 核心驗證器(Core Validators) 國際化 收發(fā)郵件 性能優(yōu)化 共享主機環(huán)境 模板引擎 集成第三方代碼 小部件 Bootstrap 小部件 Jquery UI 助手類 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
文字

數(shù)據(jù)庫遷移

數(shù)據(jù)庫遷移

在開發(fā)和維護一個數(shù)據(jù)庫驅(qū)動的應(yīng)用程序時,數(shù)據(jù)庫的結(jié)構(gòu)會隨代碼的改變而改變。例如,在開發(fā)應(yīng)用程序的過程中,會增加一張新表且必須得加進來; 在應(yīng)用程序被部署到生產(chǎn)環(huán)境后,需要建立一個索引來提高查詢的性能等等。 因為一個數(shù)據(jù)庫結(jié)構(gòu)發(fā)生改變的時候源代碼也經(jīng)常會需要做出改變,Yii 提供了一個?數(shù)據(jù)庫遷移?功能,該功能可以記錄數(shù)據(jù)庫的變化, 以便使數(shù)據(jù)庫和源代碼一起受版本控制。

如下的步驟向我們展示了數(shù)據(jù)庫遷移工具是如何為開發(fā)團隊所使用的:

  1. Tim 創(chuàng)建了一個新的遷移對象(例如,創(chuàng)建一張新的表單,改變字段的定義等)。
  2. Tim 將這個新的遷移對象提交到代碼管理系統(tǒng)(例如,Git,Mercurial)。
  3. Doug 從代碼管理系統(tǒng)當中更新版本并獲取到這個新的遷移對象。
  4. Doug 把這個遷移對象提交到本地的開發(fā)數(shù)據(jù)庫當中,這樣一來,Doug 同步了 Tim 所做的修改。

如下的步驟向我們展示了如何發(fā)布一個附帶數(shù)據(jù)庫遷移的新版本到生產(chǎn)環(huán)境當中:

  1. Scott 為一個包含數(shù)據(jù)庫遷移的項目版本創(chuàng)建了一個發(fā)布標簽。
  2. Scott 把發(fā)布標簽的源代碼更新到生產(chǎn)環(huán)境的服務(wù)器上。
  3. Scott 把所有的增量數(shù)據(jù)庫遷移提交到生產(chǎn)環(huán)境數(shù)據(jù)庫當中。

Yii 提供了一整套的遷移命令行工具,通過這些工具你可以:

  • 創(chuàng)建新的遷移;
  • 提交遷移;
  • 恢復(fù)遷移;
  • 重新提交遷移;
  • 現(xiàn)實遷移歷史和狀態(tài)。

所有的這些工具都可以通過?yii migrate?命令來進行操作。 在這一章節(jié),我們將詳細的介紹如何使用這些工具來完成各種各樣的任務(wù)。你也可以通過?yii help migrate?命令來獲取每一種工具的具體使用方法。

注意:遷移不僅僅只作用于數(shù)據(jù)庫表,它同樣會調(diào)整現(xiàn)有的數(shù)據(jù)來適應(yīng)新的表單、創(chuàng)建 RBAC 分層、又或者是清除緩存。

創(chuàng)建遷移

使用如下命令來創(chuàng)建一個新的遷移:

yii migrate/create <name>

必填參數(shù)?name?的作用是對新的遷移做一個簡要的描述。例如,如果這個遷移是用來創(chuàng)建一個叫做?news?的表單的,那么你可以使用create_news_table?這個名稱并運行如下命令:

yii migrate/create create_news_table

注意:因為?name?參數(shù)會被用來生成遷移的類名的一部分,所以該參數(shù)應(yīng)當只包含字母、數(shù)字和下劃線。

如上命令將會在?@app/migrations?目錄下創(chuàng)建一個新的名為?m150101_185401_create_news_table.php?的 PHP 類文件。該文件包含如下的代碼,它們用來聲明一個遷移類?m150101_185401_create_news_table,并附有代碼框架:

<?php

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration{
    public function up()
    {
    }

    public function down()
    {
        echo "m101129_185401_create_news_table cannot be reverted.\n";
        return false;
    }
}

每個數(shù)據(jù)庫遷移都會被定義為一個繼承自 yii\db\Migration 的 PHP 類。類的名稱按照?m<YYMMDD_HHMMSS>_<Name>?的格式自動生成,其中

  • <YYMMDD_HHMMSS>?指執(zhí)行創(chuàng)建遷移命令的 UTC 時間。
  • <Name>?和你執(zhí)行命令時所帶的?name?參數(shù)值相同。

在遷移類當中,你應(yīng)當在?up()?方法中編寫改變數(shù)據(jù)庫結(jié)構(gòu)的代碼。你可能還需要在?down()?方法中編寫代碼來恢復(fù)由?up()?方法所做的改變。 當你通過 migration 升級數(shù)據(jù)庫時,?up()?方法將會被調(diào)用,反之,?down()?將會被調(diào)用。如下代碼展示了如何通過遷移類來創(chuàng)建一張?news?表:

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends \yii\db\Migration{
    public function up()
    {
        $this->createTable('news', [
            'id' => Schema::TYPE_PK,
            'title' => Schema::TYPE_STRING . ' NOT NULL',
            'content' => Schema::TYPE_TEXT,
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }

}

注意:并不是所有遷移都是可恢復(fù)的。例如,如果?up()?方法刪除了表中的一行數(shù)據(jù),這將無法通過?down()?方法來恢復(fù)這條數(shù)據(jù)。有時候,你也許只是懶得去執(zhí)行?down()?方法了,因為它在恢復(fù)數(shù)據(jù)庫遷移方面并不是那么的通用。在這種情況下,你應(yīng)當在down()?方法中返回?false?來表明這個 migration 是無法恢復(fù)的。

migration 的基類 yii\db\Migration 通過 yii\db\Migration::db 屬性來連接了數(shù)據(jù)庫。你可以通過?配合數(shù)據(jù)庫工作?章節(jié)中所描述的那些方法來操作數(shù)據(jù)庫表。

當你通過 migration 創(chuàng)建一張表或者字段的時候,你應(yīng)該使用?抽象類型?而不是?實體類型,這樣一來你的遷移對象就可以從特定的 DBMS 當中抽離出來。 yii\db\Schema 類定義了一整套可用的抽象類型常量。這些常量的格式為?TYPE_<Name>。例如,TYPE_PK?指代自增主鍵類型;TYPE_STRING?指代字符串類型。 當遷移對象被提交到某個特定的數(shù)據(jù)庫的時候,這些抽象類型將會被轉(zhuǎn)換成相對應(yīng)的實體類型。以 MySQL 為例,TYPE_PK?將會變成?int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, 而?TYPE_STRING?則變成?varchar(255)。

在使用抽象類型的時候,你可以添加額外的約束條件。在上面的例子當中,?NOT NULL?被添加到?Schema::TYPE_STRING?當中來指定該字段不能為空。

提示:抽象類型和實體類型之間的映射關(guān)系是由每個具體的?QueryBuilder?類當中的 yii\db\QueryBuilder::$typeMap 屬性所指定的。

從 2.0.5 的版本開始,schema 構(gòu)造器提供了更加方便的方法來定義字段,因此上面的 migration 可以被改寫成:

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends \yii\db\Migration{
    public function up()
    {
        $this->createTable('news', [
            'id' => Schema::primaryKey(),
            'title' => Schema::string()->notNull(),
            'content' => Schema::text(),
        ]);
    }

    public function down()
    {
        $this->dropTable('news');
    }

}

事務(wù)遷移

當需要實現(xiàn)復(fù)雜的數(shù)據(jù)庫遷移的時候,確定每一個遷移的執(zhí)行是否成功或失敗就變得相當重要了,因為這將影響到數(shù)據(jù)庫的完整性和一致性。為了達到這個目標,我們建議你把每個遷移里面的數(shù)據(jù)庫操作都封裝到一個?transaction?里面。

實現(xiàn)事務(wù)遷移的一個更為簡便的方法是把遷移的代碼都放到?safeUp()?和?safeDown()?方法里面。它們與?up()?和?down()?的不同點就在于它們是被隱式的封裝到事務(wù)當中的。如此一來,只要這些方法里面的任何一個操作失敗了,那么所有之前的操作都會被自動的回滾。

在如下的例子當中,除了創(chuàng)建?news?表以外,我們還插入了一行初始化數(shù)據(jù)到表里面。

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration{
    public function safeUp()
    {
        $this->createTable('news', [
            'id' => Schema::primaryKey(),,
            'title' => Schema::string()->notNull(),
            'content' => Schema::text(),
        ]);
        
        $this->insert('news', [
            'title' => 'test 1',
            'content' => 'content 1',
        ]);
    }

    public function safeDown()
    {
        $this->delete('news', ['id' => 1]);
        $this->dropTable('news');
    }
}

需要注意的是,當你在?safeUp()?當中執(zhí)行多個數(shù)據(jù)庫操作的時候,你應(yīng)該在?safeDown()?方法當中反轉(zhuǎn)它們的執(zhí)行順序。在上面的例子當中,我們在?safeUp()?方法當中首先創(chuàng)建了一張表,然后插入了一條數(shù)據(jù);而在?safeDown()?方法當中,我們首先刪除那一行數(shù)據(jù),然后才刪除那張表。

注意:并不是所有的數(shù)據(jù)庫都支持事務(wù)。有些數(shù)據(jù)庫查詢也是不能被放倒事務(wù)里面的。在?implicit commit?章節(jié)當中有相關(guān)的例子可以參考。如果遇到這種情況的話,那么你應(yīng)該使用?up()?和?down()?方法進行替代。

訪問數(shù)據(jù)庫的方法

遷移的基類 yii\db\Migration 提供了一整套訪問和操作數(shù)據(jù)庫的方法。你可能會發(fā)現(xiàn)這些方法的命名和 yii\db\Command 類提供的?DAO 方法?很類似。 例如,yii\db\Migration::createTable() 方法可以創(chuàng)建一張新的表,這和 yii\db\Command::createTable() 的功能是一模一樣的。

使用 yii\db\Migration 所提供的方法的好處在于你不需要再顯式的創(chuàng)建 yii\db\Command 實例,而且在執(zhí)行每個方法的時候都會顯示一些有用的信息來告訴我們數(shù)據(jù)庫操作是不是都已經(jīng)完成,還有它們完成這些操作花了多長時間等等。

如下是所有這些數(shù)據(jù)庫訪問方法的列表:

  • yii\db\Migration::execute(): 執(zhí)行一條 SQL 語句
  • yii\db\Migration::insert(): 插入單行數(shù)據(jù)
  • yii\db\Migration::batchInsert(): 插入多行數(shù)據(jù)
  • yii\db\Migration::update(): 更新數(shù)據(jù)
  • yii\db\Migration::delete(): 刪除數(shù)據(jù)
  • yii\db\Migration::createTable(): 創(chuàng)建表
  • yii\db\Migration::renameTable(): 重命名表名
  • yii\db\Migration::dropTable(): 刪除一張表
  • yii\db\Migration::truncateTable(): 清空表中的所有數(shù)據(jù)
  • yii\db\Migration::addColumn(): 加一個字段
  • yii\db\Migration::renameColumn(): 重命名字段名稱
  • yii\db\Migration::dropColumn(): 刪除一個字段
  • yii\db\Migration::alterColumn(): 修改字段
  • yii\db\Migration::addPrimaryKey(): 添加一個主鍵
  • yii\db\Migration::dropPrimaryKey(): 刪除一個主鍵
  • yii\db\Migration::addForeignKey(): 添加一個外鍵
  • yii\db\Migration::dropForeignKey(): 刪除一個外鍵
  • yii\db\Migration::createIndex(): 創(chuàng)建一個索引
  • yii\db\Migration::dropIndex(): 刪除一個索引

提示:yii\db\Migration 并沒有提供數(shù)據(jù)庫的查詢方法。這是因為通常你是不需要去數(shù)據(jù)庫把數(shù)據(jù)一行一行查出來再顯示出來的。另外一個原因是你完全可以使用強大的?Query Builder 查詢構(gòu)建器?來構(gòu)建和查詢。

提交遷移

為了將數(shù)據(jù)庫升級到最新的結(jié)構(gòu),你應(yīng)該使用如下命令來提交所有新的遷移:

yii migrate

這條命令會列出迄今為止所有未提交的遷移。如果你確定你需要提交這些遷移,它將會按照類名當中的時間戳的順序,一個接著一個的運行每個新的遷移類里面的?up()?或者是?safeUp()?方法。如果其中任意一個遷移提交失敗了,那么這條命令將會退出并停止剩下的那些還未執(zhí)行的遷移。

對于每一個成功提交的遷移,這條命令都會在一個叫做?migration?的數(shù)據(jù)庫表中插入一條包含應(yīng)用程序成功提交遷移的記錄,該記錄將幫助遷移工具判斷哪些遷移已經(jīng)提交, 哪些還沒有提交。

提示:遷移工具將會自動在數(shù)據(jù)庫當中創(chuàng)建?migration?表,該數(shù)據(jù)庫是在該命令的 yii\console\controllers\MigrateController::db 選項當中指定的。默認情況下,是由?db?application component?指定的。

有時,你可能只需要提交一個或者少數(shù)的幾個遷移,你可以使用該命令指定需要執(zhí)行的條數(shù),而不是執(zhí)行所有的可用遷移。例如,如下命令將會嘗試提交前三個可用的遷移:

yii migrate 3

你也可以指定一個特定的遷移,按照如下格式使用?migrate/to?命令來指定數(shù)據(jù)庫應(yīng)該提交哪一個遷移:

yii migrate/to 150101_185401                      # using timestamp to specify the migration 使用時間戳來指定遷移
yii migrate/to "2015-01-01 18:54:01"              # using a string that can be parsed by strtotime() 使用一個可以被 strtotime() 解析的字符串
yii migrate/to m150101_185401_create_news_table   # using full name 使用全名
yii migrate/to 1392853618                         # using UNIX timestamp 使用 UNIX 時間戳

如果在指定要提交的遷移前面還有未提交的遷移,那么在執(zhí)行這個被指定的遷移之前,這些還未提交的遷移會先被提交。

如果被指定提交的遷移在之前已經(jīng)被提交過,那么在其之后的那些遷移將會被還原。

還原遷移

你可以使用如下命令來還原其中一個或多個意見被提交過的遷移:

yii migrate/down     # revert the most recently applied migration 還原最近一次提交的遷移
yii migrate/down 3   # revert the most 3 recently applied migrations 還原最近三次提交的遷移

注意:并不是所有的遷移都能被還原。嘗試還原這類遷移將可能導(dǎo)致報錯甚至是終止所有的還原進程。

重做遷移

重做遷移的意思是先還原指定的遷移,然后再次提交。如下所示:

yii migrate/redo        # redo the last applied migration 重做最近一次提交的遷移
yii migrate/redo 3      # redo the last 3 applied migrations 重做最近三次提交的遷移

注意:如果一個遷移是不能被還原的,那么你將無法對它進行重做。

列出遷移

你可以使用如下命令列出那些提交了的或者是還未提交的遷移:

yii migrate/history     # 顯示最近10次提交的遷移
yii migrate/history 5   # 顯示最近5次提交的遷移
yii migrate/history all # 顯示所有已經(jīng)提交過的遷移

yii migrate/new         # 顯示前10個還未提交的遷移
yii migrate/new 5       # 顯示前5個還未提交的遷移
yii migrate/new all     # 顯示所有還未提交的遷移

修改遷移歷史

有時候你也許需要簡單的標記一下你的數(shù)據(jù)庫已經(jīng)升級到一個特定的遷移,而不是實際提交或者是還原遷移。這個經(jīng)常會發(fā)生在你手動的改變數(shù)據(jù)庫的一個特定狀態(tài),而又不想相應(yīng)的遷移被重復(fù)提交。那么你可以使用如下命令來達到目的:

yii migrate/mark 150101_185401                      # 使用時間戳來指定遷移
yii migrate/mark "2015-01-01 18:54:01"              # 使用一個可以被 strtotime() 解析的字符串
yii migrate/mark m150101_185401_create_news_table   # 使用全名
yii migrate/mark 1392853618                         # 使用 UNIX 時間戳

該命令將會添加或者刪除?migration?表當中的某幾行數(shù)據(jù)來表明數(shù)據(jù)庫已經(jīng)提交到了指定的某個遷移上。執(zhí)行這條命令期間不會有任何的遷移會被提交或還原。

自定義遷移

有很多方法可以自定義遷移命令。

使用命令行選項

遷移命令附帶了幾個命令行選項,可以用來自定義它的行為:

  • interactive: boolean (默認值為 true),指定是否以交互模式來運行遷移。當被設(shè)置為 true 時,在命令執(zhí)行某些操作前,會提示用戶。如果你希望在后臺執(zhí)行該命令,那么你應(yīng)該把它設(shè)置成 false。

  • migrationPath: string (默認值為?@app/migrations),指定存放所有遷移類文件的目錄。該選項可以是一個目錄的路徑,也可以是路徑別名。需要注意的是指定的目錄必選存在,否則將會觸發(fā)一個錯誤。

  • migrationTable: string (默認值為?migration),指定用于存儲遷移歷史信息的數(shù)據(jù)庫表名稱。如果這張表不存在,那么遷移命令將自動創(chuàng)建這張表。當然你也可以使用這樣的字段結(jié)構(gòu):?version varchar(255) primary key, apply_time integer?來手動創(chuàng)建這張表。

  • db: string (默認值為?db),指定數(shù)據(jù)庫?application component?的 ID。它指的是將會被該命令遷移的數(shù)據(jù)庫。

  • templateFile: string (defaults to?@yii/views/migration.php),指定生產(chǎn)遷移框架代碼類文件的模版文件路徑。該選項即可以使用文件路徑來指定,也可以使用路徑?別名?來指定。該模版文件是一個可以使用預(yù)定義變量?$className?來獲取遷移類名稱的 PHP 腳本。

如下例子向我們展示了如何使用這些選項:

例如,如果我們需要遷移一個?forum?模塊,而該遷移文件放在該模塊下的?migrations?目錄當中,那么我們可以使用如下命令:

# 在 forum 模塊中以非交互模式進行遷移yii migrate --migrationPath=@app/modules/forum/migrations --interactive=0

全局配置命令

在運行遷移命令的時候每次都要重復(fù)的輸入一些同樣的參數(shù)會很煩人,這時候,你可以選擇在應(yīng)用程序配置當中進行全局配置,一勞永逸:

return [
    'controllerMap' => [
        'migrate' => [
            'class' => 'yii\console\controllers\MigrateController',
            'migrationTable' => 'backend_migration',
        ],
    ],
];

如上所示配置,在每次運行遷移命令的時候,backend_migration?表將會被用來記錄遷移歷史。你再也不需要通過?migrationTable?命令行參數(shù)來指定這張歷史紀錄表了。

遷移多個數(shù)據(jù)庫

默認情況下,遷移將會提交到由?db?application component?所定義的同一個數(shù)據(jù)庫當中。如果你需要提交到不同的數(shù)據(jù)庫,你可以像下面那樣指定?db?命令行選項,

yii migrate --db=db2

上面的命令將會把遷移提交到?db2?數(shù)據(jù)庫當中。

偶爾有限時候你需要提交?一些?遷移到一個數(shù)據(jù)庫,而另外一些則提交到另一個數(shù)據(jù)庫。為了達到這個目的,你應(yīng)該在實現(xiàn)一個遷移類的時候指定需要用到的數(shù)據(jù)庫組件的 ID , 如下所示:

use yii\db\Schema;
use yii\db\Migration;

class m150101_185401_create_news_table extends Migration{
    public function init()
    {
        $this->db = 'db2';
        parent::init();
    }
}

即使你使用?db?命令行選項指定了另外一個不同的數(shù)據(jù)庫,上面的遷移還是會被提交到?db2?當中。需要注意的是這個時候遷移的歷史信息依然會被記錄到?db?命令行選項所指定的數(shù)據(jù)庫當中。

如果有多個遷移都使用到了同一個數(shù)據(jù)庫,那么建議你創(chuàng)建一個遷移的基類,里面包含上述的?init()?代碼。然后每個遷移類都繼承這個基類就可以了。

提示:除了在 yii\db\Migration::db 參數(shù)當中進行設(shè)置以外,你還可以通過在遷移類中創(chuàng)建新的數(shù)據(jù)庫連接來操作不同的數(shù)據(jù)庫。然后通過這些連接再使用?DAO 方法?來操作不同的數(shù)據(jù)庫。

另外一個可以讓你遷移多個數(shù)據(jù)庫的策略是把遷移存放到不同的目錄下,然后你可以通過如下命令分別對不同的數(shù)據(jù)庫進行遷移:

yii migrate --migrationPath=@app/migrations/db1 --db=db1yii migrate --migrationPath=@app/migrations/db2 --db=db2...
第一條命令將會把?@app/migrations/db1?目錄下的遷移提交到?db1?數(shù)據(jù)庫當中,第二條命令則會把?@app/migrations/db2?下的遷移提交到?db2?數(shù)據(jù)庫當中,以此類推。
上一篇: 下一篇: