And*_*ong 5 php mysql pdo join
背景
您好,我正在开发PHP和MySQL的实验/教育工具.我是SQL的新手,但我想从一开始就以正确的方式做事.我正在为所有变量替换使用PDO预处理语句,并且可以在任何地方进行反向操作(因此,据我所知,它不能移植到非MySQL数据库).关于我的问题,我有一个关于如何前进的想法,但是我需要花费几个小时来实现(我甚至对SQL的语法都是新的),所以同时我认为我先创建一个问题万一有人可以喊叫,"这不是办法!" 并节省我几个小时的努力.
问题
我想创建一个用户可以从下拉菜单中选择的界面:
A,A.x和A.y,B,B.z和B.y,在提交代码将执行一个内部联接,每个字段分别匹配,例如A.x = B.z,A.y = B.y等等,并返回所有匹配的行.
我的计划只是生成一个INNER JOINSQL语句,循环遍历字段并插入占位符(?),绑定相应的参数,最后执行语句.
有更简单的方法吗?有没有更好的方法呢?这会以某种方式被利用吗?
非常感谢,提前.如果没有人在我结束时做出回应(可疑),我会发布我的解决方案.
杂项.
假设我将验证
A和之间选择相同数量的字段B,并且字段名称不必相同:它们将按顺序匹配.(请指出我可能不知道的任何其他细节!)
最终,目标是将这些选择本身保存在"设置"表中.实际上,用户创建他们希望每次回来时都能看到的"视图".
你做得太正确了,以至于我真的感到内疚指出你做错了!:)
您只能使用准备好的语句来参数化字段值,而不能使用 SQL 标识符,例如列名或表名。因此,您将无法通过准备好的语句参数将等传递到您的A.x条件中:您必须做一些感觉非常错误的事情,并将它们直接连接到您的 SQL 字符串中。B.zJOIN
然而,一切并没有失去。按照一些模糊的偏好顺序,您可以:
向用户提供一个选项列表,您随后可以从中重新组装 SQL:
<select name="join_a">
<option value="1">x</option>
<option value="2">y</option>
</select>
<select name="join_b">
<option value="1">z</option>
<option value="2">y</option>
</select>
Run Code Online (Sandbox Code Playgroud)
然后你的表单处理程序:
switch ($_POST['join_a']) {
case 1: $acol = 'x'; break;
case 2: $acol = 'y'; break;
default: die('Invalid input');
}
switch ($_POST['join_b']) {
case 1: $bcol = 'z'; break;
case 2: $bcol = 'y'; break;
default: die('Invalid input');
}
$sql .= "FROM A JOIN B ON A.$acol = B.$bcol";
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是,如果不损害 PHP(在这种情况下,您将面临比 SQL 注入更大的担忧),任意 SQL 绝对无法进入您的 RDBMS。
确保用户输入与预期值之一匹配:
<select name="join_a">
<option>x</option>
<option>y</option>
</select>
<select name="join_b">
<option>z</option>
<option>y</option>
</select>
Run Code Online (Sandbox Code Playgroud)
然后你的表单处理程序:
if (!in_array($_POST['join_a'], ['x', 'y'])
or !in_array($_POST['join_b'], ['z', 'y']))
die('Invalid input');
$sql .= "FROM A JOIN B ON A.$_POST[join_a] = B.$_POST[join_b]";
Run Code Online (Sandbox Code Playgroud)
这种方法依赖于 PHP 的in_array安全功能(并且还向用户公开您的基础列名称,但考虑到您的应用程序,我怀疑这是一个问题)。
执行一些输入清理,例如:
mb_regex_encoding($charset); // charset of database connection
$sql .= 'FROM A JOIN B ON A.`' . mb_ereg_replace('`', '``', $_POST['join_a']) . '`'
. ' = B.`' . mb_ereg_replace('`', '``', $_POST['join_b']) . '`'
Run Code Online (Sandbox Code Playgroud)
虽然我们在这里引用用户输入并替换用户逃避该引用的任何尝试,但这种方法可能充满各种缺陷和漏洞(在 PHPmb_ereg_replace函数或 MySQL 对引用标识符中特制字符串的处理中)。
如果可能的话,最好使用上述方法之一来避免将用户定义的字符串完全插入到 SQL 中。
| 归档时间: |
|
| 查看次数: |
187 次 |
| 最近记录: |