搜尋
首頁後端開發php教程如何巧用 PHP 數組函數

0x00 前言

PHP 的陣列是一種很強大的資料類型,同時PHP 內建了一系列與陣列相關的函數可以輕易的實現日常開發的功能。但我發現好像很多小夥伴都忽略了內建函數的作用(例如我自己就編寫過一些有關數組操作的程式碼然後發現PHP自帶了~~,善用PHP 內建函數能極大的提高開發效率和運行效率(內建函數都是用C 寫的效率比用PHP 寫的高很多),所以本文便總結了一些在常見場景中利用PHP 內建函數的實現方法。此外如果想更深入的學習有關PHP 數組函數最好還是去查PHP 手冊!

相關學習推薦:

PHP影片教學:https://www.php.cn/course /list/29/type/2.html

0x01 取指定鍵名

對於某些關聯數組,有時我們只想取指定鍵名的那部分,例如數組為['id' => 1, 'name' => 'zane', 'password' => '123456'] 此時若只想取包含id 和name的部分該怎麼實現呢?下面直接貼程式碼。

<?php
$raw = [&#39;id&#39; => 1, &#39;name&#39; => &#39;zane&#39;, &#39;password&#39; => &#39;123456&#39;];
// 自己用 PHP 实现
function onlyKeys($raw, $keys) {
    $new = [];
    foreach ($raw as $key => $val) {
        if (in_array($key, $keys)) {
            $new[$key] = $val;
        }
    }
    
    return $new;
}
// 用 PHP 内置函数实现
function newOnlyKeys($array, $keys) {
    return array_intersect_key($array, array_flip($keys));
}
var_dump(onlyKeys($raw, [&#39;id&#39;, &#39;name&#39;]));
// 结果 [&#39;id&#39; => 1, &#39;name&#39; => &#39;zane&#39;]
var_dump(newOnlyKeys($raw, [&#39;id&#39;, &#39;name&#39;]));
// 结果 [&#39;id&#39; => 1, &#39;name&#39; => &#39;zane&#39;]

很明顯簡潔很多有木有!不過array_intersect_key 和array_flip 是什麼鬼?這裡簡單的介紹一下這兩個函數的作用,首先是array_flip函數,這個函數的功能是「將數組的鍵和值對調」,也就是鍵名變成值,值變成鍵名。我們傳遞的$keys 參數經過這個函數便從[0 => 'id' , 1 => 'name'] 轉變為了['id' => 0, 'name' => 1]。

這樣做的目的是為了向array_intersect_key 函數服務,array_intersect_key 函數的功能是「使用鍵名比較計算數組的交集」,也就是返回第一個參數數組中與其他參數數組相同鍵名的值。這樣便實現了取指定鍵名的功能~(≧▽≦)/~啦!當然要詳細了解這兩個函數的功能還是要查PHP 官方手冊:array_flip array_intersect_key

0x02 移除指定鍵名

#有了上一個範例做鋪墊,這個就簡單講講啦,道理是大同小異滴。

<?php
$raw = [&#39;id&#39; => 1, &#39;name&#39; => &#39;zane&#39;, &#39;password&#39; => &#39;123456&#39;];
// 用 PHP 内置函数实现
function removeKeys($array, $keys) {
    return array_diff_key($array, array_flip($keys));
}
// 移除 id 键
var_dump(removeKeys($raw, [&#39;id&#39;, &#39;password&#39;]));
// 结果 [&#39;name&#39; => &#39;zane&#39;]

和上一個例子相比本例只是將array_intersect_key 函數改為array_diff_key,嗯……相信大家能猜出來這個函數的功能“使用鍵名比較計算數組的差集」,剛好和array_intersect_key 的功能相反而已。官方手冊:array_diff_key

0x03 陣列去重

這個相信大家都有這個需求,當然PHP 也內建了array_unique 函數供給大家使用,如下例:

<?php
$input = [&#39;you are&#39; => 666, &#39;i am&#39; => 233, &#39;he is&#39; => 233, &#39;she is&#39; => 666];
$result = array_unique($input);
var_dump($result);
// 结果 [&#39;you are&#39; => 666, &#39;i am&#39; => 233]

嘿,用這個函數就能解決大部分問題了,但是有時候你可能會覺得它不夠快,原因如下:

array_unique() 先將值作為字串排序,然後每個值只保留第一個遇到的鍵名,接著忽略所有後面的鍵名。

因為這個函數會先將陣列排序,所以速度可能在某些場景達不到預期的要求。

現在我們可以祭祀我們的黑科技 array_flip 函數,眾所周知 PHP 裡數組的鍵名是唯一的,所以在鍵名和值對調後重複的值便被忽略了。試想我們連續呼叫兩次 array_flip 函數是不是就等於實作了 array_unique 函數的函數呢?範例程式碼如下:

<?php
$input = [&#39;you are&#39; => 666, &#39;i am&#39; => 233, &#39;he is&#39; => 233, &#39;she is&#39; => 666];
$result = array_flip(array_flip($input));
var_dump($result);
// 结果 [&#39;she is&#39; => 666, &#39;he is&#39; => 233]

嗯哼? !結果和 array_unique 的不一樣!為什麼,我們可以從 PHP 官方手冊得到答案:

如果同一個值出現多次,則最後一個鍵名將作為它的值,其它鍵會被丟棄。

總的來說就是 array_unique 保留第一個出現的鍵名,array_flip 保留最後一個出現的鍵名。

注意:使用 array_flip 作為數組去重時數組的值必須能夠作為鍵名(即為 string 類型或 integer 類型),否則這個值將被忽略。

此外,若不需要保留鍵名我們可以直接這樣使用 array_values(array_flip($input))。

0x04 重設索引

當我們想要對索引不連續的陣列進行重設時,例如陣列:[0 => 233, 99 => 666],對於這種陣列我們只需要呼叫array_values 函數即可實現。如下例:

<?php
$input = [0 => 233, 99 => 666];
var_dump(array_values($input));
// 结果 [0 => 233, 1 => 66]

需要注意的是 array_values 函數不只重置數字索引還會將字串鍵名也同樣刪除並重置。那如何在保留字串鍵名的同時重置數字索引呢?答案是array_slice 函數,程式碼範例如下:

<?php
$input = [&#39;hello&#39; => &#39;world&#39;, 0 => 233, 99 => 666];
var_dump(array_slice($input, 0));
// 结果 [&#39;hello&#39; => &#39;world&#39;, 0 => 233, 1 => 66]

array_slice 函數的功能是取出數組的中的一段,但它預設會重新排序並重置數組的數字索引,所以可以利用它重置數組中的數字索引。

0x05 清除空值

#

嘿,有时候我们想清除某个数组中的空值比如:null、false、0、0.0、[]空数组、''空字符串、'0'字符串0 ,这时 array_filter 函数便能帮上大忙。代码如下:

<?php
$input = [&#39;foo&#39;, false, -1, null, &#39;&#39;, []];
var_dump(array_filter($input));
// 结果 [0 => &#39;foo&#39;, 2 => -1]

为什么会出现这样的结果捏?array_filter 的作用其实是「用回调函数过滤数组中的单元」,它的第二个参数其实是个回调函数,向数组的每个成员都执行这个回调函数,若回调函数的返回值为 true 便保留这个成员,为 false 则忽略。这个函数还有一个特性就是:

如果没有提供 callback 函数, 将删除 array 中所有等值为 FALSE 的条目。

等值为 false 就是转换为 bool 类型后值为 false 的意思,详细看文档:转换为布尔类型。

注意:如果不填写 callback 函数,0、0.0、'0'字符串0 这些可能有意义的值会被删除。所以如果清除的规则有所不同还需要自行编写 callback 函数。

0x06 确认数组成员全部为真

有时候我们希望确认数组中的的值全部为 true,比如:['read' => true, 'write' => true, 'execute' => true],这时我们需要用一个循环判定吗?NO,NO,NO……只需要用 array_product 函数便可以实现了。代码如下:

<?php
$power = [&#39;read&#39; => true, &#39;write&#39; => true, &#39;execute&#39; => true];
var_dump((bool)array_product($power));
// 结果 true
$power = [&#39;read&#39; => true, &#39;write&#39; => true, &#39;execute&#39; => false];
var_dump((bool)array_product($power));
// 结果 false

为什么能实现这个功能呢? array_product 函数本来的功能是「计算数组中所有值的乘积」,在累乘数组中所有成员的时候会将成员的值转为数值类型。当传递的参数为一个 bool 成员所组成的数组时,众所周知 true 会被转为 1,false 会被转为 0。然后只要数组中出现一个 false 累乘的结果自然会变成 0,然后我们再将结果转为 bool 类型不就是 false 了嘛!

注意:使用 array_product 函数将在计算过程中将数组成员转为数值类型进行计算,所以请确保你了解数组成员转为数值类型后的值,否则会产生意料之外的结果。比如:

<?php
$power = [&#39;read&#39; => true, &#39;write&#39; => true, &#39;execute&#39; => &#39;true&#39;];
var_dump((bool)array_product($power));
// 结果 false

上例是因为 'true' 在计算过程中被转为 0。要想详细了解请点击这里。

0x07 获取指定键名之前 / 之后的数组

如果我们只想要关联数组中指定键名值之前的部分该怎么办呢?又用一个循环?当然不用我们可以通过 array_keys、array_search 和 array_slice 组合使用便能够实现!下面贴代码:

<?php
$data = [&#39;first&#39; => 1, &#39;second&#39; => 2, &#39;third&#39; => 3];
function beforeKey($array, $key) {
    $keys = array_keys($array);
      // $keys = [0 => &#39;first&#39;, 1 => &#39;second&#39;, 2 => &#39;third&#39;]
    $len = array_search($key, $keys);
    return array_slice($array, 0, $len);
}
var_dump(beforeKey($data, &#39;first&#39;));
// 结果 []
var_dump(beforeKey($data, &#39;second&#39;));
// 结果 [&#39;first&#39; => 1]
var_dump(beforeKey($data, &#39;third&#39;));
// 结果 [&#39;first&#39; => 1, &#39;second&#39; => 2]

思路解析,要实现这样的功能大部分同学都应该能想到 array_slice 函数,但这个函数取出部分数组是根据偏移量(可以理解为键名在数组中的顺序,从 0 开始)而不是根据键名的,而关联数组的键名却是是字符串或者是不按顺序的数字,此时要解决的问题便是「如何取到键名对应的偏移量?」,这是 array_keys 函数便帮了我们大忙,它的功能是「返回数组中部分的或所有的键名」默认返回全部键名,此外返回的键名数组是以数字索引的,也就是说返回的键名数组的索引就是偏移量!例子中的原数组变为: [0 => 'first', 1 => 'second', 2 => 'third'] 。然后我们通过 array_search 便可以获得指定键名的偏移量了,因为这个函数的功能是「在数组中搜索给定的值,如果成功则返回首个相应的键名」。有了偏移量我们直接调用 array_slice 函数便可以实现目的了。

上面的例子懂了,那获取指定键名之后的数组也就轻而易举了,略微修改 array_slice 即可。直接贴代码:

<?php
$data = [&#39;first&#39; => 1, &#39;second&#39; => 2, &#39;third&#39; => 3];
function afterKey($array, $key) {
    $keys = array_keys($array);
    $offset = array_search($key, $keys);
    return array_slice($array, $offset + 1);
}
var_dump(afterKey($data, &#39;first&#39;));
// 结果 [&#39;second&#39; => 2, &#39;third&#39; => 3]
var_dump(afterKey($data, &#39;second&#39;));
// 结果 [&#39;third&#39; => 3]
var_dump(afterKey($data, &#39;third&#39;));
// 结果 []

那如何获取指定值之前或之后的数组呢?嘿,记得 array_search 的作用吧,其实我们只需要这样调用 beforeKey($data, array_search($value, $data)) 不就实现了嘛!

0x08 数组中重复次数最多的值

敲黑板,划重点!据说这是一道面试题喔。假设有这样一个数组 [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8],请问如何获取数组中重复次数最多的值?关键就在于 array_count_values 函数。实例代码如下:

<?php
$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];
$cv = array_count_values($data);
// $cv = [6 => 2, 11 => 4, 2 => 2, 4 => 3, 7 => 1, 8 => 1]
arsort($cv);
$max = key($cv);
var_dump($max);
// 结果 11

array_count_values 函数的功能是「统计数组中所有的值」,就是将原数组中的值作为返回数组的键名,值出现的次数作为返回数组的值。这样我们便可以通过 arsort 函数对出现的次数进行降序排序并且保持索引关联。最后使用 key 获得当前单元(当前单元默认为数组第一个成员)的键名,此时的键名即是原数组的值重复次数最多的值。

0x09 打广告时间

虽然 PHP 提供了很多和数组相关的函数,但使用起来还是不算太方便而且都是通过函数的调用方式而没有面向对象相关的实现,所以我最近在写一个开源的工具类项目 zane/utils,封装了一些常用的方法并且支持链式调用,其中的 Ary 类实现 「获取数组中重复次数最多的值」只需一行,如下所示:

$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];
$max = Ary::new($data)->countValues()->maxKey();
var_dump($max);
// 结果 11

欢迎大家给我提 issue 和 pr,另外如果你喜欢这个项目希望动动小手点个 star。

项目地址:https://github.com/zanemmm/utils

0x0A 结语

其实还有很多实用的函数没有介绍,但是限于文章篇幅就讲到这里了吧。本文出现的很多例子都并非本人原创的,多数出于 PHP 官方手册(每个函数功能下面的评论里都有很多大神提出一些厉害的用法,部分示例就是出自评论)。在下只是拾人牙慧,将其总结了一下。另外文章中若出现错误,希望大家能够指出,若有疑问可以互相讨论。

更多编程相关内容,请关注php中文网编程入门栏目!

以上是如何巧用 PHP 數組函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:segmentfault。如有侵權,請聯絡admin@php.cn刪除
PHP:許多網站的基礎PHP:許多網站的基礎Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

超越炒作:評估當今PHP的角色超越炒作:評估當今PHP的角色Apr 12, 2025 am 12:17 AM

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

PHP中的弱參考是什麼?什麼時候有用?PHP中的弱參考是什麼?什麼時候有用?Apr 12, 2025 am 12:13 AM

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

解釋PHP中的__ Invoke Magic方法。解釋PHP中的__ Invoke Magic方法。Apr 12, 2025 am 12:07 AM

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。

解釋PHP 8.1中的纖維以進行並發。解釋PHP 8.1中的纖維以進行並發。Apr 12, 2025 am 12:05 AM

Fibers在PHP8.1中引入,提升了並發處理能力。 1)Fibers是一種輕量級的並發模型,類似於協程。 2)它們允許開發者手動控制任務的執行流,適合處理I/O密集型任務。 3)使用Fibers可以編寫更高效、響應性更強的代碼。

PHP社區:資源,支持和發展PHP社區:資源,支持和發展Apr 12, 2025 am 12:04 AM

PHP社區提供了豐富的資源和支持,幫助開發者成長。 1)資源包括官方文檔、教程、博客和開源項目如Laravel和Symfony。 2)支持可以通過StackOverflow、Reddit和Slack頻道獲得。 3)開發動態可以通過關注RFC了解。 4)融入社區可以通過積極參與、貢獻代碼和學習分享來實現。

PHP與Python:了解差異PHP與Python:了解差異Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

php:死亡還是簡單地適應?php:死亡還是簡單地適應?Apr 11, 2025 am 12:13 AM

PHP不是在消亡,而是在不斷適應和進化。 1)PHP從1994年起經歷多次版本迭代,適應新技術趨勢。 2)目前廣泛應用於電子商務、內容管理系統等領域。 3)PHP8引入JIT編譯器等功能,提升性能和現代化。 4)使用OPcache和遵循PSR-12標準可優化性能和代碼質量。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器