我们必须在global中定义prepared语句变量吗


Do we must define prepared statement variable in global, always?

我有下面的函数来准备、执行和返回结果。我调用它来准备插入查询,并将值绑定到它,然后返回执行的结果。但是,当我检查函数范围外受影响的行数时,它会得到-1,但我期望的记录会插入到我的表中。

function prepare_and_run($link,$query_structure){
    $stmt = mysqli_prepare($link,$query_structure);
    mysqli_stmt_bind_param($stmt, 's', 'a string value');
    mysqli_stmt_execute($stmt);
    $result=mysqli_stmt_get_result($stmt);
    if($result===false && !mysqli_errno($link)) 
        return true;
    return $result;
}
//call the function above
$link=mysqli_connect(...);
$result=prepare_and_run($link,"insert into table values(?)");
echo mysqli_affected_rows($link); // output: -1 !!!

我在代码中添加了3行,看到它是固定的:

$dpq_stmt=null;  // it is added
function prepare_and_run($link,$query_structure){
    $stmt = mysqli_prepare($link,$query_structure);
    mysqli_stmt_bind_param($stmt, 's', 'a string value');
    mysqli_stmt_execute($stmt);
    global $dpq_stmt; // it is added
    $dpq_stmt=$stmt;  // it is added
    $result=mysqli_stmt_get_result($stmt);
    if($result===false && !mysqli_errno($link)) 
        return true;
    return $result;
}
//call the function above
$link=mysqli_connect(...);
$result=prepare_and_run($link,"insert into ...");
echo mysqli_affected_rows($link); // output: 1 . it is correct

但为什么呢?我们必须在global中定义prepared语句变量吗?

我不太确定PHP,也不确定为什么您的脚本通过添加这些行来工作,但为了回答一般问题,我认为将准备好的语句声明为全局变量是不好的做法。

准备好的报表通常需要关闭;不这样做可能导致内存泄漏。全局变量可用于模块的整个范围。虽然这对于简单的脚本来说可能并不明显,但一旦代码崩溃并需要扩展,就很难跟踪代码的哪一部分使用了什么全局资源。这是并发灾难的经典配方。

显然,如果您的代码足够模块化,那么您可能真的必须将某些模块中的一些准备好的语句声明为全局语句。但当你这样做的时候,不要忘记,你需要有一种干净的方式来关闭这些资源,当你宣布它们是全球性的时,你这样做并不是因为你草率。

有点晚了,但让我们尝试帮助:如果prepare语句和绑定到prepare语句中的任何变量都没有声明在同一范围内,那么YES,则需要使用全局变量。

如果不这样做,这些变量将不会被准备好的语句看到,它将被视为本地变量,并且将被设置为NULL。