2017-03-03 78 views
0

我有以下代碼:循環準備statments

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次完美的作品 但是使用此代碼在那裏,循環重複兩次以上將導致POST到PHP來封端的無響應

,並生成在MySQL日誌以下,

2017-03-03T16:47:49.284972Z 450 [注]中止連接450到DB: '中央' 用戶: '用戶名' 主機: '本地主機'(得到了一個錯誤讀出 通信分組)

2017-03-03T16:47:49.582165Z 451 [注]中止 連接451至DB:「中央'用戶名:'用戶名'主機:'localhost' (錯誤讀取通信數據包)

所以問題是我做了什麼錯?

注意 我嘗試添加

$res->free(); 
$stmt->close(); 

這就導致

包亂序。預計1接收7包大小= 7

mysqli_stmt ::執行():MySQL服務器已消失

mysqli_stmt ::執行():讀取錯誤結果集的頭

的信息。 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 
+0

我想有對服務器進行,​​並且可能會導致這...從過多的請求整齊版本編輯我猜想http://stackoverflow.com/questions/2232150/pdo-mysql-server-has-gone-away這個線程可以幫助 – RohitS

+0

,你可以從錯誤中看到它的localhost DB只有我使用它,所以在那裏應該只是當前訪問它的這個命令,這些應該是順序不同步 – MikeT

+0

T是...但有一些解決方案ns在線程內,您可以嘗試..也嘗試啓用重新連接屬性。 – RohitS

回答

0

的問題是,你需要調用$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(); 
     } 
    } 
} 
+0

太多的代碼永遠不是問題,只有錯誤的代碼,你能指出哪個部分是錯誤的,因爲你似乎做的大部分是刪除所有的錯誤處理 – MikeT

+0

你喜歡稱爲「錯誤處理」實際上並不*處理*任何東西。然而,這使得代碼非常難以閱讀和切入點。現在它非常清晰易讀,無需水平滾動整個屏幕。 –

+0

正如我所說更容易閱讀不會改變行爲,你已經做了一些改變了行爲,畢竟,如果我不知道爲什麼這會修復它,我怎麼才能找到問題,我下一次做出什麼錯誤? – MikeT

-2

你可以看到什麼動原因這個錯誤https://dev.mysql.com/doc/refman/5.7/en/communication-errors.html

如果客戶端成功地連接但稍後斷開不當或 終止時,服務器遞增Aborted_clients狀態 變量,並記錄一箇中止連接消息到錯誤日誌。該 原因可能是下列任何一項:

  • 客戶端程序沒有退出之前調用mysql_close()

  • 客戶一直在睡覺超過WAIT_TIMEOUTinteractive_timeout秒而不發出的 服務器的任何請求。

  • 客戶端程序在數據傳輸的中間突然結束。

但是,我認爲,這不是很好的做法,以使用bind_param內循環,因爲它應該在循環之前只使用一次一個。 第二個通知是確保關閉連接,即使有錯誤產生。

+1

不幸的是,您的猜測與您提出的問題無關。 –

+0

真的!那麼爲什麼你的答案在循環的外面包含** bind_param **,因爲我的猜測與這個問題沒有關係? –

+0

因爲只運行一次就可以了,但是在循環中調用並沒有什麼壞處,>與問題無關。 –