为什么这个 mysqli 准备好的插入语句不能处理多个值?

Why won't this mysqli prepared insert statement work with multiple values?

提问人:VCS-Jacob 提问时间:7/26/2022 最后编辑:BarmarVCS-Jacob 更新时间:7/26/2022 访问量:117

问:

我在使用准备好的插入语句时遇到问题。 该脚本应该读取.txt文件的内容,并将数据插入到数据库中的相应列中。这是我在尝试插入时不断遇到的错误。

致命错误:未捕获mysqli_sql_exception:列“propertyName”不能在 C:\xamppp\htdocs\php7\propertyUpload.php:19 中为空 堆栈跟踪:#0 C:\xamppp\htdocs\php7\propertyUpload.php(19):mysqli_stmt_execute(Object(mysqli_stmt)) #1 {main} 在第 19 行的 C:\xamppp\htdocs\php7\propertyUpload.php 中抛出

顺便说一句:.txt的内容位于一个数组中,如下所示:

TEST1000, PROPERTY1
TEST2000, PROPERTY2
TEST3000, PROPERTY3
<?php
    include 'config.php';
    if (empty($_SERVER['HTTP_REFERER']))
    {
        header('Location: ""');
        exit;
    }
    ini_set("auto_detect_line_endings", true);
    $open = fopen('test22-7-18.txt','r');
    while (!feof($open))
    {
        $getTextLine = fgets($open);
        $explodeLine = explode(",",$getTextLine);
        list($accountCode,$propertyName) = $explodeLine;
        $sql = "INSERT INTO properties (accountCode, propertyName) values(?, ?)";
        if ($stmt = mysqli_prepare($link, $sql))
        {
            mysqli_stmt_bind_param($stmt,"ss",$accountCode, $propertyName);
            (mysqli_stmt_execute($stmt));
        }
    }
    fclose($open);
    
     ?>

但是,当我将代码更改为此时,内容将正确插入:

<?php
include 'config.php';
if (empty($_SERVER['HTTP_REFERER']))
{
    header('Location: ""');
    exit;
}
ini_set("auto_detect_line_endings", true);
$open = fopen('test22-7-18.txt','r');
while (!feof($open))
{
    $getTextLine = fgets($open);
    $explodeLine = explode(",",$getTextLine);
    list($accountCode,$propertyName) = $explodeLine;
    $sql = "INSERT INTO properties (accountCode, propertyName) values(? , '$propertyName')";
    if ($stmt = mysqli_prepare($link, $sql))
    {
        mysqli_stmt_bind_param($stmt,"s",$accountCode);
        (mysqli_stmt_execute($stmt));
    }
}
fclose($open);
?>

第二个脚本是否对 SQL 注入开放,如果不能,我可以保持原样吗?有谁知道为什么我不能让第一个语句起作用?

php mysqli 预备语句

评论

0赞 Barmar 7/26/2022
为什么 while(!feof(file)) 总是错的
0赞 Dharman 7/26/2022
是的,第二个示例对 SQL 注入开放,您不能保持这样。
0赞 ADyson 7/26/2022
也许文件中的某些行包含该属性的 null 值?在第二个示例中,它们将作为空字符串插入
0赞 Dharman 7/26/2022
为什么要使用已弃用的指令?auto_detect_line_endings
0赞 VCS-Jacob 7/26/2022
哇,我很欣赏所有的快速回复!我会寻找auto_detect_line_endings的替代方案。

答:

2赞 Barmar 7/26/2022 #1

的值是 ,但表中的列是声明的。$propertyNamenullpropertyNameNOT NULL

这很可能是由于您错误地使用了 ,这导致您在文件末尾调用额外的时间。这将设置为 ,并返回 ,因此设置为(可能还会出现“未定义的偏移量”警告,表明您没有打印)。while(!feof($open))fgets()$getTextLinefalseexplode()[""]$barnull

使用字符串替换时,将扩展为空字符串,因此在该行中插入空字符串。这样可以防止错误,但您可能没有得到所需的结果,因为它会插入一个带有空值的额外行。null

while ($getTextLine = fgets())

作为您的循环条件,而不是while (!feof($getTextLine))