0

Inside a for loop I have the following code which pushes an array that contains some data inside another array:

$finCombo = array("color" => $color, "size" => $size, "productID" => $theProductID."-".$color, "imageURL" => 'https://click-tshirt.gr/images/detailed/all/'.$theProductCode."_".strtolower($color).'.jpg', "productURL" => $theProductURL, "title" => $theProductName, "price" => $theProductPrice, "category_path" => $theCategoryName, "availability" => $theProductAvailability, "brand" => $theProductBrand, "SKU" => $theProductCode."-".$color);

array_push($finalCmb, $finCombo);

The goal is to create an XML file using the data from the array. The code should return an xml file that looks like the below example:

<store>
    <date>2017-09-22 19:30</date>
    <products>
         <product>
             <SKU>10206-BLACK</SKU>
             <productID>338-BLACK</productID>
             <size>Small, Medium, Large, X Large</size>
             <color>BLACK</color>
             <title>Women's Jersey Short Sleeve Deep V-Neck Tee BLACK</title>
             <productURL>https://click-tshirt.gr/el-4/t-shirt-el/womens-jersey-short-sleeve-deep-v-neck-tee/</productURL>
             <imageURL>https://click-tshirt.gr/images/detailed/all/10206_Black.jpg</imageURL>
             <price>9.90</price>
             <category_path>ΓΥΝΑΙΚΕΙΑ///T-SHIRT</category_path>
             <brand>BELLA&CANVAS</brand>
             <availability>Κατόπιν παραγγελίας</availability>
         </product>

Here an example of the array where you can see that "425-DEEP_NAVY" is inserted in the array with the size "Medium" but later on it is inserted again and again for each size:

