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

direktori cari
閱讀前篇 簡介 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)
watak

數(shù)據(jù)提供者

數(shù)據(jù)提供者

在?Pagination?和?Sorting?部分, 我們已經(jīng)介紹了如何允許終端用戶選擇一個特定的數(shù)據(jù)頁面,根據(jù)一些字段對它們進行展現(xiàn)與排序。 因為分頁和排序數(shù)據(jù)的任務(wù)是很常見的,所以Yii提供了一組封裝好的data provider類。

數(shù)據(jù)提供者是一個實現(xiàn)了 yii\data\DataProviderInterface 接口的類。 它主要用于獲取分頁和數(shù)據(jù)排序。它經(jīng)常用在?data widgets?小物件里,方便終端用戶進行分頁與數(shù)據(jù)排序。

下面的數(shù)據(jù)提供者類都包含在Yii的發(fā)布版本里面:

  • yii\data\ActiveDataProvider:使用 yii\db\Query 或者 yii\db\ActiveQuery 從數(shù)據(jù)庫查詢數(shù)據(jù)并且以數(shù)組項的方式或者?Active Record實例的方式返回。
  • yii\data\SqlDataProvider:執(zhí)行一段SQL語句并且將數(shù)據(jù)庫數(shù)據(jù)作為數(shù)組返回。
  • yii\data\ArrayDataProvider:將一個大的數(shù)組依據(jù)分頁和排序規(guī)格返回一部分數(shù)據(jù)。

所有的這些數(shù)據(jù)提供者遵守以下模式:

// 根據(jù)配置的分頁以及排序?qū)傩詠韯?chuàng)建一個數(shù)據(jù)提供者$provider = new XyzDataProvider([
    'pagination' => [...],
    'sort' => [...],
]);

// 獲取分頁和排序數(shù)據(jù)$models = $provider->getModels();

// 在當前頁獲取數(shù)據(jù)項的數(shù)目$count = $provider->getCount();

// 獲取所有頁面的數(shù)據(jù)項的總數(shù)$totalCount = $provider->getTotalCount();

你可以通過配置 yii\data\BaseDataProvider::pagination 和 yii\data\BaseDataProvider::sort 的屬性來設(shè)定數(shù)據(jù)提供者的分頁和排序行為。屬性分別對應(yīng)于 yii\data\Pagination 和 yii\data\Sort。 你也可以對它們配置false來禁用分頁和排序特性。

Data widgets,諸如 yii\grid\GridView,有一個屬性名叫?dataProvider?,這個屬性能夠提供一個 數(shù)據(jù)提供者的示例并且可以顯示所提供的數(shù)據(jù),例如,

echo yii\grid\GridView::widget([
    'dataProvider' => $dataProvider,
]);

這些數(shù)據(jù)提供者的主要區(qū)別在于數(shù)據(jù)源的指定方式上。在下面的部分,我們將詳細介紹這些數(shù)據(jù)提供者的使用方法。

活動數(shù)據(jù)提供者

為了使用 yii\data\ActiveDataProvider,你應(yīng)該配置其 yii\data\ActiveDataProvider::query 的屬性。 它既可以是一個 yii\db\Query 對象,又可以是一個 yii\db\ActiveQuery 對象。假如是前者,返回的數(shù)據(jù)將是數(shù)組; 如果是后者,返回的數(shù)據(jù)可以是數(shù)組也可以是?Active Record?對象。 例如,

use yii\data\ActiveDataProvider;

$query = Post::find()->where(['status' => 1]);

$provider = new ActiveDataProvider([
    'query' => $query,
    'pagination' => [
        'pageSize' => 10,
    ],
    'sort' => [
        'defaultOrder' => [
            'created_at' => SORT_DESC,
            'title' => SORT_ASC,
        ]
    ],
]);

// 返回一個Post實例的數(shù)組$posts = $provider->getModels();

假如在上面的例子中,$query?用下面的代碼來創(chuàng)建,則數(shù)據(jù)提供者將返回原始數(shù)組。

use yii\db\Query;

$query = (new Query())->from('post')->where(['status' => 1]);

注意:假如查詢已經(jīng)指定了?orderBy?從句,則終端用戶給定的新的排序說明(通過?sort?來配置的)將被添加到已經(jīng)存在的從句中。 任何已經(jīng)存在的?limit?和?offset?從句都將被終端用戶所請求的分頁(通過?pagination?所配置的)所重寫。

默認情況下,yii\data\ActiveDataProvider使用?db?應(yīng)用組件來作為數(shù)據(jù)庫連接。你可以通過配置 yii\data\ActiveDataProvider::db 的屬性來使用不同數(shù)據(jù)庫連接。

SQL數(shù)據(jù)提供者

