# 數組助手類
除了[PHP中豐富的數組函數集](http://php.net/manual/zh/book.array.php), Yii 數組助手類提供了額外的靜態方法,讓你更高效地處理數組。
## 獲取值
用原生PHP從一個對象、數組、或者包含這兩者的一個復雜數據結構中獲取數據是非常繁瑣的。 你首先得使用`isset`?檢查 key 是否存在, 然后如果存在你就獲取它,如果不存在, 則提供一個默認返回值:
~~~
class User
{
public $name = 'Alex';
}
$array = [
'foo' => [
'bar' => new User(),
]
];
$value = isset($array['foo']['bar']->name) ? $array['foo']['bar']->name : null;
~~~
Yii 提供了一個非常方便的方法來做這件事:
~~~
$value = ArrayHelper::getValue($array, 'foo.bar.name');
~~~
方法的第一個參數是我們從哪里獲取值。第二個參數指定了如何獲取數據, 它可以是下述幾種類型中的一個:
* 數組鍵名或者欲從中取值的對象的屬性名稱;
* 以點號分割的數組鍵名或者對象屬性名稱組成的字符串,上例中使用的參數類型就是該類型;
* 返回一個值的回調函數。
回調函數如下例所示:
~~~
$fullName = ArrayHelper::getValue($user, function ($user, $defaultValue) {
return $user->firstName . ' ' . $user->lastName;
});
~~~
第三個可選的參數如果沒有給定值,則默認為?`null`,如下例所示:
~~~
$username = ArrayHelper::getValue($comment, 'user.username', 'Unknown');
~~~
對于取到值后想要立即從數組中刪除的情況,你可以使用?`remove`?方法:
~~~
$array = ['type' => 'A', 'options' => [1, 2]];
$type = ArrayHelper::remove($array, 'type');
~~~
執行了上述代碼之后,?`$array`?將包含?`['options' => [1, 2]]`?并且?`$type`?將會是?`A`?。 注意和?`getValue`?方法不同的是,`remove`?方法只支持簡單鍵名。
## 檢查鍵名的存在
`ArrayHelper::keyExists`?工作原理和[array_key_exists](http://php.net/manual/en/function.array-key-exists.php)差不多,除了 它還可支持大小寫不敏感的鍵名比較,比如:
~~~
$data1 = [
'userName' => 'Alex',
];
$data2 = [
'username' => 'Carsten',
];
if (!ArrayHelper::keyExists('username', $data1, false) || !ArrayHelper::keyExists('username', $data2, false)) {
echo "Please provide username.";
}
~~~
## 檢索列
通常你要從多行數據或者多個對象構成的數組中獲取某列的值,一個普通的例子是獲取id值列表。
~~~
$data = [
['id' => '123', 'data' => 'abc'],
['id' => '345', 'data' => 'def'],
];
$ids = ArrayHelper::getColumn($array, 'id');
~~~
結果將是?`['123', '345']`。
如果需要額外的轉換或者取值的方法比較復雜, 第二參數可以指定一個匿名函數:
~~~
$result = ArrayHelper::getColumn($array, function ($element) {
return $element['id'];
});
~~~
## 重建數組索引
按一個指定的鍵名重新索引一個數組,可以用?`index`?方法。輸入的數組應該是多維數組或者是一個對象數組。 鍵名(譯者注:第二個參數)可以是子數組的鍵名、對象的屬性名, 也可以是一個返回給定元素數組鍵值的匿名函數。
如果一個鍵值(譯者注:第二個參數對應的值)是 null,相應的數組元素將被丟棄并且不會放入到結果中,例如,
~~~
$array = [
['id' => '123', 'data' => 'abc'],
['id' => '345', 'data' => 'def'],
];
$result = ArrayHelper::index($array, 'id');
// the result is:
// [
// '123' => ['id' => '123', 'data' => 'abc'],
// '345' => ['id' => '345', 'data' => 'def'],
// ]
// using anonymous function
$result = ArrayHelper::index($array, function ($element) {
return $element['id'];
});
~~~
## 建立哈希表
為了從一個多維數組或者一個對象數組中建立一個映射表(鍵值對),你可以使用?`map`方法.`$from`?和?`$to`?參數分別指定了欲構建的映射表的鍵名和屬性名。 根據需要,你可以按照一個分組字段?`$group`?將映射表進行分組,例如。
~~~
$array = [
['id' => '123', 'name' => 'aaa', 'class' => 'x'],
['id' => '124', 'name' => 'bbb', 'class' => 'x'],
['id' => '345', 'name' => 'ccc', 'class' => 'y'],
);
$result = ArrayHelper::map($array, 'id', 'name');
// 結果是:
// [
// '123' => 'aaa',
// '124' => 'bbb',
// '345' => 'ccc',
// ]
$result = ArrayHelper::map($array, 'id', 'name', 'class');
// 結果是:
// [
// 'x' => [
// '123' => 'aaa',
// '124' => 'bbb',
// ],
// 'y' => [
// '345' => 'ccc',
// ],
// ]
~~~
## 多維排序
`multisort`?方法可用來對嵌套數組或者對象數組進行排序,可按一到多個鍵名排序,比如,
~~~
$data = [
['age' => 30, 'name' => 'Alexander'],
['age' => 30, 'name' => 'Brian'],
['age' => 19, 'name' => 'Barney'],
];
ArrayHelper::multisort($data, ['age', 'name'], [SORT_ASC, SORT_DESC]);
~~~
排序之后我們在?`$data`?中得到的值如下所示:
~~~
[
['age' => 19, 'name' => 'Barney'],
['age' => 30, 'name' => 'Brian'],
['age' => 30, 'name' => 'Alexander'],
];
~~~
第二個參數指定排序的鍵名,如果是單鍵名的話可以是字符串,如果是多鍵名則是一個數組, 或者是如下例所示的一個匿名函數:
~~~
ArrayHelper::multisort($data, function($item) {
return isset($item['age']) ? ['age', 'name'] : 'name';
});
~~~
第三個參數表示增降順序。單鍵排序時,它可以是?`SORT_ASC`?或者?`SORT_DESC`?之一。 如果是按多個鍵名排序,你可以用一個數組為各個鍵指定不同的順序。
最后一個參數(譯者注:第四個參數)是PHP的排序標識(sort flag),可使用的值和調用PHP?[sort()](http://php.net/manual/zh/function.sort.php)?函數時傳遞的值一樣。
## 檢測數組類型
想知道一個數組是索引數組還是聯合數組很方便,這有個例子:
~~~
// 不指定鍵名的數組
$indexed = ['Qiang', 'Paul'];
echo ArrayHelper::isIndexed($indexed);
// 所有鍵名都是字符串
$associative = ['framework' => 'Yii', 'version' => '2.0'];
echo ArrayHelper::isAssociative($associative);
~~~
## HTML 編碼和解碼值
為了將字符串數組中的特殊字符做 HTML 編解碼,你可以使用下列方法:
~~~
$encoded = ArrayHelper::htmlEncode($data);
$decoded = ArrayHelper::htmlDecode($data);
~~~
默認情況只會對值做編碼(譯者注:原文中是編碼,應為編解碼)。通過給第二個參數傳?`false`?,你也可以對鍵名做編碼。 編碼將默認使用應用程序的字符集,你可以通過第三個參數指定該字符集。
## 合并數組
~~~
/**
* 將兩個或者多個數組遞歸式的合并為一個數組。
* 如果每個數組有一個元素的鍵名相同,
* 那么后面元素的將覆蓋前面的元素(不同于 array_merge_recursive)。
* 如果兩個數組都有相同鍵名的數組元素(譯者注:嵌套數組)
* 則將引發遞歸合并。
* 對數值型鍵名的元素,后面數組中的這些元素會被追加到前面數組中。
* @param array $a 被合并的數組
* @param array $b 合并的數組,你可以在第三、第四個
* 參數中指定另外的合并數組,等等
* @return 合并的結果數組 (原始數組不會被改變)
*/
public static function merge($a, $b)
~~~
## 對象轉換為數組
你經常要將一個對象或者對象的數組轉換成一個數組,常見的情形是,為了通過REST API提供數據數組(或其他使用方式), 將AR模型(活動記錄模型)轉換成數組。如下代碼可完成這個工作:
~~~
$posts = Post::find()->limit(10)->all();
$data = ArrayHelper::toArray($posts, [
'app\models\Post' => [
'id',
'title',
// the key name in array result => property name
'createTime' => 'created_at',
// the key name in array result => anonymous function
'length' => function ($post) {
return strlen($post->content);
},
],
]);
~~~
第一個參數包含我們想要轉換的數據,在本例中,我們要轉換一個叫?`Post`?的 AR 模型。
第二個參數是每個類的轉換映射表,我們在此設置了一個`Post`?模型的映射。 每個映射數組包含一組的映射,每個映射可以是:
* 一個要包含的照原樣的字段名(和類中屬性的名稱一致);
* 一個由你可隨意取名的鍵名和你想從中取值的模型列名組成的鍵值對;
* 一個由你可隨意取名的鍵名和有返回值的回調函數組成的鍵值對;
這上面的轉換結果將會是:
~~~
[
'id' => 123,
'title' => 'test',
'createTime' => '2013-01-01 12:00AM',
'length' => 301,
]
~~~
也可以在一個特定的類中實現yii\base\Arrayable接口, 從而為其對象提供默認的轉換成數組的方法。
- 介紹(Introduction)
- 關于 Yii(About Yii)
- 從 Yii 1.1 升級(Upgrading from Version 1.1)
- 入門(Getting Started)
- 安裝 Yii(Installing Yii)
- 運行應用(Running Applications)
- 第一次問候(Saying Hello)
- 使用 Forms(Working with Forms)
- 玩轉 Databases(Working with Databases)
- 用 Gii 生成代碼(Generating Code with Gii)
- 更上一層樓(Looking Ahead)
- 應用結構(Application Structure)
- 結構概述(Overview)
- 入口腳本(Entry Scripts)
- 應用(Applications)
- 應用組件(Application Components)
- 控制器(Controllers)
- 模型(Models)
- 視圖(Views)
- 模塊(Modules)
- 過濾器(Filters)
- 小部件(Widgets)
- 前端資源(Assets)
- 擴展(Extensions)
- 請求處理(Handling Requests)
- 運行概述(Overview)
- 引導(Bootstrapping)
- 路由引導與創建 URL(Routing and URL Creation)
- 請求(Requests)
- 響應(Responses)
- Sessions and Cookies
- 錯誤處理(Handling Errors)
- 日志(Logging)
- 關鍵概念(Key Concepts)
- 組件(Components)
- 屬性(Properties)
- 事件(Events)
- 行為(Behaviors)
- 配置(Configurations)
- 別名(Aliases)
- 類自動加載(Class Autoloading)
- 服務定位器(Service Locator)
- 依賴注入容器(Dependency Injection Container)
- 配合數據庫工作(Working with Databases)
- 數據庫訪問(Data Access Objects): 數據庫連接、基本查詢、事務和模式操作
- 查詢生成器(Query Builder): 使用簡單抽象層查詢數據庫
- 活動記錄(Active Record): 活動記錄對象關系映射(ORM),檢索和操作記錄、定義關聯關系
- 數據庫遷移(Migrations): 在團體開發中對你的數據庫使用版本控制
- Sphinx
- Redis
- MongoDB
- ElasticSearch
- 接收用戶數據(Getting Data from Users)
- 創建表單(Creating Forms)
- 輸入驗證(Validating Input)
- 文件上傳(Uploading Files)
- 收集列表輸入(Collecting Tabular Input)
- 多模型同時輸入(Getting Data for Multiple Models)
- 顯示數據(Displaying Data)
- 格式化輸出數據(Data Formatting)
- 分頁(Pagination)
- 排序(Sorting)
- 數據提供器(Data Providers)
- 數據小部件(Data Widgets)
- 操作客戶端腳本(Working with Client Scripts)
- 主題(Theming)
- 安全(Security)
- 認證(Authentication)
- 授權(Authorization)
- 處理密碼(Working with Passwords)
- 客戶端認證(Auth Clients)
- 安全領域的最佳實踐(Best Practices)
- 緩存(Caching)
- 概述(Overview)
- 數據緩存(Data Caching)
- 片段緩存(Fragment Caching)
- 分頁緩存(Page Caching)
- HTTP 緩存(HTTP Caching)
- RESTful Web 服務
- 快速入門(Quick Start)
- 資源(Resources)
- 控制器(Controllers)
- 路由(Routing)
- 格式化響應(Response Formatting)
- 授權驗證(Authentication)
- 速率限制(Rate Limiting)
- 版本化(Versioning)
- 錯誤處理(Error Handling)
- 開發工具(Development Tools)
- 調試工具欄和調試器(Debug Toolbar and Debugger)
- 使用 Gii 生成代碼(Generating Code using Gii)
- TBD 生成 API 文檔(Generating API Documentation)
- 測試(Testing)
- 概述(Overview)
- 搭建測試環境(Testing environment setup)
- 單元測試(Unit Tests)
- 功能測試(Functional Tests)
- 驗收測試(Acceptance Tests)
- 測試夾具(Fixtures)
- 高級專題(Special Topics)
- 高級應用模版(Advanced Project Template)
- 從頭構建自定義模版(Building Application from Scratch)
- 控制臺命令(Console Commands)
- 核心驗證器(Core Validators)
- 國際化(Internationalization)
- 收發郵件(Mailing)
- 性能優化(Performance Tuning)
- 共享主機環境(Shared Hosting Environment)
- 模板引擎(Template Engines)
- 集成第三方代碼(Working with Third-Party Code)
- 小部件(Widgets)
- Bootstrap 小部件(Bootstrap Widgets)
- jQuery UI 小部件(jQuery UI Widgets)
- 助手類(Helpers)
- 助手一覽(Overview)
- Array 助手(ArrayHelper)
- Html 助手(Html)
- Url 助手(Url)