2016-12-10 12 views
0

これは理解しにくい場合はお詫びします。説明するのは非常に難しく、PHP開発の初心者です。私は行ごとにCSVファイルを読み込み、各行を配列に格納するスクリプトを持っています。 CSVファイルは、そう(3列の一例)のようにフォーマットされている:これらの行は、次にMagentoのAPIに製品を輸出し、ループを介して実行されるPHPループ - 最後の非空白値を配列から使用する

enter image description here

<?php 
    // Interpret the CSV file and store each row as an array. 
    $csv = array(); 
    $new_csv = array(); 

    if (FALSE !== $handle = fopen("http://csvfilelink.csv", "r")) { 
     while (FALSE !== $row = fgetcsv($handle)) { 
      $csv[] = $row; 
     } 
    } 

    foreach ($csv as $row) { 
     $new_row = array(); 
     for ($i = 0, $c = count($csv[0]); $i < $c; ++$i) { 
      $new_row[$csv[0][$i]] = $row[$i]; 
     } 
     $new_csv[] = $new_row; 
    } 

    // Create client session. 
    $client = new SoapClient('API-URL'); 
    $sessionId = $client->login('User', 'Pass'); 

    // Product variables. 
    $attributeSets = $client->catalogProductAttributeSetList($sessionId); 
    $attributeSet = current($attributeSets); 
    $total_rows = count($csv); 

    // Create Products from CSV. 
    for ($sku = 1, $name = 1, $price = 1, $desc = 1, $table = 1, $qty = 1, $cond = 1, $pos = 1, $image = 1, $brand = 1, $color = 1, $material = 1, $style = 1; 
     $sku < $total_rows, $name < $total_rows, $price < $total_rows, $desc < $total_rows, $table < $total_rows, $qty < $total_rows, $cond < $total_rows, $pos < $total_rows, $image < $total_rows, $brand < $total_rows, $color < $total_rows, $material < $total_rows, $style < $total_rows; 
     ++$sku, ++$name, ++$price, ++$desc, ++$table, ++$qty, ++$cond, ++$pos, ++$image, ++$brand, ++$color, ++$material, ++$style) { 

     if ($new_csv[$sku]['Product SKU'] != '') { 
      try { 
       // Create product data. 
       $client->catalogProductCreate($sessionId, 'simple', $attributeSet->set_id, $new_csv[$sku]['Product SKU'], array(
        'name' => $new_csv[$name]['Product Name'], 
        'price' => $new_csv[$price]['Price'], 
        'categories' => array(
         'category' => 'DifferentCategory' 
        ), 
        'description' => $new_csv[$desc]['Product Description (Including HTML)'] . "<br><br>" . $new_csv[$table]['Param table'], 
        'weight' => 1, 
        'status' => 1, 
        'visibility' => 4, 
        'tax_class_id' => 1, 
        'stock_data' => array(
         'qty' => $new_csv[$qty]['Stock Quantity'], 
         'is_in_stock' => 1 
        ), 
        'additional_attributes' => array(
         'single_data' => array(
          array('key' => 'condition', 'value' => $new_csv[$cond]['Condition (Including HTML)']), 
          array('key' => 'brand', 'value' => $new_csv[$brand]['Brand']), 
          array('key' => 'color', 'value' => $new_csv[$color]['Color']), 
          array('key' => 'material', 'value' => $new_csv[$material]['Material']), 
          array('key' => 'style', 'value' => $new_csv[$style]['Style']) 
         ) 
        ) 
       ),0); 

       // Add product images. 
       $client->catalogProductAttributeMediaCreate($sessionId, $new_csv[$sku]['Product SKU'], array(
        'file' => array(
         'content' => base64_encode(file_get_contents($new_csv[$image]['Main Image'])), 
         'mime' => 'image/png', 
        ), 
        'position' => $new_csv[$pos]['Image Rank Position'], 
        'types' => array('image') 
       ), 0); 

       // Echo success message. 
       echo '<div class="success_box"><span class="success_box_text"><b>Success:</b> Product <b>' . $new_csv[$sku]['Product SKU'] . '</b> has been created.</div>'; 
      } catch (SoapFault $e) { 
       // Echo error message. 
       echo '<div class="error_box"><span class="error_box_text"><b>Error:</b> Cannot create product <b>' . $new_csv[$sku]['Product SKU'] . '</b> - ' . $e->getMessage() . '.</span></div>'; 
      } 
     } else { 
      $client->catalogProductAttributeMediaCreate($sessionId, $new_csv[$sku]['Product SKU'], array(
       'file' => array(
        'content' => base64_encode(file_get_contents($new_csv[$image]['Main Image'])), 
        'mime' => 'image/png', 
       ), 
       'position' => $new_csv[$pos]['Image Rank Position'], 
       'types' => array('image') 
      ), 0); 
     } 
    } 

?> 

これが唯一の1つの製品イメージを持っている製品のための素晴らしい作品が、私はに追加する必要があります私はこれらのイメージとして読み込まProduct Image列を持つ行を処理する必要があるだろうことに気づい:以下の私のコードを参照してください。以前のループでcatalogProductCreateが実行されたときに以前に作成されたものと同じ製品。これを処理するために、Product SKU列の現在の値が空であるかどうかを確認し、空でない場合はcatalogProductAttributeMediaCreateコードのみを実行するように、if/elseステートメントを追加しました。これに

