2016-04-29 205 views
0

我有工作代碼,但我似乎已經向我的代碼引入了一個糟糕的瓶頸。在詳細討論之前,讓我給你一些關於這段代碼的背景知識。我有一個用PHP/HTML生成的表格,其中顯示了數據庫中的部分列表(149部分)。用戶可以選擇該項目的數量,然後點擊「添加到購物車」,這一切都正常工作。PHP - MySQL - Foreach循環瓶頸

但是,我試圖通過添加一個功能來增加一些功能,只允許用戶選擇我們手頭上的此產品的實際數量(在添加此功能之前,我之前已將最大值硬編碼100)。

現在這個工作,但它是可怕的慢(加載頁面50秒)。但是,在實現這個頁面之前立即加載沒有問題,因此這對於getPartQuantityOnHand()函數肯定是一個問題。

我認爲問題在於,對於每個部件(149),我都調用此函數,然後必須重新連接到數據庫才能找到正確的數量。有沒有人看到我可以改善這種方式?僅供參考,零件託管在一個完全獨立的數據庫中,這些數據來自這些零件的現有數量。

我已經離開了PHP代碼的一些部分,因爲這是不必要的批量這個職位,我知道我在這裏缺少零件。

getParts.php

 <?php 
      $partList = $_SESSION['controller']->getParts(); 

      foreach ($partList as $part) { 

      //Call to get the current quantity on hand for this specific part 
      //THIS IS WHEN THE PROBLEM WAS INTRODUCED 
      $quantityOnHand = $_SESSION['controller']->getPartQuantityOnHand($part->number); 

      //Only display this part if we have at least one on hand 
      if ($quantityOnHand > 0) 
      { 
       echo "<tr>"; 
       echo "<td>" . $part->number . "</td>"; 
       echo "<td>" . $part->description . "</td>"; 
       echo "<td>&#36;" . $part->price . "</td>"; 
       echo "<td>"; 
        echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>'; 
       echo "</td>"; 
        echo "</form>"; 
       echo "</td>"; 

       echo "</tr>"; 
      } 
      } 

      echo "</table>"; 
     echo "</div>"; 
    ?> 

getPartQuantityOnHand()

public function getPartQuantityOnHand($partNum) { 
     $conn = $this->connect(); 

     $sql = "select Quantity from ReceivingInfo where PartNumber = '$partNum'"; 
     $stmt = $conn->prepare($sql); 
     $stmt->execute(); 

     $row = $stmt->fetch(PDO::FETCH_ASSOC); 

     $quantityOnHand = $row['Quantity']; 

     return $quantityOnHand; 
    } 

感謝您的幫助,您可以提供!

+0

比方說,你有一個數組的所有零件號碼。如何1調用例程來做一個getHand(id,in(a,b,c,d)。結果集包含partId,onHand。此時,您將兩個PHP數組相互對齊,並將它們組合起來。 – Drew

+0

@德魯嗯..我從來沒有嘗試過這樣的事情,但我可以肯定地給它一個鏡頭。感謝您的輸入。 – trevor

回答

1

由於兩個數據庫是分開的,你有兩個選擇:

  1. 確定你循環之前的部分數字並生成HTML,然後查詢所有在同一時間與IN條款:

    SELECT ... WHERE PartNumber IN (1, 2, 3, 4); 
    
  2. 選擇所有庫存水平的部分,當你第一次調用getPartQuantityOnHand和存儲:

    public function getPartQuantityOnHand($partNum) { 
        if(!$this->partQuantitiesOnHand) { 
         $conn = $this->connect(); 
    
         $sql = "select Quantity, PartNumber from ReceivingInfo"; 
         $stmt = $conn->prepare($sql); 
         $stmt->execute(); 
    
         $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 
    
         $this->partQuantitiesOnHand = array_column($rows, 'Quantity', 'PartNumber'); 
        } 
    
        return $this->partQuantitiesOnHand[$partNum] ?? null; 
    } 
    

選項2的缺點是,如果你有很多比在單頁上列出多個部分,它永遠不會執行,以及選項1

+0

謝謝,我結束了使用選項2,它很好。我的加載時間已恢復正常! – trevor

0

因此,而不是做一個149個不同的SQL查詢,只需做一個查詢,將所有需要的Quantity值帶回來。

ex。

SELECT Quantity FROM ReceivingInfo WHERE PartNumber IN ($listOfPartNums)

當然

你將要興建的字符串$listOfPartNums

或者,如果你真的總是帶回他們的完整列表,可以排除IN條款,不需要擔心生成字符串。

您必須稍微更改一下函數以將partnum/quantity對存儲在關聯數組中。

然後在你的getParts中。PHP得到這樣的數量:

<?php 
     $partList = $_SESSION['controller']->getParts(); 
     $quantityList = getQtyList(); // return assoc array of partnum/qty pairs 

     foreach ($partList as $part) { 

     //Call to get the current quantity on hand for this specific part 
     //THIS IS WHEN THE PROBLEM WAS INTRODUCED 
     $quantityOnHand = $quantityList[$part->number]; 

     //Only display this part if we have at least one on hand 
     if ($quantityOnHand > 0) 
     { 
      echo "<tr>"; 
      echo "<td>" . $part->number . "</td>"; 
      echo "<td>" . $part->description . "</td>"; 
      echo "<td>&#36;" . $part->price . "</td>"; 
      echo "<td>"; 
       echo '<input name="qty'. $part->number .'" type="number" value="1" min="1" max="' . $quantityOnHand .'"/>'; 
      echo "</td>"; 
       echo "</form>"; 
      echo "</td>"; 

      echo "</tr>"; 
     } 
     } 

     echo "</table>"; 
    echo "</div>"; 
?>