繁体   English   中英

PHP / MYSQL-使用mysql_insert_id插入多行?

[英]PHP/MYSQL - Inserting multiple rows using mysql_insert_id?

背景:

我正在从客户表单将基本客户信息上载到数据库。 当客户端单击“完成”时,输入的信息((名称城市国家等)将存储在client_info表中。

作为替代,客户端也可以将图像上传到服务器。 这些图像的信息( image_pathimage_name )然后存储在另一个单独的表中,该表称为client_images ,该表具有与client_info链接的外键

client_info表:

CREATE TABLE IF NOT EXISTS `client_info` (
  `client_id` int(11) NOT NULL AUTO_INCREMENT,
  `client_name` varchar(100) NOT NULL,
  `client_city` varchar(100) NOT NULL,
  `client_country` varchar(10) NOT NULL,
  PRIMARY KEY (`client_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10446 ;

client_images表:

CREATE TABLE IF NOT EXISTS `client_images` (
  `image_id` int(11) NOT NULL AUTO_INCREMENT,
  `image_path` varchar(100) NOT NULL,
  `image_name` varchar(100) NOT NULL,
  `client_id` int(11) NOT NULL,
  PRIMARY KEY (`image_id`),
  KEY `client_id` (`client_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=415;

问题:

我已经成功地将一行上载到client_images表。 添加多个行会导致以下错误

Cannot add or update a child row: a foreign key constraint fails (`db`.`client_images`, CONSTRAINT `client_images_ibfk_1` FOREIGN KEY (`client_id`) REFERENCES `client_info` (`client_id`) ON DELETE CASCADE ON UPDATE CASCADE) : 1452

但是,当我通过控制台添加多行和一个已经存在的client_id进行测试时,它可以很好地工作。

例:

mysql> INSERT INTO client_images (image_path, image_name, client_id) VALUES ('pathname1', 'name1', 10241);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO client_images (image_path, image_name, client_id) VALUES ('pathname2', 'name2', 10241);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO client_images (image_path, image_name, client_id) VALUES ('pathname3', 'name3', 10241);
Query OK, 1 row affected (0.00 sec)

我需要指出的是,我将其排列如下:

文件: (create_article.php)

insert_client_info($client_name, $client_city, $client_country);    

include('uploads.php');

?>

<?php mysql_close($connection); ?>

uploads.php内部,我有一个foreach循环,该循环计算将要上传的文件数量,在循环的最后,我目前具有一个功能insert_images($ image_path,$ image_name);

功能(insert_images):

function insert_images($directory_path, $image_name) {  

    global $connection;
    $client_id=mysql_insert_id();

    $query = "INSERT INTO client_images (
        image_path, image_name, client_id
    ) VALUES (
        '{$directory_path}', '{$image_name}', '{$client_id}'
    )";
$result = mysql_query($query, $connection);

if ($result) {
    // Success!
    echo "<p></p>";
    echo "Successfully uploaded the file.";
    echo "<p></p>";

} else {
    // Display error message.
    echo "<p>" . mysql_error() ." : ".mysql_errno(). "</p>";
}
return $result;
}

阅读其他类似的问题,我了解到致命弱点可能是mysql_insert_id() ,并且以某种方式使用了与foreach循环中第一个不同的另一个连接,从而导致出现上述的MYSQL错误。

谢谢/ EDZ

这部分:

$query = "INSERT INTO client_images (
        image_path, image_name, client_id
    ) VALUES (
        '{$directory_path}', '{$image_name}', '{$client_id}'
    )";

将会:

$query = "INSERT INTO client_images (
        image_path, image_name, client_id
    ) VALUES (
        '$directory_path', '$image_name', $client_id
    )";

您必须使用mysql_real_escape_string()对变量进行转义,以防止SQL注入

$client_id也是数字,因此不需要引用'$client_id'

添加多个行会导致以下错误:

最后一个插入ID是由当前MySQL会话中最新的INSERT生成的ID,该ID生成了一个自动递增的ID。

当您插入第一个图像时,最新的INSERT是client_info的图像。

但是一旦到达第二张图像,最新的INSERT就是第一张图像,因此mysql_insert_id()返回的值是不同的。 同样,每个后续的INSERT都会更改mysql_insert_id()返回的值。

您应该 foreach循环开始插入图像之前设置变量$ client_id,并将该变量传递给对insert_images()的每次调用。 在uploads.php中:

$client_id=mysql_insert_id();
foreach (...) {
    insert_images($client_id, ...);
}

将$ client_id传递为insert_images()函数的参数,而不是在函数中设置$ client_id。

function insert_images($client_id, $directory_path, $image_name) {  
    ...
}

PS:@tttony在提醒您注意SQL注入时有一个好处。

另请参阅我的演讲《 SQL注入的神话和谬论》 ,或我的《 SQL反模式:避免数据库编程的陷阱》一书中有关SQL注入的章节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM