我遇到了一个小问题。我目前正在开发一个需要在 MySQL 中使用动态表名的应用程序。
基本上,我有一个根据多种因素(流派、播放长度、发行日期等)从数据库中选择专辑的过程——这个过程的一部分允许用户创建一堆自定义过滤器..
自定义过滤器向用户返回符合该选择标准的所有相册的计数。然后将这些专辑的 ID 存储在具有随机生成的哈希/序列号的表中(例如 albumSelect_20880f9c05d68a)
我这样做是因为我不想在一个字段中存储一个巨大的逗号分隔列表(真的很傻)——而且我不想像这样将一组值发送到我的 HTML 中的隐藏字段只会增加数据吞吐量(一次可能有数千行)
在 CodeIgniter 中,我使用查询绑定(bind)来生成我的 SQL 查询,如下所示:
select * from artists where artistName = ? AND albumTitle = ?
当我参数化查询时,查询会自动转义
$query = $this->db->query($sql,array("Singer","Album"));
棘手的部分来了
如果我将查询写成这样:
$sql = "select albumid from albums where albumid in (select albumid from albumSelect_?)";
$this->db->query($sql,array('20880f9c05d68a'));
结果查询变为:
select `albumid` from `albums` where `albumid` in (select `albumid` from `albumSelect_'20880f9c05d68a'`)
确实如此,但显然查询无效..
编辑:更多信息
查询可以是更大查询的一部分,具体取决于用户选择的条件。例如
$sql = "select albumid from albums where albumid in(select albumid from tags where tag = ?) AND albumid in(select albumid from albumSelect_?)";
我只是想知道是否有办法让它工作,或者是否有人可以提出更好的替代方案。表名的串联显然不是一个选项。
提前致谢!
戴夫
最佳答案
转义机制仅适用于数据字符串,不适用于模式名称。换句话说,只针对表的内容,而不针对其结构。因此,您要么必须自己将字符串粘贴到查询中,要么避免以这种方式使用表。查询模板的 ?
帮不了你。
如果将字符串粘贴到表名中,则可以使用常用的 PHP 字符串连接机制。您应该特别确定根据适当严格的正则表达式检查字符串,以避免 SQL 注入(inject)。确保您确实只粘贴了一个您生成的格式的随机字符串,没有其他内容。
作为替代方案,您可以有一个包含所有选择的大表,并使用一个额外的列来保存您的标识哈希,或使用其他一些合适的键来标识单个选择。这样,您就不必在正常操作期间修改数据库架构。我相信包括我在内的大多数开发人员都宁愿避免通过程序代码进行此类修改。良好的数据库设计适用于固定模式。
关于php - 使用 Codeigniter 在 MySQL 中安全地转义动态表名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11529763/