1

私は2つのほぼ同じプログラムを実行していますが、1つは最低価格のみを確認する必要があり、もう1つは最低4つの価格を確認して平均を取得する必要がある点が異なります。私の問題は、2番目のプログラムを実行すると、メモリ不足の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']);

これが2番目のプログラムです。

    $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']);

2番目のプログラムの86行目である条件行($ condition = $ offer-> Qualifiers-> ItemSubcondition;)でエラーが発生しています。これが発生している理由を誰かが知っていますか?また、誰かがそれをより良く実行するための提案がありますか?

4

1 に答える 1

1

まず、2つのコードレビューポイント:

  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内で0、1、4、または100回まで追加できます。foreach少なくとも4回追加されると、whileループはすぐに終了します(したがって、存在しない場合もあります)。追加回数が4回未満の場合、foreachループは同じデータに対して再度実行されます。whileこれにより、ループの条件を満たす可能性が高くなり、無限ループが発生するかどうかはわかりません。

CPU時間だけでなく、メモリが不足している理由は、追加の配列$lowestPricesDefaultが増加しない場合でも増加するため、ループ(したがって内部ループ全体)が繰り返さ$lowestPricesれるたびに無期限に増加し続けるためです。whileforeach

于 2012-08-24T13:41:58.007 に答える