我很难道歉,如果这很难理解,很难解释,我是PHP开发的新手。我有一个脚本,它逐行读取CSV文件并将每一行存储在一个数组中。 CSV文件的格式如下(3列示例):
这些行然后通过循环运行,将产品导出到Magento API。请参阅下面的代码:
<?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
时创建的。为了尝试处理这个问题,我添加了一个if/else
语句,用于标识Product SKU
列中的当前值是否为空,然后如果它不为空,则仅执行catalogProductAttributeMediaCreate
代码。< / p>
这个问题是循环递增$sku
变量,因此当执行else
语句时,脚本会尝试将图像添加到{{1}的当前值同一行中的列,因此抛出了无效的数据错误。
我无法弄清楚如何让脚本返回到最后一个非空Product SKU
值,以便将图像添加到该产品而不是返回错误。我可能不得不删除Product SKU
语句,因为它不会像我最初希望的那样处理问题(愚蠢地没有意识到变量会随着每个循环而增加)。但是我想,在其他地方仍然需要if/else
行才能使用。
我愿意接受任何有关如何克服这一点的想法。我提前感谢您提供的任何见解。如果不清楚需要澄清,请告诉我,谢谢!
答案 0 :(得分: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功能提取您自己的功能
之后,你可以选择一个逻辑:
我会回答第一个问题:)
<?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)
这是你需要的吗?