問題がelseステートメントが実行されるときにループしたがって$sku変数をインクリメントし、スクリプトは、同じ行内のProduct SKU列の現在の値にイメージを追加しようとし、したがって、無効を投げていることですデータエラー。

最後の空でないProduct SKUの値にスクリプトを戻す方法を考えて、エラーを返す代わりにその製品にイメージを追加する方法はありません。私はif/elseステートメントを遡及的に取り除かなければならないかもしれませんが、これは当初期待していた方法で問題を処理しませんでした(愚かなことに、変数が各ループで増分されることを認識しませんでした)。しかし、私はif ($new_csv[$sku]['Product SKU'] != '')行がまだこれが動作するためには別の場所で必要とされるだろうと想像しています。

私はどのように私がこれを克服することができるのアイデアには開いています。あなたが提供できる洞察力があれば、事前に感謝します。これが不明確で、明確化が必要な場合はお知らせください、ありがとうございます!

答えて

1

私はあなたのコードを簡素化することができると思います:)

1.ソースデータ

<?php 

$data = [ 
    ['1', 'Product1', 'value1.1'], 
    ['', '',  'value1.2'], // there is no value on columns 0 & 1 => take last with 
    ['', '',  'value1.3'], // there is no value on columns 0 & 1 => take last with 
    ['2', 'Product2', 'value2.1'], 
    ['', '',  'value2.2'], /// idem 
]; 

?> 

は、あなた自身のものを抽出し、あなたのCSVが

2.読み取りデータを機能

経由した後あなたは論理を選択することができます:

  • は、それぞれの列に対して正しい値を前の値にします。
  • は、ID列が有効な(exの場合)正しい値で前の値を取ります。
  • ...

私が最初にのためにお答えします:)

<?php 
/************************************************************** 
* FUNCTION getPreviousColumnValue       * 
************************************************************** 
* This function return the previous valid value on array  * 
* list, on the selected colum. A valid value is something * 
* not null or different of '' (empty).      * 
************************************************************** 
* @param array $data: array source, multidim     * 
* @param int $from: current line. Will extract sub array  * 
* from 0 to $from.           * 
* @param int $column: column index to analyze.    * 
************************************************************** 
* Examples:             * 
* - getPreviousColumnValue($data, 3, 0)      * 
*  On $data, from line 3, return the previous correct * 
*  value for column 0 on $data array      * 
**************************************************************/ 
function getPreviousColumnValue(array $data, $from, $column) { 
    $data = array_slice($data, 0, $from + 1); // extract sub data array. $from id the current line 
    $data = array_reverse($data); // reverse for analyze 

    // Loop on each reversed line (from 0 to $from) 
    foreach($data as $row) { 
     // If the index does not exist, skip 
     if(!isset($row[$column])) continue; 

     // If the value (is null or empty) and different of '0', skip 
     if(is_null($row[$column]) OR $row[$column] === '') continue; 

     // Else, return this value ! 
     return $row[$column]; 
    } 
    return null; // Null, there is no value :(
} 

// Read CSV data - this is your code ! 
foreach($data as $iLineNumber => $line) { 

    // Include this loop at the begenning of you code 
    // Iterate on each row of the line: 
    foreach($line as $iRowKey => $row) { 
     // If the value (is null or empty) and different of '0' ... 
     // ... we need to find the previous valid value 
     if(is_null($row) OR $row === '') { 
      $line[$iRowKey] = getPreviousColumnValue($data, $iLineNumber, $iRowKey); 
     } 
     // So, if value is valid => use it ; else, find correct one via the function 
    } 

    // Your code here ! The array is fully filled. 
    // $client->catalogProductCreate(...) 
    var_dump($line); 
} 

最終的な出力で:

array (size=3) 
    0 => string '1' (length=1) 
    1 => string 'Product1' (length=8) 
    2 => string 'value1.1' (length=8) 

array (size=3) 
    0 => string '1' (length=1) 
    1 => string 'Product1' (length=8) 
    2 => string 'value1.2' (length=8) 

array (size=3) 
    0 => string '1' (length=1) 
    1 => string 'Product1' (length=8) 
    2 => string 'value1.3' (length=8) 

array (size=3) 
    0 => string '2' (length=1) 
    1 => string 'Product2' (length=8) 
    2 => string 'value2.1' (length=8) 

array (size=3) 
    0 => string '2' (length=1) 
    1 => string 'Product2' (length=8) 
    2 => string 'value2.2' (length=8) 

これは何が必要でしょうか?

+0

これを追加していただきありがとうございます。私の無知を許してください。しかし、最初のコードブロックは何ですか?私はこれを理解するのに時間がかかりますが、それがどのように進むのかを教えてくれます。 –

+1

私は前の投稿にいくつかのコメントを追加しました。それは良いですか? :) –

+0

本当にありがとうございました。これは、あなたのコードに当てはまるように変数の名前を変更すべきですか? 'foreach($ csv as $ row)'を 'foreach($ data as $ iLineNumber => $ line)'に置き換えます。 –

関連する問題