yii\data\SqlDataProvider 應(yīng)用的時候需要結(jié)合需要獲取數(shù)據(jù)的SQL語句?;?yii\data\SqlDataProvider::sort 和 yii\data\SqlDataProvider::pagination 規(guī)格,數(shù)據(jù)提供者會根據(jù)所請求的數(shù)據(jù)頁面(期望的順序)來調(diào)整?ORDER BY?和?LIMIT?的SQL從句。

為了使用 yii\data\SqlDataProvider,你應(yīng)該指定 yii\data\SqlDataProvider::sql 屬性以及 yii\data\SqlDataProvider::totalCount 屬性,例如,

use yii\data\SqlDataProvider;

$count = Yii::$app->db->createCommand('
    SELECT COUNT(*) FROM post WHERE status=:status
', [':status' => 1])->queryScalar();

$provider = new SqlDataProvider([
    'sql' => 'SELECT * FROM post WHERE status=:status',
    'params' => [':status' => 1],
    'totalCount' => $count,
    'pagination' => [
        'pageSize' => 10,
    ],
    'sort' => [
        'attributes' => [
            'title',
            'view_count',
            'created_at',
        ],
    ],
]);

// 返回包含每一行的數(shù)組$models = $provider->getModels();

說明:yii\data\SqlDataProvider::totalCount 的屬性只有你需要分頁數(shù)據(jù)的時候才會用到。 這是因為通過 yii\data\SqlDataProvider::sql 指定的SQL語句將被數(shù)據(jù)提供者所修改并且只返回當前頁面數(shù)據(jù)。 數(shù)據(jù)提供者為了正確計算可用頁面的數(shù)量仍舊需要知道數(shù)據(jù)項的總數(shù)。

數(shù)組數(shù)據(jù)提供者

yii\data\ArrayDataProvider 非常適用于大的數(shù)組。數(shù)據(jù)提供者允許你返回一個經(jīng)過一個或者多個字段排序的數(shù)組數(shù)據(jù)頁面。 為了使用 yii\data\ArrayDataProvider,你應(yīng)該指定 yii\data\ArrayDataProvider::allModels 屬性 作為一個大的數(shù)組。 這個大數(shù)組的元素既可以是一些關(guān)聯(lián)數(shù)組(例如:DAO查詢出來的結(jié)果)也可以是一些對象(例如:Active Record實例) 例如,

use yii\data\ArrayDataProvider;

$data = [
    ['id' => 1, 'name' => 'name 1', ...],
    ['id' => 2, 'name' => 'name 2', ...],
    ...
    ['id' => 100, 'name' => 'name 100', ...],
];

$provider = new ArrayDataProvider([
    'allModels' => $data,
    'pagination' => [
        'pageSize' => 10,
    ],
    'sort' => [
        'attributes' => ['id', 'name'],
    ],
]);

// 獲取當前請求頁的每一行數(shù)據(jù)$rows = $provider->getModels();

注意:數(shù)組數(shù)據(jù)提供者與?Active Data Provider?和?SQL Data Provider?這兩者進行比較的話, 會發(fā)現(xiàn)數(shù)組數(shù)據(jù)提供者沒有后面那兩個高效,這是因為數(shù)組數(shù)據(jù)提供者需要加載所有的數(shù)據(jù)到內(nèi)存中。

數(shù)據(jù)鍵的使用

當使用通過數(shù)據(jù)提供者返回的數(shù)據(jù)項的時候,你經(jīng)常需要使用一個唯一鍵來標識每一個數(shù)據(jù)項。 舉個例子,假如數(shù)據(jù)項代表的是一些自定義的信息,你可能會使用自定義ID作為鍵去標識每一個自定義數(shù)據(jù)。 數(shù)據(jù)提供者能夠返回一個通過 yii\data\DataProviderInterface::getModels() 返回的鍵與數(shù)據(jù)項相對應(yīng)的列表。 例如,

use yii\data\ActiveDataProvider;

$query = Post::find()->where(['status' => 1]);

$provider = new ActiveDataProvider([
    'query' => Post::find(),
]);

// 返回包含Post對象的數(shù)組$posts = $provider->getModels();

// 返回與$posts相對應(yīng)的主鍵值$ids = $provider->getKeys();

在上面的例子中,因為你提供給 yii\data\ActiveDataProvider 一個 yii\db\ActiveQuery 對象, 它是足夠智能地返回一些主鍵值作為鍵。你也可以明確指出鍵值應(yīng)該怎樣被計算出來,計算的方式是通過使用一個字段名或者一個可調(diào)用的計算鍵值來配置。 例如,

// 使用 "slug" 字段作為鍵值$provider = new ActiveDataProvider([
    'query' => Post::find(),
    'key' => 'slug',
]);

