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

相关推荐
码云数智-大飞16 小时前
PHP 接口开发规范:统一返回格式、异常处理与参数校验
开发语言·php
admin and root16 小时前
「移动安全」安卓APP 反编译&frida脱壳技巧分享
android·开发语言·python·web安全·微信小程序·移动安全·攻防演练
dadaobusi16 小时前
仿真边界处理
开发语言·php
云水一下17 小时前
零基础玩转bWAPP靶场(十四):SQL 注入(GET/选择型)
web安全·sql注入·bwapp
微学AI19 小时前
内网穿透的应用-把飞牛NAS变成家庭录像中心:EasyNVR部署与远程回放实战
开发语言·php
峥嵘life19 小时前
Android WiFi连接过程 wpa_supplicant 日志分析
android·开发语言·php
weixin_BYSJ198719 小时前
「课设设计」springboot校园超市助购系统26449 (附源码)
java·javascript·spring boot·python·django·flask·php
sbjdhjd19 小时前
SQL 注入零基础详解:原理、手工注入流程与 Sqli-Labs 靶场实战1~5关和第9关思路
数据库·sql·计算机网络·web安全·网络安全·网络攻击模型·安全架构
xuefeiniao20 小时前
CentOS + 宝塔服务器偶发 SSH、面板、网站全部无法访问排查记录(PHP-FPM 内存耗尽案例)
服务器·centos·ssh·php
学习溢出20 小时前
【网络安全】Living off the Land 攻击 | 蓝队防守
安全·web安全·网络安全