Php 环形预制桩

Php 环形预制桩,php,mysql,mysqli,Php,Mysql,Mysqli,我有以下代码: try { if(!($stmt = $conn["DB"]->prepare('CALL `central`.`permissions_edit`(?,?,?,?,?);'))) { $rtn["Errors"][] = "permissions_edit Prepare failed: (" . $conn["DB"]->errno . ") " . $conn["DB"]->error; } else{

我有以下代码:

try
{
    if(!($stmt = $conn["DB"]->prepare('CALL `central`.`permissions_edit`(?,?,?,?,?);')))
    {
        $rtn["Errors"][] = "permissions_edit Prepare failed: (" . $conn["DB"]->errno . ") " . $conn["DB"]->error;
    }
    else{
        foreach ($data as $user => $areas) {
            foreach ($areas as $area => $access) {
                foreach ($access as $acc => $active) {
                    if($active != "U")
                    {
                        if(!($stmt->bind_param(
                            'siiis',
                            $key,
                            $user,
                            $area,
                            $acc,
                            $active
                        )))
                        {
                            $rtn["Error"][] = "permissions_edit Bind failed: (" . $conn["DB"]->errno . ") " . $conn["DB"]->error;
                        }
                        else if(!($stmt->execute()))
                        {
                            $rtn["Errors"][] = "permissions_edit Execute failed: (" . $conn["DB"]->errno . ") " . $conn["DB"]->error;
                        }
                        else if($res = $stmt->get_result())
                        {
                            if ($row = $res->fetch_assoc())
                            {

                                if(isset($row["Success"]) && $row["Success"] )
                                {
                                    $rtn["Results"][]= "user=$user areas=$area access=$acc active=$active Message=" . $row["Msg"];
                                }
                                else
                                {
                                    $rtn["Success"] = false;
                                    $rtn["Errors"][]= "user=$user areas=$area access=$acc active=$active Message=" . $row["Msg"];                   
                                }
                            }

                        }
                        else
                        {
                            $rtn["Errors"][] = "permissions_edit Get failed: (" . $conn["DB"]->errno . ") " . $conn["DB"]->error;
                        }

                    }
                    else
                        $rtn["Results"][]= "user=$user areas=$area access=$acc active=$active Message=Unchanged";
                }
            }
        }
    }


}
catch(Exception $e)
{
    $rtn["Errors"][] = "permissions_edit Error(" . $conn["DB"]->errno . "): " . $conn["DB"]->error;
}
在循环重复1-2次的情况下使用此代码非常有效 但是,如果使用循环重复两次以上的代码,则会导致对PHP的POST终止而没有响应

并在MySql日志中生成以下内容:

2017-03-03T16:47:49.284972Z 450[注]中止了450到db的连接: “中心”用户:“用户名”主机:“本地主机”(读取时出错) 通信数据包)

2017-03-03T16:47:49.582165Z 451[注]中止 连接451到db:'central'用户:'username'主机:'localhost' (读取通信数据包时出错)

所以问题是我做错了什么

注意 我试着加上

$res->free();
$stmt->close();
这就导致了

包坏了。预期1人收到7人。数据包大小=7

mysqli_stmt::execute():MySQL服务器已离开

mysqli_stmt::execute():读取结果集的头时出错

从info.php

PHP Version 5.6.27

mysqli
MysqlI Support  enabled
Client API library version  mysqlnd 5.0.11-dev - 20120503 - $Id: 76b08b24596e12d4553bd41fc93cccd5bac2fe7a $
Active Persistent Links     0
Inactive Persistent Links   0
Active Links    0
Directive   Local Value Master Value
mysqli.allow_local_infile   On  On
mysqli.allow_persistent On  On
mysqli.default_host no value    no value
mysqli.default_port 3306    3306
mysqli.default_pw   no value    no value
mysqli.default_socket   no value    no value
mysqli.default_user no value    no value
mysqli.max_links    Unlimited   Unlimited
mysqli.max_persistent   Unlimited   Unlimited
mysqli.reconnect    Off Off
mysqli.rollback_on_cached_plink Off Off

您可以看到这个错误是由什么引起的

如果客户机成功连接,但后来断开连接不正确,或 如果终止,服务器将增加中止的\u客户端状态 变量,并将中止的连接消息记录到错误日志中。这个 原因可能是以下任何一种:

  • 客户端程序在退出之前没有调用mysql\u close()

  • 客户端睡眠时间超过了等待超时时间或 交互\u超时时间秒,无需向服务器发出任何请求 服务器

  • 客户端程序在数据传输过程中突然终止。

但是,我认为在循环内部使用bind_param不是好的做法,因为它应该在循环之前只使用一次。
第二个注意事项是,即使出现错误,也要确保关闭连接。

问题是您需要调用
$conn[“DB”]->next_result()

这是一个整洁的版本,可以工作

$stmt = $conn["DB"]->prepare('CALL `central`.`permissions_edit`(?,?,?,?,?);');
$stmt->bind_param('siiis', $key, $user, $area, $acc, $active);

foreach ($data as $user => $areas) {
    foreach ($areas as $area => $access) {
        foreach ($access as $acc => $active) {
            if($active == "U")
            {
                $rtn["Results"][]= "user=$user areas=$area access=$acc active=$active Message=Unchanged";
                continue;
            }
            $stmt->execute();
            $row = $stmt->get_result()->fetch_assoc();
            if(!empty($row["Success"]))
            {
                 $rtn["Results"][]= "user=$user areas=$area access=$acc active=$active Message=" . $row["Msg"];
            }
            else
            {
                 $rtn["Success"] = false;
                 $rtn["Errors"][]= "user=$user areas=$area access=$acc active=$active Message=" . $row["Msg"];
            }
            $conn["DB"]->next_result();
        }
    }
}

我猜对服务器的请求太多了,这可能是造成此问题的原因…从编辑我猜此线程可能会有帮助,正如您从错误中看到的,它是一个本地主机数据库,只有我使用它,因此,当前应该只有该命令正在访问它,并且这些命令应该是连续的,而不是同时的是…但是线程中有一些解决方案,您可以尝试..您还尝试启用重新连接属性..不幸的是,您的推测都与所问的问题无关。真的!!既然我的推测与问题无关,那么为什么你的答案会在循环外包含bind_param呢?因为运行一次是明智的,但是调用一个与问题无关的循环=>并没有坏处。太多的代码从来都不是问题,只是错误的代码,你能指出哪一部分是错误的吗?因为你看起来做的大部分事情都是删除所有的错误处理。你想象中的“错误处理”实际上并不能处理任何事情。然而,这使得这段代码非常难以阅读和切中要害。现在它非常清晰可读,无需水平滚动整个屏幕。正如我所说的,更容易阅读不会改变行为,你所做的事情改变了行为,毕竟,如果我不知道为什么这样做可以解决问题,那么下次我犯了什么错误,我怎么才能发现问题呢?PHP非常热衷于谈论错误,所以你不会错过它们。浏览你的代码,我能看到的唯一功能区别是
conn[“DB”]->next_result()