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 のプリペアド ステートメント ページで &を検索しましたが、結果が表示されませんでした。

編集:

私はそれを機能させるためにこれを使用しました...

$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 を含むシリーズ (Graces And Places) でも同じ問題が発生することがわかりました。私は、そのためのレシーブ&ミニスタリング・ヒーリングの「修正」を複製することになりました。

URL クエリ (または And という単語は重要ではありません) とは何の関係もないように思われますが、準備されたステートメントとは関係ありません。

4

1 に答える 1

3

これには複数の原因が考えられます。キャラクターは複数のレベルで悪です。&この場合、次の 2 つが関連しているようです。

リクエストが次のようになっている可能性があります (&記号は下に強調表示されています) 。

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

URL のタイトルがエスケープされていないためです。これは、 & 文字が新しいパラメーター名をマークすることを意味し、完全なタイトルではなくseriesbeに切り捨てられ、クエリが次のようになります。ReceivingReceiving & Ministering

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

より適切な解決策を推奨できるように、リクエストの URL を組み立てる方法を示す必要がありますが、GET パラメータで使用される値をエスケープするにはurlencode()を使用する必要があります。

または、値を間違って記述していることが問題である可能性があります (ただし、現在はそうではありません) 。

HTML では1&文字は無効です。正しいエスケープは&

SELECTクエリからの出力を次のように HTML エンコードする必要があります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 に答える