关于Doctrine-如何打印出真正的sql,而不仅仅是准备好的语句?和怎么打印sql语句的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于DoctrineRawSQL和准备好的语句、mys
关于Doctrine - 如何打印出真正的 sql,而不仅仅是准备好的语句?和怎么打印sql语句的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Doctrine Raw SQL和准备好的语句、mysqli准备好的语句num_rows返回0,而查询返回大于0、PDO 准备好的语句是否足以防止 SQL 注入?、PDO 准备好的语句:获取 NULL 而不是预期的结果等相关知识的信息别忘了在本站进行查找喔。
本文目录一览:- Doctrine - 如何打印出真正的 sql,而不仅仅是准备好的语句?(怎么打印sql语句)
- Doctrine Raw SQL和准备好的语句
- mysqli准备好的语句num_rows返回0,而查询返回大于0
- PDO 准备好的语句是否足以防止 SQL 注入?
- PDO 准备好的语句:获取 NULL 而不是预期的结果
Doctrine - 如何打印出真正的 sql,而不仅仅是准备好的语句?(怎么打印sql语句)
我们正在使用 Doctrine,一个 PHP ORM。我正在创建这样的查询:
$q = Doctrine_Query::create()->select(''id'')->from(''MyTable'');
然后在函数中添加各种 where 子句和适当的东西,像这样
$q->where(''normalisedname = ? OR name = ?'', array($string, $originalString));
稍后,在execute()
该查询对象之前,我想打印出原始 SQL 以检查它,然后执行以下操作:
$q->getSQLQuery();
但是,这只会打印出准备好的语句,而不是完整的查询。我想看看它发送到 MySQL 的内容,但它打印出一个准备好的语句,包括?
‘s.
有什么方法可以查看“完整”查询吗?
答案1
小编典典Doctrine 没有向数据库服务器发送“真正的 SQL 查询”:它实际上是使用准备好的语句,这意味着:
- 发送声明,以便准备好(这是由返回的内容
$query->getSql()
) - 然后,发送参数(由返回
$query->getParameters()
) - 并执行准备好的语句
这意味着 PHP 端永远不会有“真正的”SQL 查询——因此,Doctrine 无法显示它。
Doctrine Raw SQL和准备好的语句
我有一个使用准备好的语句的Doctrine_RawSql查询。但是,当生成SQL查询时,它们似乎会被忽略。但是,如果我忽略了标记值,则会得到关于不匹配的绑定变量数量的异常(因此,至少是试图将它们包含在内)。
如果我内联包含这些值,Doctrine是否在幕后做任何事情以防止SQL注入?
这是我的代码:
public function sortedPhotogsByLocation($location){ $q = new Doctrine_RawSql(); $result = $q->select(''{p.*}'') ->from(''photographers p'') ->addComponent(''p'', ''Photographer'') ->where(''p.city_id = ?'', $location->id) ->orderBy(''CASE WHEN p.lname < "?%" THEN 1 ELSE 0 END, p.lname ASC'', $location->photographer_sort) ->execute(); return $result;}
这提供了以下SQL输出:
SELECT * FROM photographers p WHERE p.city_id = ? ORDER BY CASE WHEN p.lname < "?%" THEN 1 ELSE 0 END, p.lname ASC
编辑:上的属性$location
已正确设置。如果我对参数进行硬编码:
->where(''p.city_id = ?'', 5)
我遇到了相同的问题,即令牌没有被替换。
答案1
小编典典我对Doctrine_RawSql并不完全熟悉,但占位符应单独使用,而不是“?%”?并在传递的变量上添加%。看一下示例#6。
mysqli准备好的语句num_rows返回0,而查询返回大于0
我有一个简单的准备好的声明,用于实际存在的电子邮件:
$mysqli = new mysqli("localhost", "root", "", "test");if (mysqli_connect_errno()) { printf("Connect failed: %s\n", mysqli_connect_error()); exit();}$sql = ''SELECT `email` FROM `users` WHERE `email` = ?'';$email = ''example@hotmail.com'';if ($stmt = $mysqli->prepare($sql)) { $stmt->bind_param(''s'', $email); $stmt->execute(); if ($stmt->num_rows) { echo ''hello''; } echo ''No user'';}
结果:No user
在应回显时回显hello
我在控制台中运行了相同的查询,并使用与上述相同的电子邮件得到了结果。
我也使用一个简单的mysqli查询进行了测试:
if ($result = $mysqli->query("SELECT email FROM users WHERE email = ''example@hotmail.com''")) { echo ''hello'';}
结果:我所期望的 hello
还$result
的num_rows
是1。
为什么准备的陈述 num_row
不大于0?
答案1
小编典典当您通过mysqli执行一条语句时,直到您获取结果,结果才真正在PHP中出现-
结果由数据库引擎保存。因此,mysqli_stmt
对象无法知道执行后立即有多少结果。
像这样修改您的代码:
$stmt->execute();$stmt->store_result(); // pull results into PHP memory// now you can check $stmt->num_rows;
见手册
这不适用于您的特定示例,但是如果您的结果集很大,$stmt->store_result()
则会消耗大量内存。在这种情况下,如果您关心的只是弄清楚是否至少返回了一个结果,请不要存储结果。相反,只需检查结果元数据是否不为空:
$stmt->execute();$hasResult = $stmt->result_metadata ? true : false;
见手册
PDO 准备好的语句是否足以防止 SQL 注入?
假设我有这样的代码:
$dbh = new PDO("blahblah");
$stmt = $dbh->prepare('SELECT * FROM users where username = :username');
$stmt->execute( array(':username' => $_REQUEST['username']) );
PDO 文档说:
准备好的语句的参数不需要引用;司机为您处理。
这真的是我需要做的一切来避免 SQL 注入吗? 真的那么容易吗?
如果它有所作为,您可以假设 MySQL。另外,我真的只是对使用准备好的语句来对抗 SQL 注入感到好奇。在这种情况下,我不关心 XSS 或其他可能的漏洞。
PDO 准备好的语句:获取 NULL 而不是预期的结果
您似乎发现了 MariaDB SQL 优化器的错误。请尽早向他们提交错误报告。
该问题与 PDO 无关。您看到不同结果的原因是 PDO 默认将所有值绑定为字符串。当您将其绑定为字符串时,会正确评估 WHERE
子句中的比较。当您将值转换为整数或使用文字 1 时,优化器会将其与 product.id
进行比较,而不是与 stock.product
进行比较。不太确定这里内部发生了什么,但显然使用整数时行为是错误的。您可以在 https://dba.stackexchange.com/ 上询问是否有人对此行为有解释,但这很可能需要由 MariaDB 团队作为错误解决。
Here is an online reproducible version of this bug.
今天的关于Doctrine - 如何打印出真正的 sql,而不仅仅是准备好的语句?和怎么打印sql语句的分享已经结束,谢谢您的关注,如果想了解更多关于Doctrine Raw SQL和准备好的语句、mysqli准备好的语句num_rows返回0,而查询返回大于0、PDO 准备好的语句是否足以防止 SQL 注入?、PDO 准备好的语句:获取 NULL 而不是预期的结果的相关知识,请在本站进行查询。
本文标签: