3

我希望我的 PHP Web 应用程序的用户能够将列插入到某些表中,而无需具备 SQL 知识的人。最好的方法是什么,显然 SQL 注入和 id-10-t 错误是一个问题。

我可以用吗

sql = 'ALTER TABLE table_name ADD ? ?'

然后将“new_col”和“varchar(100)”作为字符串传入?或者这超出了 PDO 的能力范围吗?

4

3 回答 3

1

不幸的是,您不能将ALTER TABLE语句中的列名或属性与 PDO 参数绑定。相反,为了防止 SQL 注入,我建议根据只允许字母、数字和下划线的正则表达式验证列名,并确保在语句中反引用列名。

if (!preg_match('/^[a-z0-9_]+$/i', $column_name)) {
  // Fail!!! submitted column name doesn't match regex
}
  • ^= 字符串的开头
  • [a-z0-9_]+= 一个或多个字母、数字、下划线
  • $= 字符串结尾
  • /i= 不区分大小写

接下来,要验证列的数据类型,您应该只允许一组特定的选项,并使用数组验证它们。这称为白名单

// Allowed types:
$acceptable_types = array('VARCHAR(200)', 'VARCHAR(10)', 'INT', 'FLOAT', 'etc...');
if (!in_array($column_data_type, $acceptable_types)) {
  // Fail!!! Invalid type submitted
}

上述选项最好通过<select>列表之类的方式提供。您还可以指定其他选项,例如NULL / NOT NULL复选框输入来构造ALTER TABLE语句。

// Only after everything is successfully validated:
$sql = "ALTER TABLE `tablename` ADD `$valid_column_name` $valid_column_datatype $NULL_option";
于 2012-12-18T02:11:42.570 回答
0

您可能需要考虑附加列的元表。

如果您为每种汽车设置了数据(如整备重量、高度等),然后是用户添加的其他专门信息,但不适用于每辆汽车,您可以将其存储在单独的表中,如下所示:

CAR TABLE: id name 路边重量身高 ...

META TABLE: id (主键) car_id (外键) data_name data_value

Meta 表与 Car 表是一对多的关系。如果用户想要为 2 辆特定汽车添加一列以记录“镜子大小”或其他内容,则 Meta 表将获得两条记录,其中包含自动 id、汽车 id、“镜子大小”和大小。

如果您想要一组数据名称列表,您可以使用第三个表,并让元表存储 id、car_id 和 data_id。

只是一个想法!

于 2014-02-04T21:16:37.350 回答
-2

最好的方法显然是不允许用户能够将列插入某些表中。特别是不需要具有 SQL 知识的人。
这是违反所有规则的。

这样一个相当基本的问题与极其不寻常的目标相结合总是有一种糟糕的设计的味道。

所以,正确的答案是:

  1. 放弃这种用户添加列的想法。这真的很奇怪。
  2. 开始另一个问题,解释你的总体目标,描述用例并寻求适当的解决方案。
于 2012-12-18T05:34:06.710 回答