【发布时间】:2011-10-21 10:10:03
【问题描述】:
更新:请见下文;我已经删除了所有抽象并创建了一个普通的 PHP 脚本,但仍然得到同样的错误。请参阅下面的“另一个更新”以获取更多信息...
原帖:我有一个通过数据库抽象层正确形成的查询。查询如下:
SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id,
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = 5c9_dpd_users.cms_usergroup_id
ORDER BY username asc
如果我生成相同的查询,但将其作为准备好的语句运行,该语句将 WHERE 子句的第二个操作数参数化,如下所示,我会得到不正确的结果。我确信该语句本身是正确的,并且我正在运行 MySQLi prep。语句以正确的顺序运行。准备好的语句查询如下:
SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id,
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc
此查询似乎将参数化的5c9_dpd_users.cms_usergroup_id 转换为简单的“5”,因为运行该查询会从SELECT 子句中检索正确的列,但对于所有结果返回相同的usergroup_name - 此用户组名称匹配具有5c9_dpd_usergroups_cms.id 或5 的结果的用户组名称。
我正在动态绑定参数 (call_user_func_array())。在本例中,我告诉它将? 参数绑定为i。我想也许这使它出于某种原因将5c9_dpd_users.cms_usergroup_id 转换为5,但我已经尝试了所有其他三种数据类型(s、b 和d),但没有运气。
注意:我多次使用我的数据库抽象层都没有问题,尽管这是它运行连接的第一个实例(它是最近才开发的)。重申一下,如果没有参数化,查询通过 PHP 和 MySQL 控制台返回正确的结果,但如果通过 PHP 准备语句函数给出?,则结果不正确,如上所述。
如果有人能提供帮助,我将不胜感激。我整晚都在谷歌上搜索这件事的帮助,我在任何地方都找不到任何类似的实例。谢谢。
编辑(提供 PHP 代码):
$stmt->select_prep(array('users.id', 'users.username', 'users.cms_usergroup_id', 'usergroups_cms.usergroup_name', 'users.email'), array('users'));
$stmt->left_join_prep('usergroups_cms');
$stmt->on_prep('usergroups_cms.id', '=', 'users.cms_usergroup_id', 'i');
$stmt->order($column, $asc_desc);
$stmt->execute_prep();
查询现在已执行,我所要做的就是调用 $stmt->fetch_prep(),这是一个基本上检索结果集的包装方法。此客户端代码生成的查询是上面给出的第二个 - 我作为示例给出的参数化 - 查询。
我在 $stmt->execute_prep() 方法中打印了一些调试代码,绑定到查询的参数正确显示为:
Array
(
[0] => i
[1] => 5c9_dpd_users.cms_usergroup_id
)
这意味着它将一个参数(键 1)绑定为 int(键 0)。我也尝试将它绑定为字符串,double 和 blob,但没有效果。
另一个更新:
我创建了一个测试脚本来完全移除我的数据库抽象层,结果是一样的:没有返回cms用户组名。这是脚本:
<?php
$mysqli = new mysqli('localhost', 'root', '', 'frame');
$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id,
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email
FROM ac9_dpd_users
LEFT JOIN ac9_dpd_usergroups_cms
ON ac9_dpd_usergroups_cms.id = ?
ORDER BY username asc";
$stmt = $mysqli->prepare($q);
$stmt->bind_param('i', $param);
$param = 'ac9_dpd_users.cms_usergroup_id';
$stmt->execute();
$stmt->bind_result($a, $b, $c, $d, $e);
while ($stmt->fetch()) {
echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>";
}
$stmt->close();
unset($mysqli);
?>
输出:
id: 7
un: ADD
id: 1
cms name:
email: test@test.com
id: 1
un: New User
id: 2
cms name:
email: test@test.com
等
【问题讨论】:
-
php.net/manual/en/mysqli-stmt.bind-param.php 那里有一个关于将 call_user_func_array() 与绑定参数结合使用到语句的警告。您认为这可能会影响您吗?
-
我不这么认为,因为传递非引用参数会导致致命/警告错误(我忘记了,确切地说)。
-
你能展示一些你用来绑定参数的代码吗?谁知道呢,你可能错过了那里的东西。
-
我会展示我能做的;然而,这一切都是抽象的,所以恐怕不会完全清楚......
-
5 在某种程度上是第一个用户组 ID 吗?好像是设置了一次就没有修改了?
标签: php mysql join mysqli prepared-statement