SQL 的更新请求在从 PHP 查询时失败,但在 SQL 命令行上运行良好

UPDATE request for SQL fails on querying from PHP but works good on SQL command line

我正在开发一个库存维护页面。我遇到了一个奇怪的问题。当我 运行 PHP 到 AJAX 时,除了 mysqli_query 部分外,一切正常。

<?php
include 'dbconnector.php';
$item_code  =   json_decode(filter_input(INPUT_POST,'icode')) or die('line1');
$item_count =   json_decode(filter_input(INPUT_POST,'icount')) or die('line2');

$sql_string =   '';

for($i=0; $i<sizeOf($item_code); $i++)
{
    $sql_string.=" UPDATE stock_main SET iSTOK=".$item_count[$i]." WHERE iCODE=\"".$item_code[$i]."\"; ";
}

    echo $sql_string;
$query_sql  =   mysqli_query($dbconnector,$sql_string);
if($query_sql>0)
    echo 'SUCCESS';
else
    echo mysqli_error($query_sql); 
?>

问题是当我 运行 对单个语句它工作正常。当连接多个语句时,它 returns 为 false。但是多语句场景在 phpMyAdmin 命令行中运行良好。当试图检查它为什么失败时 mysqli_error returns 说参数应该是 mysqli 类型但它是布尔值。

mysqli_query函数不支持一次查询多个sql。推荐使用mysqli_multi_query()函数;

你的代码行将是这样的:-

$query_sql = mysqli_multi_query($dbconnector, $sql_string);

为了使用多个查询,可以使用

mysqli_multi_query ( mysqli $link , string $query )

来自 PHP 手册:

The API functions mysqli_query() and mysqli_real_query() do not set a connection flag necessary for activating multi queries in the server. An extra API call is used for multiple statements to reduce the likeliness of accidental SQL injection attacks. An attacker may try to add statements such as ; DROP DATABASE mysql or ; SELECT SLEEP(999). If the attacker succeeds in adding SQL to the statement string but mysqli_multi_query is not used, the server will not execute the second, injected and malicious SQL statement.

所以你的代码应该是:

<?php
include 'dbconnector.php';
$item_code  =   json_decode(filter_input(INPUT_POST,'icode')) or die('line1');
$item_count =   json_decode(filter_input(INPUT_POST,'icount')) or die('line2');

$sql_string =   '';

for($i=0; $i<sizeOf($item_code); $i++)
{
    $sql_string.=" UPDATE stock_main SET iSTOK=".$item_count[$i]." WHERE iCODE=\"".$item_code[$i]."\"; ";
}

    echo $sql_string;
$query_sql  =   mysqli_multi_query($dbconnector, $sql_string);
if($query_sql>0)
    echo 'SUCCESS';
else
    echo mysqli_error($query_sql); 
?>

Php.net Multiple Statements

上查看更多信息

澄清一下

正如其他人所建议的那样,从 SQL 注入攻击的角度来看,最好使用准备好的语句,因为数据将被自动格式化和过滤。 但是,这并不意味着普通查询是完全糟糕的,只要您采取所有必要的步骤来确保您受到保护。

警告:您对SQL Injections and should use parameterized prepared statements instead of manually building your queries. They are provided by PDO or by MySQLi. Never trust any kind of input! Even when your queries are executed only by trusted users, you are still in risk of corrupting your data. Escaping is not enough!

持开放态度

不要按照其他答案的建议使用 mysqli_multi_query(),因为它只会让您更容易受到 SQL 注入。你真的不需要这个功能!使用准备好的语句,不仅更简单、更安全,而且更不容易出错。

// Switch error reporting!
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
include 'dbconnector.php';
$item_code = json_decode(filter_input(INPUT_POST, 'icode')) or die('line1');
$item_count = json_decode(filter_input(INPUT_POST, 'icount')) or die('line2');

// Prepare query
$stmt = $dbconnector->prepare('UPDATE stock_main SET iSTOK=? WHERE iCODE=?');

// bind and execute multiple times
for ($i = 0; $i < sizeof($item_code); $i++) {
    $stmt->bind_param('ss', $item_count[$i], $item_code[$i]);
    $stmt->execute();
}