array_search()函数的用法

array_search() 是 PHP 中非常基础且常用的一个数组处理函数。但在 Web 安全(尤其是代码审计和 CTF)中,它因为默认的弱类型比较机制,经常成为漏洞的突破口。

1. 函数基本定义

array_search() 的作用是在数组中搜索给定的值,如果找到则返回首个匹配的键名 (Key) ,如果没找到则返回 false

官方语法签名:

php 复制代码
array_search(mixed $needle, array $haystack, bool $strict = false): int|string|false

它接收三个参数(前两个必填,第三个选填):

  • $needle (搜索的值): 你想要在数组中查找的目标值。
  • $haystack (被搜索的数组): 你要在哪个数组里面找。
  • $strict (严格模式):这是最关键的安全考点!
    • 默认值是 false:此时函数使用松散比较 ( ==)。也就是说,它只比较值,不比较数据类型。
    • 如果设置为 true:此时函数使用严格比较 ( ===)。它不仅要求值相等,还要求数据类型完全一致。

在 PHP 中,数组的"键"(key)既可以是整数(索引),也可以是字符串 。也就是说,索引数组的下标(0、1、2...)本身就是键。PHP 手册里统一称它们为"键"(key),而不是分开叫"索引"和"键名"。

php 复制代码
// 索引数组 ------ 键是整数
$arr1 = ['苹果', '香蕉', '橙子'];
$key = array_search('香蕉', $arr1);
echo $key;   // 输出 1(整数键,也就是我们常说的下标)

// 关联数组 ------ 键是字符串
$arr2 = ['a' => '苹果', 'b' => '香蕉', 'c' => '橙子'];
$key = array_search('香蕉', $arr2);
echo $key;   // 输出 'b'(字符串键)

// 混合数组
$arr3 = [10, 'name' => 'Tom', 20];
$key = array_search('Tom', $arr3);
echo $key;   // 输出 'name'

再看看array_search的其它用法:

php 复制代码
//重复值-只返回第一个匹配键
$arr = [1,2,3,2];
$key = array_search(2,$arr);          //返回 1(索引1)

//严格比较模式(strict=true)
$arr = [1,'1',2];
$key1 = array_search(1,$arr);         //返回 0(索引0)
$key2 = array_search(1,$arr,true);    //返回 0(索引0)
$key3 = array_search('1',$arr,true);    //返回 1(索引1)

//搜索失败返回false
$arr = ['a', 'b', 'c'];
$key = array_search('d', $arr);    // false

//警惕返回0导致的逻辑错误
$arr = ['apple', 'banana'];
$index = array_search('apple', $arr);   // 0

if (!$index) {          // 错误:0 被当作 false
    echo "未找到";      // 错误地输出"未找到"
}
// 正确写法:
if ($index === false) {
    echo "未找到";
}
扩展技巧

获取所有匹配值的键

如果数组中有重复值,而你想得到所有匹配的键,请使用:

php 复制代码
$arr = ['a','b','a','c'];
$needle = 'a';
$keys = array_keys($arr, $needle, true); // [0,2]

PHP 8.0 弱类型大改版(影响 CTF 和老系统审计)

这是近几年代码审计中最重大的变化。在 PHP 8.0 之前和之后,array_search() 在松散模式下的表现有着天壤之别。

  • PHP 7.x 及更早版本(经典的数字与字符串比较坑): 在老版本 PHP 中,当数字与非数字字符串进行 == 比较时,PHP 会把字符串强制转换为数字 0
php 复制代码
// 在 PHP 7.4 中
$arr = ['apple', 'banana'];
$key = array_search(0, $arr); // 返回 0 !! 
// 因为 0 == 'apple' 变成了 0 == 0,结果为 true
  • 你要搜索的值是整数 0
  • 数组中的元素是字符串 'apple''banana'
  • 在松散比较下,字符串与整数比较时,PHP 会尝试将字符串转换为数字。'apple' 转换为数字的结果是 0(非数字开头字符串转数字得 0),'banana' 同理。
  • 所以 0 == 'apple' 成立,array_search() 返回第一个匹配的键,即 0

PHP 8.0 及之后版本: PHP 官方终于修正了这个"反人类"的机制。现在,数字和非数字字符串比较时,会先把数字转成字符串。因此 0 == 'apple' 变成了 '0' == 'apple',结果为 false

相关推荐
Johnstons11 小时前
游戏网络测试怎么做?从延迟到丢包,一套完整的游戏弱网测试方案
网络·游戏·php
Rocket-Luo11 小时前
谈谈企业中的网络安全
网络·安全·web安全
技术不好的崎鸣同学12 小时前
[BJDCTF2020]The mystery of ip 思路及解法
网络·安全·web安全
Bruce_Liuxiaowei14 小时前
2026年7月第1周网络安全形势周报
人工智能·安全·web安全·ai·智能体
楷哥爱开发15 小时前
降低网络爬虫成本:基础设施优化指南
服务器·开发语言·php
两个人的幸福14 天前
Windows 桌面应用自研 PHP 队列(下):完整代码与六大工程化优化
php
BingoGo16 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
JaguarJack16 天前
PHP 泛型之殇 泛型 RFC 提案被拒绝
后端·php
用户30745969820717 天前
PHP 扩展——从入门到理解
php
鹏仔先生17 天前
拷贝漫画APP下载页PHP程序,后台带免费AI写作
php