// 使用md5(id)的結(jié)果作為鍵值$provider = new ActiveDataProvider([
    'query' => Post::find(),
    'key' => function ($model) {
        return md5($model->id);
    }
]);

創(chuàng)建自定義數(shù)據(jù)提供者

為了創(chuàng)建自定義的數(shù)據(jù)提供者類,你應(yīng)該實現(xiàn) yii\data\DataProviderInterface 接口。 一個簡單的方式是從 yii\data\BaseDataProvider 去擴展,這種方式允許你關(guān)注數(shù)據(jù)提供者的核心邏輯。 這時,你主要需要實現(xiàn)下面的一些方法:

  • yii\data\BaseDataProvider::prepareModels():準備好在當前頁面可用的數(shù)據(jù)模型,并且作為一個數(shù)組返回它們。

  • yii\data\BaseDataProvider::prepareKeys():接受一個當前可用的數(shù)據(jù)模型的數(shù)組,并且返回一些與它們相關(guān)聯(lián)的鍵。

  • yii\data\BaseDataProvider::prepareTotalCount(): 在數(shù)據(jù)提供者中返回一個標識出數(shù)據(jù)模型總數(shù)的值。

下面是一個數(shù)據(jù)提供者的例子,這個數(shù)據(jù)提供者可以高效地讀取CSV數(shù)據(jù):

<?phpuse?yii\data\BaseDataProvider;

class?CsvDataProvider?extends?BaseDataProvider{
? ? /**
? ? ?*?@var?string?name?of?the?CSV?file?to?read
? ? ?*/

? ? public?$filename;

? ? /**
? ? ?*?@var?string|callable?name?of?the?key?column?or?a?callable?returning?it
? ? ?*/

? ? public?$key;

? ? /**
? ? ?*?@var?SplFileObject
? ? ?*/

? ? protected?$fileObject;?//?SplFileObject?is?very?convenient?for?seeking?to?particular?line?in?a?file


? ? /**
? ? ?*?@inheritdoc
? ? ?*/

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

? ? ? ? //?open?file
? ? ? ? $this->fileObject?=?new?SplFileObject($this->filename);
? ? }

? ? /**
? ? ?*?@inheritdoc
? ? ?*/

? ? protected?function?prepareModels()
? ?
{
? ? ? ? $models?=?[];
? ? ? ? $pagination?=?$this->getPagination();

? ? ? ? if?($pagination?===?false)?{
? ? ? ? ? ? //?in?case?there's?no?pagination,?read?all?lines
? ? ? ? ? ? while?(!$this->fileObject->eof())?{
? ? ? ? ? ? ? ? $models[]?=?$this->fileObject->fgetcsv();
? ? ? ? ? ? ? ? $this->fileObject->next();
? ? ? ? ? ? }
? ? ? ? }?else?{
? ? ? ? ? ? //?in?case?there's?pagination,?read?only?a?single?page
? ? ? ? ? ? $pagination->totalCount?=?$this->getTotalCount();
? ? ? ? ? ? $this->fileObject->seek($pagination->getOffset());
? ? ? ? ? ? $limit?=?$pagination->getLimit();

? ? ? ? ? ? for?($count?=?0;?$count?<?$limit;?++$count)?{
? ? ? ? ? ? ? ? $models[]?=?$this->fileObject->fgetcsv();
? ? ? ? ? ? ? ? $this->fileObject->next();
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? return?$models;
? ? }

? ? /**
? ? ?*?@inheritdoc
? ? ?*/

? ? protected?function?prepareKeys($models)
? ?
{
? ? ? ? if?($this->key?!==?null)?{
? ? ? ? ? ? $keys?=?[];

? ? ? ? ? ? foreach?($models?as?$model)?{
? ? ? ? ? ? ? ? if?(is_string($this->key))?{
? ? ? ? ? ? ? ? ? ? $keys[]?=?$model[$this->key];
? ? ? ? ? ? ? ? }?else?{
? ? ? ? ? ? ? ? ? ? $keys[]?=?call_user_func($this->key,?$model);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? ? ? return?$keys;
? ? ? ? }?else?{
? ? ? ? ? ? return?array_keys($models);
? ? ? ? }
? ? }

? ? /**
? ? ?*?@inheritdoc
? ? ?*/

? ? protected?function?prepareTotalCount()
? ?
{
? ? ? ? $count?=?0;

? ? ? ? while?(!$this->fileObject->eof())?{
? ? ? ? ? ? $this->fileObject->next();
? ? ? ? ? ? ++$count;
? ? ? ? }

? ? ? ? return?$count;
? ? }
}
Artikel sebelumnya: Artikel seterusnya: