PHP文件函数不支持通配符,传入"log_.txt"会直接创建字面名为log_.txt的文件;需用date、sprintf、md5等动态生成具体文件名,或结合glob()检测并推导编号。

PHP fopen() 和 file_put_contents() 不支持通配符命名
PHP 原生文件操作函数(如 fopen()、file_put_contents()、touch())**不解析通配符**(如 *、?、[a-z])。你传入 "log_*.txt",它会直接尝试创建一个字面名为 log_*.txt 的文件(含星号),而不是生成多个匹配名或自动补全。
想实现“通配符式”文件名,得自己生成具体名字
常见需求其实是:按时间、序号、哈希等规则动态生成唯一/有序的文件名。所谓“通配符”,本质是字符串模板 + 变量替换。例如:
-
"backup_{Y-m-d}_{$id}.sql"→ 用date('Y-m-d')和变量拼接 -
"image_{$counter:04d}.png"→ 用sprintf('image_%04d.png', $counter) -
"cache_".md5($key).".json"→ 哈希确保唯一性
别依赖 shell 通配符逻辑,PHP 文件系统层不处理这个。
用 glob() 配合创建前检查,避免覆盖
如果你的意图是「创建一个不与现有文件冲突的新文件」(比如 report_001.txt、report_002.txt),可以用 glob() 扫描已有匹配名,再推导下一个编号:
立即学习“PHP免费学习笔记(深入)”;
$base = 'report';
$pattern = $base . '_[0-9][0-9][0-9].txt';
$existing = glob($pattern);
$next_num = count($existing) + 1;
$filename = sprintf('%s_%03d.txt', $base, $next_num);
file_put_contents($filename, 'data');
注意:glob() 只读,不创建;且 Windows 下大小写不敏感,Linux 下敏感,glob() 行为一致但需注意路径分隔符。
误用 shell 通配符会导致静默失败或奇怪文件名
以下写法是错的,且危险:
-
file_put_contents('log_*.log', $data)→ 真的会创建叫log_*.log的文件(含星号字符) -
exec("touch log_*.log")→ 若当前目录有log_a.log,shell 展开后变成touch log_a.log,覆盖原文件 -
system("echo hello > cache_$(date +%s).txt")→ 依赖 shell,跨平台不可靠,还可能被注入(若变量未过滤)
真正可控的方式永远是:在 PHP 中先算出确定的文件名,再调用文件函数 —— 不绕过 PHP 的字符串控制权。
通配符是 shell 或 glob 模式匹配的概念,不是文件创建接口的参数语法。搞混这点,轻则生成错名,重则覆盖关键文件。











