ZetCode

PHP PDO::quote 方法

最后修改于 2025 年 4 月 19 日

PHP 中的 PDO::quote 方法用于转义和引用字符串,以便在 SQL 查询中使用。它有助于在不使用预处理语句时防止 SQL 注入。

基本定义

PDO::quote 会在字符串前后加上引号,并转义输入字符串中的特殊字符。它返回一个理论上可以安全包含在 SQL 语句中的带引号字符串。

语法:public PDO::quote(string $string, int $parameter_type = PDO::PARAM_STR): string|false。该方法返回带引号的字符串,如果失败则返回 false。

基本用法示例

这演示了 PDO::quote 转义字符串的最简单用法。

pdo_quote_basic.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $string = "O'Reilly";
    $quoted = $pdo->quote($string);
    
    echo "Original: $string\n";
    echo "Quoted: $quoted";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这通过添加反斜杠来转义 "O'Reilly" 中的撇号。输出将显示可以安全用于 SQL 查询的正确加引号的字符串。

在 SQL 查询中使用 quote

这展示了如何在直接 SQL 查询执行中使用 PDO::quote。

pdo_quote_query.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $name = "John O'Connor";
    $quotedName = $pdo->quote($name);
    
    $sql = "SELECT * FROM users WHERE name = $quotedName";
    $stmt = $pdo->query($sql);
    
    $user = $stmt->fetch();
    if ($user) {
        echo "User found: {$user['name']}";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

通过先引用用户输入,可以安全地将其包含在 SQL 查询中。请注意,出于安全考虑,通常优先使用预处理语句而不是此方法。

使用不同的参数类型引用

PDO::quote 可以处理字符串和整数等不同的参数类型。

pdo_quote_types.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    
    // String parameter
    $string = "It's a string";
    $quotedString = $pdo->quote($string, PDO::PARAM_STR);
    
    // Integer parameter
    $number = 42;
    $quotedNumber = $pdo->quote($number, PDO::PARAM_INT);
    
    echo "Quoted string: $quotedString\n";
    echo "Quoted number: $quotedNumber";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这演示了引用不同的数据类型。请注意,PDO::PARAM_INT 仍然返回带引号的字符串,这可能不适用于所有数据库操作。

为 LIKE 子句进行引用

在将 PDO::quote 与 LIKE 子句一起使用时,需要特殊处理。

pdo_quote_like.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $search = "%test%";
    $quotedSearch = $pdo->quote($search);
    
    // Remove outer quotes added by quote()
    $quotedSearch = trim($quotedSearch, "'");
    
    $sql = "SELECT * FROM products WHERE name LIKE '%$quotedSearch%'";
    $stmt = $pdo->query($sql);
    
    while ($row = $stmt->fetch()) {
        echo "Product: {$row['name']}\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这展示了如何处理带 PDO::quote 的 LIKE 通配符。我们删除了外部引号,以便将通配符字符正确包含在 SQL 模式中。

为多个值进行引用

这演示了为 IN 子句引用多个值。

pdo_quote_multiple.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $values = ["apple", "banana", "cherry"];
    
    $quotedValues = array_map([$pdo, 'quote'], $values);
    $inClause = implode(',', $quotedValues);
    
    $sql = "SELECT * FROM fruits WHERE name IN ($inClause)";
    $stmt = $pdo->query($sql);
    
    while ($row = $stmt->fetch()) {
        echo "Fruit: {$row['name']}\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这通过引用每个数组元素来创建安全的 IN 子句。array_map 函数将 quote 应用于每个值,implode 函数将它们与逗号连接起来。

引用与预处理语句

这比较了使用 PDO::quote 和预处理语句进行安全性。

pdo_quote_vs_prepared.php
<?php

declare(strict_types=1);

try {
    $pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
    $input = "O'Reilly";
    
    // Using quote
    $quoted = $pdo->quote($input);
    $sql1 = "SELECT * FROM books WHERE author = $quoted";
    
    // Using prepared statement
    $sql2 = "SELECT * FROM books WHERE author = ?";
    $stmt = $pdo->prepare($sql2);
    $stmt->execute([$input]);
    
    echo "Query with quote: $sql1\n";
    echo "Prepared statement is generally preferred for security";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

虽然两种方法都能防止 SQL 注入,但通常更推荐使用预处理语句。它们更安全,并且对于重复查询通常性能更高。

特定于数据库的行为

PDO::quote 的行为可能因数据库驱动程序而异,如下所示。

pdo_quote_drivers.php
<?php

declare(strict_types=1);

$string = "It's a test";

// MySQL
$mysql = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
echo "MySQL: " . $mysql->quote($string) . "\n";

// SQLite
$sqlite = new PDO('sqlite:test.db');
echo "SQLite: " . $sqlite->quote($string) . "\n";

// PostgreSQL
$pgsql = new PDO('pgsql:host=localhost;dbname=testdb', 'user', 'password');
echo "PostgreSQL: " . $pgsql->quote($string) . "\n";

不同的数据库驱动程序可能对 quote 的实现方式不同。请务必使用您的特定数据库进行测试,以了解 PDO::quote 的确切行为。

最佳实践

来源

PHP PDO::quote 文档

本教程通过实际示例介绍了 PDO::quote 方法,展示了其在不同数据库场景下的用法。

作者

我叫 Jan Bodnar,是一名热情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有超过十年的经验。

列出 所有 PHP PDO 函数