Array ( [0] => Array ( [0] => Array ( [color] => BLACK_DARK_GREY [size] => Small [productID] => 390-BLACK_DARK_GREY [imageURL] => https://click-tshirt.gr/images/detailed/all/18608_black_dark‌​_grey.jpg [productURL] => http://click-tshirt.gr/el-3/category-50/adult-fashion-basic-‌​ls-hooded-tee/ [title] => Adult Fashion Basic LS Hooded Tee [price] => 13.800000 [category_path] => ΑΝΔΡΙΚΑ/ΦΟΥΤΕΡΑΚΙΑ ΜΕ ΚΟΥΚΟΥΛΑ [availability] => Κατόπιν παραγγελίας [brand] => ANVIL [SKU] => 18608-BLACK_DARK_GREY )))

There is also one thing that happens and so far I have managed to resolve it with JavaScript. That is the products are inserted in the array for every "productID" there is several "size's" so for each size the same productID is inserted several times while what I need is that for each productID the size to be an array containing all sizes that correspond to that productID. See codepen console below:

codepen example

4
  • Possible duplicate of How to generate XML file dynamically using PHP? Commented Oct 16, 2017 at 9:51
  • 1
    Ok, it seems that your problem is not creating an XML file, but rather that you get multiple values in your array. Please post your code, so we can see what your error is. Also, don't ask two questions in the same question. Create a new question for your second part. Commented Oct 16, 2017 at 10:18
  • Checkout your $color variable. It is an array not a string. Commented Oct 16, 2017 at 11:17
  • 1
    Checkout your $color variable. It is an array not a string. In other words to get an XML like descriped you should have an array of products its elements are associative array for each product and that associative array should not has arrays as values. i.e [0 => ['SKU' => '10206 red', 'productID' => '288-red','size' => 'small, large'],1=>[],... Commented Oct 16, 2017 at 11:23

1 Answer 1

3

Combining arrays

First, your problem probably lies in your usage of array_push.

$array = ['test'];
$secondarray = ['foo', 'bar'];

array_push($array, $secondarray);

will give you an $array containing the array $secondarray

Array (
    0 => (string) "test"
    1 => Array (
        0 => (string) "foo"
        1 => (string) "bar"
    )
)

What I guess you want is array_merge(), which will merge the two arrays instead.

$array = ['test'];
$secondArray = ['foo', 'bar'];
$resultArray = array_merge($array, $secondArray);

Which will give you the $resultArray:

Array(
    [1] => (string) "test"
    [2] => (string) "foo"
    [3] => (string) "bar"
)

Converting to XML

You can do this in multiple ways. Write your own solution using XmlWriter or create a DOM structure using either SimpleXml or DomDocument.

SimpleXml

Perhaps the simplest solution is to use SimpleXmlElement like this:

$xml = SimpleXmlElement('<store/>');
$xml->addChild('date', '2017-09-22 19:30');
$products = $xml->addChild('products');
$product  = $products->addChild('product');
foreach ($finCombo as $name => $value) {
    $product->addChild($name, $value);
}
echo $xml->asXML(), PHP_EOL;

SimpleXml with Formatting

If you want to use the same formatting/indentation as in your example, you need to use DomDocument or XmlWriter. If you are already doing this in SimpleXml, you can easily load a DomDocument from a SimpleXmlElement.

...
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
$domxml->dom_import_simplexml($xml); // load the SimpleXmlElement previously created.
echo $domxml->saveXML();

DomDocument

Or you could do this directly with DOMDocument.

$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$store = $dom->createElement('store');
$dom->appendChild($store);
$store->appendChild($dom->createElement('date', '2017-09-22 19:30'));
$products = $dom->createElement('products');
$product = $dom->createElement('product');
foreach ($finCombo as $key => $val) {
    $product->appendChild($dom->createElement($key, $val));
}
$products->appendChild($product);
$store->appendChild($products);
echo $dom->saveXML(), PHP_EOL;

XmlWriter

Or, if you want more control (e.g. over indentation), you can use XmlWriter

$writer => new XMLWriter();
$writer->openMemory();
$writer->setIndent(true);
$writer->setIndentString('    ');
$writer->startDocument('1.0', 'UTF-8');
$writer->startElement('store');
$writer->startElement('date');
$writer->text('2017-09-22 19:30');
$writer->fullEndElement(); // end date element
$writer->startElement('products');
$writer->startElement('product');
foreach ($finCombo as $key => $val) {
    $writer->startElement($key);
    $writer->text($val);
    $writer->fullEndElement(); // end $key element
}
$writer->fullEndElement(); // end product element
$writer->fullEndElement(); // end products element
$writer->fullEndElement(); // end store element
$writer->endDocument();
echo $writer->flush(true);
Sign up to request clarification or add additional context in comments.

8 Comments

Rather than converting to a string and back with $domxml->loadXML($xml->asXML());, you should use dom_import_simplexml which directly re-wraps the object in memory (the two APIs work on the same underlying structures). I've checked, and this still lets you set the pretty-print flags on the document: 3v4l.org/WtPsI
Great comment, I will update the answer in a moment.
okay, so here's what we get with the DOMDocument solution: Warning: DOMDocument::createElement() expects parameter 2 to be string, array given in C:\xampp\htdocs\get_content\index.php on line 203 Fatal error: Uncaught TypeError: Argument 1 passed to DOMNode::appendChild() must be an instance of DOMNode, null given in C:\xampp\htdocs\get_content\index.php:203 Stack trace: #0 C:\xampp\htdocs\get_content\index.php(203): DOMNode->appendChild(NULL) #1 {main} thrown in C:\xampp\htdocs\get_content\index.php on line 203
here is what print_r shows for the array that I need to convert to xml (this is the first entry): Array ( [0] => Array ( [0] => Array ( [color] => BLACK_DARK_GREY [size] => Small [productID] => 390-BLACK_DARK_GREY [imageURL] => https://click-tshirt.gr/images/detailed/all/18608_black_dark_grey.jpg [productURL] => http://click-tshirt.gr/el-3/category-50/adult-fashion-basic-ls-hooded-tee/ [title] => Adult Fashion Basic LS Hooded Tee [price] => 13.800000 [category_path] => ΑΝΔΡΙΚΑ/ΦΟΥΤΕΡΑΚΙΑ ΜΕ ΚΟΥΚΟΥΛΑ [availability] => Κατόπιν παραγγελίας [brand] => ANVIL [SKU] => 18608-BLACK_DARK_GREY )))
@MilošMiljković, I see your problem now. Your array is an array of arrays. This is probably due to your use of array_push(), which pushes the variable/object you are passing it onto the array you specify. If you try to push an array onto another array, you will simply get an array containing an array. What I guess you want to do is use array_merge (php.net/array_merge)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.