最常见原因是松散比较和键为0被误判为false,必须用$key !== false严格判断;file_exists失败多因stat缓存、路径权限或NFS/Docker问题;MySQL乱码需确认连接、表、字段均为utf8mb4;date()时间偏差主因时区未设为Asia/Shanghai。

array_search 返回 false 却明明存在值
最常见的情况是用了松散比较,却没意识到 array_search 在没传第三个参数时默认做类型转换。比如数组里存的是字符串 '123',你用整数 123 去搜,它会返回键,但如果你后续用 if ($key) 判断,而键恰好是 0,就会被当成 false 跳过。
必须用严格比较判断返回值:
-
if ($key !== false)—— 这是唯一安全的写法 - 加第三个参数
true:array_search(123, $arr, true),避免字符串'123'和整数123意外匹配 - 确认搜索值和数组元素类型一致,必要时先用
(string)或(int)强转
file_exists 判断文件存在却返回 false
不是文件真不存在,而是 PHP 缓存了上次的 stat 结果,或者权限/路径出了问题。
典型诱因和应对方式:
立即学习“PHP免费学习笔记(深入)”;
- 调用前加
clearstatcache(),尤其在文件刚被创建或删除后立即检查 - 用
__DIR__ . '/path/to/file'拼绝对路径,别依赖当前工作目录 - 检查 Web 服务器用户(如
www-data)对目标路径是否有读权限,ls -l看一眼父目录的dr-xr-xr-x就可能拦住访问 - 如果路径来自 NFS 或 Docker volume,加一次重试:
for ($i = 0; $i
PDO 查询结果为空但 SQL 在数据库里能查到
大概率是字符集或连接配置不一致,中文字段尤其容易中招。
重点排查这几处:
- 连接后立刻执行
$pdo->exec("SET NAMES utf8mb4"),不能只靠 DSN 里的charset=utf8mb4 - 确认表和字段实际字符集:
SHOW CREATE TABLE your_table,得看到DEFAULT CHARSET=utf8mb4和COLLATE=utf8mb4_unicode_ci - 如果用
mysqli,记得调$mysqli->set_charset('utf8mb4'),这个动作不能省 - 检查 SQL 语句里有没有意外的不可见字符(比如从编辑器复制来的全角空格),用
bin2hex()打印字符串看看
date() 输出时间比实际快/慢 8 小时
几乎全是时区没设对,哪怕服务器时间准也没用。
关键点很实在:
- 不要依赖
php.ini的date.timezone,有些环境会被覆盖;每份脚本开头加date_default_timezone_set('Asia/Shanghai') - 别用
PRC、UTC+8这类非标准时区名,PHP 不认,必须用Asia/Shanghai这种 IANA 标准名 - 如果用
DateTime类,构造时就要带时区:new DateTime('now', new DateTimeZone('Asia/Shanghai')),否则默认按 UTC 解析 - 注意
time()返回的是 Unix 时间戳(UTC 秒数),它本身没错;错在date()格式化时没绑定时区
file_exists 查日志文件又因路径含错误时间而失败。所以一旦发现“查找不准确”,先盯住输入源头——时间、路径、编码、类型,别急着改搜索逻辑。



















