【问题标题】:explode does not work爆炸不起作用
【发布时间】:2014-05-05 03:20:03
【问题描述】:

此代码用于插入特定规格的单元。 例如,如果规格是长度,那么单位是厘米、米和毫米。

当我尝试用逗号读取单个文本字段中的所有单位时,在 PHP 中尝试用逗号分解这些单位。 但是当我提交表单时,只有第一个单元被保存到 DB。

这是我的数据库结构:

CREATE TABLE IF NOT EXISTS `tbl_unit` (
  `unit_id` varchar(5) NOT NULL,
  `unit_name` varchar(50) NOT NULL,
  `specification_id` int(11) NOT NULL,
  PRIMARY KEY (`unit_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

这是我的代码:

<?php
include("../config.php");
$uid=$_POST['unitid'];
$unit=$_POST['unitname'];
$spec=$_POST['specification'];

$arr1 = explode(',',$unit);
$size=count($arr1);

for($i=0;$i<$size;$i++)
{
  mysql_query("insert into tbl_unit values('".$uid."','$arr1[$i]','".$specification."')");

}
 header('Location:addunit.php');
 ?>

让我感到困惑的是,当我尝试分别插入 $arr1[0]$arr1[1]$arr1[2] 时,值被保存了。我认为 for 循环只执行一次。 for循环有什么问题?

【问题讨论】:

  • 您的代码容易受到 SQL 注入的攻击。你应该阅读how to prevent them in PHP
  • 欢迎来到 Stack Overflow!还有the mysql extension is deprecated。您应该切换到MySQLiPDO 并使用准备好的语句。
  • var_dump($arr1); 看到爆炸有效,我不会盲目爆炸。我会考虑进行 strpos 检查,例如if (strpos($unit, ',' ) !== FALSE) { echo "INPUT IS READY TO EXPLODE"; }。您不应该在循环中查询,为什么不检查查询的返回值(请参阅php.net/mysqli_query)...

标签: php loops for-loop explode


【解决方案1】:

问题是unit_id 是您表中的主键,但您正试图为此列插入多个具有相同值的记录。每次循环时,您使用相同的 unit_id 值插入,但使用不同的 unit_name 值。只要unit_id 是主键(或唯一键),您就不能这样做。

【讨论】:

  • thnx 很多.. :) 我明白了
【解决方案2】:

您对 unit_id 有一个“主键”约束,因此第一个插入成功,但所有后续插入都失败。

我可以在这里指出许多其他事情,但我没有完整的了解,我只是列出一些主要的:

1) 在 mysql 中,最好使用 int 主键,因此即使您不使用它,也最好显式地拥有这样的列。如果您想强制执行,作为 varchar 的“unit_id”列仍然可以具有“唯一键”约束。

2) 如果您对“unit_id”有唯一约束,您将不得不重新考虑您的表规范。关于如何捕获多个单位。也许它应该在没有唯一约束的情况下被索引?

3) 在将 $_POST 的输入插入表之前,您没有对其进行转义或清理 - 使其容易受到 SQL 注入攻击

4) 根据数组的大小,您可以执行“批量插入”而不是为每个插入循环 - 即提供多个行值的单个 mysql inset 调用。

5) 'explode()' 上的小事 - 它对空字符串有非常微妙的行为,所以最好检查一下(可能作为第 3 点中提到的数据清理检查的一部分) - 例如:

php -r '$a = explode(",", ""); var_dump($a);'

array(1) {
  [0]=>
  string(0) ""
}

【讨论】:

  • 谢谢建议.. :)
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 2011-10-05
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多