You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP DOMDocument替换图片URL遇双点空格触发Invalid '..'-range报错

报错信息

Invalid '..'-range, '..'-range needs to be incrementing

问题描述

我此前在西班牙语论坛提出过相同问题,但未得到有效解答,找不到其他解决方案因此在此提问。
我的需求是批量修改多篇文章条目中的部分图片URL:对于图片URL路径规则简单的条目,修改逻辑可正常运行;但URL路径中夹杂空格、连续双点的条目会触发上述报错。
我从数据库读取数据开展测试,选取了触发该报错的ID=2的用户数据作为测试样本,以下是我用于修改图片URL的测试代码:

$data= User::find(2);

$html = $data->name;
$html = "<body>$html</body>";


$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_COMPACT | LIBXML_HTML_NOIMPLIED | LIBXML_NONET | LIBXML_HTML_NODEFDTD);
if (is_null($dom)) {
} else {
  $a_nodelist = $dom->getElementsByTagName('p');

  foreach ($a_nodelist as $enlace) {
    $img = $enlace->getElementsByTagName('img')->item(0);
    if ($img) {
      $urlImagen = $img->getAttribute('src');
      $imagenArreglo = explode("/", $urlImagen);
      $nombreImagen = end($imagenArreglo);

      $rutasinImagen = rtrim($urlImagen, $nombreImagen);

      dd($rutasinImagen);

      $nuevaruta = 'http://www.rumberos.net/wp-content/uploads/2022/imagen/';
      $file = fopen("archivo.txt", "a");
      fwrite($file, $data->id . PHP_EOL);
      fclose($file);

      DB::table("users")
        ->where("id", "=", $data->id)
        ->update(["name" => DB::raw("REPLACE(name,  '$rutasinImagen', '$nuevaruta')")]);
    }

文章内容以HTML格式存储,因此我使用DOMDocument解析DOM结构提取图片URL,该逻辑在部分URL规范的文章上可正常运行,我推测问题出在格式不规范的URL上。触发报错的测试条目中的图片URL如下:

http://midominio.com/images/2014/HTV- Premios Heat - Juanes..jpg

我在拆分字符串提取图片文件名的步骤添加了dd调试打印,该步骤运行正常,但在执行rtrim移除URL中文件名部分、后续数据库替换操作时触发报错,我怀疑异常是URL中包含的连续双点、空格特殊字符导致的。

故障原因

报错根源是对rtrim函数的用法理解错误:

  • rtrim的第二个参数是字符掩码集合,不是要完整删除的后缀字符串。函数会从字符串末尾开始,逐个检查字符是否在掩码集合内,只要命中就删除,直到碰到不在集合内的字符为止。
  • 传入的文件名参数是HTV- Premios Heat - Juanes..jpg,其中包含.字符,当函数处理到URL末尾的连续..时,会尝试将..解析为字符范围(类似a..z代表a到z的所有字符),但单独的..无法构成合法的递增字符范围,就会抛出对应错误。
  • 额外隐患:直接把URL变量拼接进SQL语句,URL里的空格、单引号等特殊字符不仅会导致SQL语法错误,还存在SQL注入风险。
修复方法
  • 弃用rtrim处理URL路径,改用字符串拆分的方式准确提取目录路径,替换原有rtrim相关逻辑:
    $imagenArreglo = explode("/", $urlImagen);
    $nombreImagen = array_pop($imagenArreglo); // 弹出数组最后一个元素,即文件名
    $rutasinImagen = implode("/", $imagenArreglo) . "/"; // 拼接剩余部分为目录路径,末尾补斜杠
    
  • 改写数据库更新逻辑,用参数绑定的方式传入替换值,避免特殊字符导致的语法问题和安全风险:
    DB::table("users")
        ->where("id", $data->id)
        ->update([
            "name" => DB::raw("REPLACE(name, :old_path, :new_path)")
        ])
        ->setBindings([
            'old_path' => $rutasinImagen,
            'new_path' => $nuevaruta
        ]);
    
  • 可选优化:处理URL前先做一次URL解码,避免编码后的空格(%20)、特殊字符导致路径匹配失败。

内容的提问来源于stack exchange,提问作者Isaac Lovera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:27:14