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

相关推荐
峥嵘life8 小时前
Android16 311Y3 EAP-TLS 网络连接失败分析与修复总结
android·开发语言·人工智能·php
AC赳赳老秦12 小时前
公开图片 OCR 数据提取:OpenClaw 合规采集公开信息图,识别文字与表格并转化为结构化数据
java·大数据·前端·数据库·python·php·openclaw
吴声子夜歌12 小时前
网络安全——概述(一)
安全·web安全
云水一下13 小时前
零基础玩转bWAPP靶场(五十九):Insecure DOR (Change Secret)
web安全·bwapp·idor·change secret
AC赳赳老秦14 小时前
风控岗应用:OpenClaw 采集公开司法与经营异常数据,自动生成企业风险评估报告
大数据·c语言·数据库·人工智能·python·php·openclaw
云水一下17 小时前
零基础玩转bWAPP靶场(五十八):XSS - Stored (User-Agent)
web安全·xss·bwapp·user-agent·stored
发量惊人的中年网工18 小时前
中小企业网络管理进阶:从设备堆叠到统一管理
服务器·网络·安全·网络安全·php·制造
小新讲网安21 小时前
PowerShell安全攻防实战:从渗透利用到检测防御全攻略
安全·web安全·网络安全·黑客·自动化·sqlmap·网安
北漂燕郊杨哥21 小时前
phpStudy 手工安装最新稳定版 PHP 8.5.9(NTS)方法(Windows 本地开发)
windows·php·phpstudy
qetfw1 天前
Debian 部署 Discuz! 论坛:Nginx、PHP 与 MariaDB 配置
linux·运维·nginx·debian·php·discuz