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

相关推荐
一拳一个娘娘腔4 小时前
【第五期】漏洞攻防-逻辑篇:越权与支付漏洞 —— 为什么改个参数就能“0元购”?
安全·web安全·web
ch3nyuyu5 小时前
socket套接字
开发语言·php
持敬chijing6 小时前
Web渗透之前后端漏洞-命令注入
安全·web安全·网络安全·网络攻击模型·安全威胁分析
leagsoft_10037 小时前
零信任选型五刀法——零信任怎么选?五个问题,五条红线
开发语言·php
顾凌陵7 小时前
Web信息收集实战指南
安全·web安全
yyuuuzz7 小时前
云服务器软件部署的几个常见问题
运维·服务器·开发语言·网络·云计算·php·apache
juesdo8 小时前
青岑CTF web入门 EZCMD系列
web安全·网络安全·php
RisunJan8 小时前
Linux命令-php(PHP语言的命令行接口)
linux·php
持敬chijing9 小时前
Web渗透之前后端漏洞-CSRF(跨站请求伪造)
安全·web安全·网络安全·xss·csrf