Php 参考—;关于PDO的常见问题 这是什么?
这是一个关于PHP数据对象的常见问题列表 为什么会这样? 由于PDO有一些普通PHP用户所不知道的特性,因此关于PDO中准备好的语句和错误处理的问题非常常见。所以,这只是一个可以找到所有这些东西的地方 我在这里该怎么办? 如果您的问题已通过此列表投票,请在下面找到您的问题并将修复应用于您的代码。简单看看其他问题也是一个好主意,让自己为其他常见的陷阱做好准备 名单Php 参考—;关于PDO的常见问题 这是什么?,php,pdo,Php,Pdo,这是一个关于PHP数据对象的常见问题列表 为什么会这样? 由于PDO有一些普通PHP用户所不知道的特性,因此关于PDO中准备好的语句和错误处理的问题非常常见。所以,这只是一个可以找到所有这些东西的地方 我在这里该怎么办? 如果您的问题已通过此列表投票,请在下面找到您的问题并将修复应用于您的代码。简单看看其他问题也是一个好主意,让自己为其他常见的陷阱做好准备 名单 另见 PDO查询失败,但我看不到任何错误。如何从PDO获取错误消息? 为了能够看到数据库错误,必须设置为exce
下面是一个正确创建PDO连接的示例:
$dsn = "mysql:host=$host;dbname=$db;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
// other options
);
$pdo = new PDO($dsn, $user, $pass, $opt);
通过这种方式连接,您将始终收到查询执行期间发生的所有数据库错误的通知。请注意,您通常必须能够看到PHP错误。在一个实时站点上,你必须查看错误日志,因此,设置必须是
error_reporting(E_ALL);
ini_set('display_errors',0);
ini_set('log_errors',1);
在本地开发服务器上,可以在屏幕上出错:
error_reporting(E_ALL);
ini_set('display_errors',1);
当然,您永远不应该在PDO语句前面使用错误抑制运算符(@
)
此外,由于许多糟糕的示例告诉您将每个PDO语句包装到try..catch
块中,因此我必须做一个明确的说明:
不要使用try..catch操作符只是为了回显错误消息。未捕获异常在这方面已经很好了,因为它的作用方式与其他PHP错误相同-因此,您可以使用站点范围的设置来定义行为-因此,您将收到没有此无用代码的错误消息。而无条件回显的错误消息可能会向潜在攻击者透露一些敏感信息,但会使诚实的访问者感到困惑
- 可以稍后添加,但不是必需的。特别是对于新用户,建议使用未经处理的异常,因为这些异常信息丰富、有用且安全李>
- 仅当您要处理错误本身时才使用
,例如回滚事务李>try..catch
$sql = "SELECT * FROM t WHERE column LIKE '%?%'";
如果你仔细思考一下这个问题,你就会明白,在单引号中,问号变成了一个字面问号,对准备好的语句没有任何特殊意义
所以,必须使用prepared语句发送完整的字符串文本。有两种可能的方法:
- 请先准备完整表达式:
$name = "%$name%"; $stm = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?"); $stm->execute(array($name)); $data = $stm->fetchAll();
- 或者在查询中使用连接
$sql = "SELECT * FROM t WHERE column LIKE concat('%',?,'%')";
LIMIT?,?
查询变成LIMIT'10',10'
,这是导致查询失败的无效语法
这个问题也可以解决
- 通过关闭仿真模式(因为MySQL可以正确排序所有占位符):
- 通过显式绑定和设置适当的类型(PDO::PARAM_INT):
$stm = $pdo->prepare('SELECT * FROM table LIMIT ?, ?'); $stm->bindValue(1, $limit_from,PDO::PARAM_INT); $stm->bindValue(2, $per_page,PDO::PARAM_INT); $stm->execute(); $data = $stm->fetchAll();
%
,\uu
和任何其他引擎支持的通配符,然后再将其放入查询中。@DCoder:+1,只是为了完整起见,并且因为这是一个参考问题:addcslashes($name,%\\\)代码>。谢谢,但这只是且仅限于在PDO中限制使用时?
$stm = $pdo->prepare('SELECT * FROM table LIMIT ?, ?');
$stm->bindValue(1, $limit_from,PDO::PARAM_INT);
$stm->bindValue(2, $per_page,PDO::PARAM_INT);
$stm->execute();
$data = $stm->fetchAll();