首页 > 解决方案 > 如何在可能具有 % 的格式字符串的一部分中转义 sprintf 说明符

问题描述

编码:

<?php
$tableName = 'users';
$position = 1;
$paths = ['index'];     
    $sqlFormat = "SELECT * FROM %s WHERE (";
    for ($i =0; $i < count($paths); $i++){
      if ($i == (count($paths)-1)){
        $sqlFormat .= "path LIKE '%%$paths[$i]%%') ";       
      }
      else{
        $sqlFormat .= "path LIKE '%%$paths[$i]%%' OR ";     
      }   
    }
    $sqlFormat .= "AND (position = $position) AND published = 'Y' ";
    $sqlFormat .= "ORDER BY weight ASC";
    $sql = sprintf($sqlFormat, $tableName);
    echo $sql;

症状:

$paths数组包含普通字符串时,它可以正常工作。但是,如果我们设置它的路径,$paths = ['index%'];则会生成PHP Warning: sprintf(): Too few arguments.... 换句话说,如果$paths包含值有%符号。在这种情况下我无法使用%%转义,like 发生在上面 SQL 的 like 子句中,...LIKE '%%$paths[$i]%%...因为$paths可能包含%可选的。

我无法找到一种方法来让可选转义(%如果存在)。所有类似的问题都谈论转义固定值

标签: phpescapingprintf

解决方案


我找到了一个解决方案,方法是使用str_replace()for 数组的元素逐个paths替换来解决问题:%%%

$sqlFormat .= "path LIKE '%%".str_replace('%','%%',$paths[$i])."%%') ";

因此,如果元素包含任何单个元素,则会通过将其加倍%来进行转义。sprintf


推荐阅读