在php中运行程序时内存不足


Out of Memory when running a program in php

我正在运行两个几乎相同的程序,只是一个只需要查看最低价格,另一个需要查看最低的4个价格并获得平均值。我的问题是,当运行第二个程序时,我得到了一个内存不足的php致命错误。我的主机提供商已将我的内存限制设置为3000M,但我仍然会收到错误。这是第一个程序的代码:

    $parsed_xml = amazon_xml($isbn);
$current = $parsed_xml->ListMatchingProductsResult->Products->Product;
$asin = $current->Identifiers->MarketplaceASIN->ASIN;
//print_r($asin);
// get information based on the items ASIN
$price_xml = amazonPrice_xml($asin, $ItemCondition);
$currentPrice = $price_xml ->GetLowestOfferListingsForASINResult->Product->LowestOfferListings->LowestOfferListing;
$listPrice = $currentPrice->Price->ListingPrice->Amount;
// check to see if there are values
if(!empty($listPrice))
{  
            //print_r($listPrice); die;
//if($currentPrice->Price->ListingPrice->Amount > 0) {
    while(count($lowestPrices) < 2)
    {
            foreach($currentPrice as $offer){ 
                $totalFeedback = $offer->SellerFeedbackCount;
                $condition = $offer->Qualifiers->ItemSubcondition;
                //amazon condition matching algorithm (so we can match our condition up against amazons conditions)
                switch ($condition) {
                case "New":
                    $amazonCondition = 5;
                    break;
                case "Mint":
                    $amazonCondition = 4;
                    break;
                case "VeryGood":
                    $amazonCondition = 3;
                    break;
                case "Good":
                    $amazonCondition = 2;
                    break;
                case "Acceptable":
                    $amazonCondition = 1;
                    break;
                default:
                    $amazonCondition = 0;
                } // end of switch statement
            //echo $condition . "|" . $ourCondition . "|" . $amazonCondition . "|" . count($lowestPrices) . "|" . $totalFeedback . "|" . $merchantId . "<br/>";
            /* default lowest 1 */
                if(count($lowestPricesDefault[$a] <2)){
                $lowestPricesDefault[$a] = str_replace('$','',$offer->Price->ListingPrice->Amount);
                $a++;
                }
                if( ($ourCondition <= $amazonCondition) && ($totalFeedback >= 1500) &&  (count($lowestPrices) <2) )
                {
                $lowestPrices[$x] = str_replace('$','',$offer->Price->ListingPrice->Amount);
                $x++;
                }
            }
        $z++;
    }

    if(count($lowestPrices) > 0){
        $avgPrice = (array_sum($lowestPrices)/count($lowestPrices)) - .10;
        $source = "Amazon Condition Price";
    }else{
        //$avgPrice = $listPrice - ($listPrice * 0.25);
        $avgPrice = (array_sum($lowestPricesDefault)/count($lowestPricesDefault)) - .10;
        $source = "Default Pricing";
    }
    //make sure avg price is atleast 5.50, >236% of follett price, and >=200% of our cost
    if($avgPrice < ($follettPrice * 2.37)){
        $avgPrice = $follettPrice * 2.37;
        $source = "Follett Pricing";
    }
    if($avgPrice < ($row['cost'] * 2)){
        $avgPrice = $row['cost'] * 2;
        $source = "Double Cost";
    }
    if($avgPrice < 5.50){
        $avgPrice = 5.50;
        $source = "Lowest Base Cost";
    }
    //update Prices
    $conn->query("UPDATE inventory SET ourPrice = $avgPrice WHERE sku=" . $row['sku']);

这是第二个程序:

    $parsed_xml = amazon_xml($isbn);
$current = $parsed_xml->ListMatchingProductsResult->Products->Product;
$asin = $current->Identifiers->MarketplaceASIN->ASIN;
// get information based on the items ASIN
$price_xml = amazonPrice_xml($asin, $ItemCondition);
$currentPrice = $price_xml ->GetLowestOfferListingsForASINResult->Product->LowestOfferListings->LowestOfferListing;
$listPrice = $currentPrice->Price->ListingPrice->Amount;
// check to see if there are values
if(!empty($listPrice))
{  
//if($price_xml) {
    while(count($lowestPrices) < 4 ) // changed count to 4 per loralee's email 5-1-2012
    {

        foreach($currentPrice as $offer){
            $totalFeedback = $offer->SellerFeedbackCount;
            $condition = $offer->Qualifiers->ItemSubcondition;
                //amazon condition matching algorithm (so we can match our condition up against amazons conditions)
                switch ($condition) {
                case "New":
                    $amazonCondition = 5;
                    break;
                case "Mint":
                    $amazonCondition = 4;
                    break;
                case "VeryGood":
                    $amazonCondition = 3;
                    break;
                case "Good":
                    $amazonCondition = 2;
                    break;
                case "Acceptable":
                    $amazonCondition = 1;
                    break;
                default:
                    $amazonCondition = 0;
                }
            //echo $condition . "|" . $ourCondition . "|" . $amazonCondition . "|" . count($lowestPrices) . "|" . $totalFeedback . "|" . $merchantId . "<br/>";
            /* default lowest 4 */
            if(count($lowestPricesDefault[$a] < 4)){ //changed to 4 per new pricing specs
                $lowestPricesDefault[$a] = str_replace('$','',$offer->Price->ListingPrice->Amount);
                $a++;
            }
            if( ($ourCondition <= $amazonCondition) && ($totalFeedback >= 99) &&  (count($lowestPrices) < 4) ) //changed to 4 per new pricing specs
            {
                $lowestPrices[$x] = str_replace('$','',$offer->Price->ListingPrice->Amount);
                $x++;
            } 
        }
        $z++;
    }

    if(count($lowestPrices) > 0){
        $avgPrice = array_sum($lowestPrices)/count($lowestPrices);
        $source = "Amazon Condition Price";
    }else{
        //$avgPrice = $listPrice - ($listPrice * 0.25);
        $avgPrice = array_sum($lowestPricesDefault)/count($lowestPricesDefault);
        $source = "Default Pricing";
    }
    //make sure avg price is atleast 5.50, >236% of follett price, and >=200% of our cost
    if($avgPrice < ($follettPrice * 2.37)){
        $avgPrice = $follettPrice * 2.37;
        $source = "Follett Pricing";
    }
    if($avgPrice < ($row['cost'] * 2)){
        $avgPrice = $row['cost'] * 2;
        $source = "Double Cost";
    }
    if($avgPrice < 5.50){
        $avgPrice = 5.50;
        $source = "Lowest Base Cost";
    }
    //update fillzPrice
    $conn->query("UPDATE inventory SET ourPrice = $avgPrice WHERE sku=" . $row['sku']);

我在第二个程序的第86行收到了错误,即条件行($condition=$offer->Qualifiers->ItemSubcondition;)有人知道为什么会发生这种情况吗?此外,有人有什么建议可以让它运行得更好吗?

首先,两个代码审查点:

  1. 您有变量$a$x$z,它们都没有初始条件,对任何试图维护代码的人来说都是完全不透明的。一个单独的$i作为循环计数器通常被认为是可以接受的,但良好的变量命名可以使调试变得容易得多
  2. 使用SimpleXML时,始终将值强制转换为字符串:$asin = $current->Identifiers->MarketplaceASIN->ASIN;应读取$asin = (string)$current->Identifiers->MarketplaceASIN->ASIN;。除其他外,忘记执行此操作将意味着$asin永远无法保存到会话中(因为SimpleXML对象无法序列化)

至于你的代码为什么失败,我认为你的循环结构是错误的:

while(count($lowestPrices) < 4 )
{
    foreach($currentPrice as $offer)
    {
        // Do something which may add to `$lowestPrices`
        $z++;
    }
}

首先,$z似乎没有用于任何用途。其次,$lowestPrices可以在foreach循环内被添加到0、1、4、甚至100次。如果添加到至少4次,while循环将立即退出(因此可能不存在);如果它被添加到少于4次,则foreach循环将简单地在相同的数据上再次运行。我不清楚这是否会使它更有可能满足while循环的条件,给你一个无限循环。

内存不足,而不仅仅是CPU时间不足的原因是,即使$lowestPrices没有,额外的数组$lowestPricesDefault也会增长,因此每次while循环(因此整个内部foreach循环)重复时,它都会无限期地增长。