如何让PHP glob搜索不受关键词顺序影响?
解决PHP多关键词任意顺序文件搜索问题
别担心基础问题呀,刚自学PHP遇到这类匹配逻辑的问题太正常了~咱们先说说你当前代码的核心问题:你用glob拼接的$inclusion是按关键词输入顺序生成的通配符模式,比如输入"dog cat",模式会变成*dog*cat*,这就要求文件/路径里必须先出现dog再出现cat才能匹配,反过来就搜不到了。
要实现所有关键词都存在、不限制顺序的搜索,我们需要换个思路:先获取所有目标JPG文件,再逐个检查每个文件的路径是否包含所有关键词,不管顺序。下面是具体的修改方案:
核心思路
- 递归遍历所有子文件夹,获取所有JPG文件(兼容大小写)
- 对每个文件的完整路径(包含文件夹名+文件名),检查是否同时包含所有关键词(不区分大小写)
- 再应用你的排除规则,最后筛选出符合条件的文件
修改后的完整代码
<?php // 获取用户输入的关键词,处理空输入情况 $keywords = trim($_REQUEST['keywords'] ?? ''); // 分割关键词并过滤空字符串(处理多个空格的情况) $exploded_keywords = array_filter(explode(" ", $keywords)); // 转成小写,方便不区分大小写检查 $keywords_lower = array_map('strtolower', $exploded_keywords); // 确保你已经正确定义排除词数组(示例值可替换) $exclude = []; // 比如:['temp', 'draft'] // 存储最终符合条件的文件 $matched_files = []; // 递归遍历根目录下的所有文件(根目录可按需修改,当前目录用.) $root_dir = '.'; $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root_dir)); foreach ($iterator as $file) { // 只处理文件,且是JPG格式(兼容大小写) if ($file->isFile() && preg_match('/\.jpg$/i', $file->getFilename())) { // 获取文件完整路径并转小写 $full_path = strtolower($file->getPathname()); // 检查是否包含所有关键词 $all_keywords_hit = true; foreach ($keywords_lower as $keyword) { if (strpos($full_path, $keyword) === false) { $all_keywords_hit = false; break; } } // 关键词全部命中后,再检查是否在排除列表中 if ($all_keywords_hit) { $is_excluded = false; foreach ($exclude as $term) { if (stripos($full_path, strtolower($term)) !== false) { $is_excluded = true; break; } } if (!$is_excluded) { $matched_files[] = $file->getPathname(); } } } } // 展示缩略图的逻辑(替换成你原有的展示代码即可) foreach ($matched_files as $file) { // 示例:echo '<img src="' . htmlspecialchars($file) . '" alt="Thumbnail" class="thumb">'; } ?>
关键改进点说明
- 用
RecursiveDirectoryIterator递归遍历子目录,比glob更灵活,支持任意深度的文件夹 - 统一转小写后用
strpos检查,实现不区分大小写的匹配,和你原代码中[jJ][pP][gG]的逻辑保持一致 - 先验证所有关键词是否存在,再检查排除项,逻辑更清晰,也避免了无效的排除检查
- 过滤空关键词,解决用户输入多个空格导致的无效匹配问题
为什么原来的方法不行?
glob的通配符模式是顺序敏感的,*keyword1*keyword2*表示"任意字符 + keyword1 + 任意字符 + keyword2 + 任意字符",它无法实现"同时包含两个关键词但顺序不限"的匹配需求。只有逐个检查每个关键词是否存在,才能达成这种任意顺序的多关键词搜索。
内容的提问来源于stack exchange,提问作者Diego T
相关产品推荐
相关产品推荐

