开发者社区> 问答> 正文

PDO是如何处理SQL语句中对字段名以及表名的转义

比如在一个数据表中有一个字段叫order,是专门用来做排序的,我的语句可能要这么写

$sth = $pdo->prepare('SELECT * FROM table_name ORDER BY order ASC');
$sth->execute();

但是因为order本身是一个关键字,那么在执行的时候就会报syntax错误,我知道在pdo里对字段可以用:column_name来动态绑定,它会自动处理引号等问题,也可以用$pdo->quote来转义字符串,但是对字段名和表名却没有方法来转义。

这种转义在不同的数据库系统里是一样的,比如在mysql里

SELECT * FROM table_name ORDER BY `order` ASC

而在sqlite里

SELECT * FROM table_name ORDER BY "order" ASC

有没有一种通用而又省事的办法来处理这个问题呢
更新
根据答案最后总结出一种通用的转义方法

$escapes = array(
    'mysql'    =>    array('`', '`'),
    'mssql'    =>    array('[', ']')
);

$driver = $db->getAttributes(PDO::ATTR_DRIVER_NAME);
$escape = isset($escapes[$driver]) ? $escapes[$driver] : array('"', '"');
$field = $escape[0] . $field . $escape[1];

展开
收起
落地花开啦 2016-06-12 14:43:51 3309 0
1 条回答
写回答
取消 提交回答
  • 喜欢技术,喜欢努力的人

    遇到这种问题,也许你只能使用判断driver的方法来达到目的。你可以专门为此写个函数或者方法:

    function add_quote_identifier($field, $driver = 'mysql')
    {
        switch ($driver) {
            case 'mysql':
                return sprintf('`%s`', $field);
            case 'sqlite':
                return sprintf('"%s"', $field);
            default:
                return $field;
        }
    }

    然后再利用他来prepare statement:
    $stmt = $dbh->prepare(sprintf('SELECT * FROM table_name ORDER BY %s ASC', add_quote_identifier('order')));

    2019-07-17 19:34:03
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
SQL Server 2017 立即下载
GeoMesa on Spark SQL 立即下载
原生SQL on Hadoop引擎- Apache HAWQ 2.x最新技术解密malili 立即下载