0

我有这段 PHP 代码(为简洁起见)作为准备好的语句,允许用户使用系列标题搜索数据库......

$series = null;
if (isset($_GET["series"])) $series = $_GET["series"];

try {
    $dbh = new PDO("sqlsrv:Server=localhost;Database=Radio", "", "");
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    if (isset($series)) {
        $sql = "SELECT *
            FROM dbo.Schedule
            WHERE dbo.Schedule.Series LIKE :series
            ORDER BY dbo.Schedule.Date ASC";
    }
    $stmt = $dbh->prepare($sql);
    if (isset($series)) {
        $stmt->execute(array(":series" => $series));
    }
    $stmt->setFetchMode(PDO::FETCH_ASSOC);
    $dbh = null;
}
catch(PDOException $e) {
    echo $e->getMessage();
}

对于不包含 & 的任何系列标题,它都可以正常工作,但对于包含 & 的任何系列标题,它都会失败(不产生任何结果)。

例如,丰富的能力有效,但接受和施助治疗无效(即使两者都在数据库的系列字段中。

我试过htmlspecialchars(rawurlencode($_GET["series"]))了,每一个都是单独的。

在 SQL 服务器上,传递相同的查询(使用标题)就可以了。

SELECT *
FROM [Radio].[dbo].[Schedule]
where Series like 'Receiving & Ministering Healing'

我的猜测是问题出在准备好的语句的执行或绑定参数中。

我在PHP 的 Prepared Statements 页面上搜索了 &,但没有看到任何结果。

编辑:

我用它来让它工作......

$series = null;
if (isset($_GET["series"])) $series = $_GET["series"];
$queries = parse_url($_SERVER['QUERY_STRING']);
if (substr($queries["path"], 7) == "Receiving%20&%20Ministering%20Healing") $series = "Receiving & Ministering Healing";

我确信这是一种糟糕的方法,但没有其他选择有效。当然,这只适用于这种特殊情况。我欢迎更好的解决方案。

编辑2:

我发现一个带有 WORD And in it (Graces And Places) 的系列出现了同样的问题。我最终复制了我的“修复”来接受和施助医治。

我似乎与 URL 查询(或单词 And 无关紧要)没有任何关系,而是准备好的语句。

4

1 回答 1

3

这可能有多种原因。这个&角色在多个层面上都是邪恶的,在这种情况下,这两个似乎相关:

您的请求可能是这样的(&下面突出显示的标志)

http://somedomain.com/somepage.php?param=something&series=Receiving & Ministering Healing
                                                  ^ (valid)         ^ (unintended!)

因为标题没有为 URL 转义。这意味着 & 字符标记了一个新的参数名称 - 并且会截断seriestoReceiving而不是完整的 title Receiving & Ministering,从而导致查询:

SELECT *
FROM [Radio].[dbo].[Schedule]
where Series like 'Receiving '

您可能应该向我们展示如何组装请求的 URL 以便能够推荐更合适的解决方案,但您应该使用urlencode()来转义要在 GET 参数中使用的值。

或者问题可能是(但现在不是这种情况)您错误地写入了值。

单个&字符在 HTML 中无效!正确的转义是&

您应该使用 HTML 对SELECT查询的输出进行编码htmlentities

echo "<h1>".htmlentities($resultComingFromQuery)."</h1>";

编辑

一个错误的请求可能会导致一个错误的响应(GIGO)......这个:

http://www.flcbranson.org/api/radio/?series=Receiving%20%26%20Ministering Healing

是正确的要求。这是URL 编码的。你必须解码它:

$decodedTitle = urldecode($_GET['series']);

并在查询中使用它...

于 2013-10-03T16:41:52.353 回答