I want to export an array of objects in CSV :
array(10) {
[0]=>
object(Produit)#228 (36) {
["id_produit":protected]=> string(4) "9999"
["reference":protected]=> string(9) "reference1"
}
[1]=>
object(Produit)#228 (36) {
["id_produit":protected]=> string(4) "8888"
["reference":protected]=> string(9) "reference2"
}
}
IN something like :
id_produit | reference | ...
9999 | reference1 | ...
8888 | reference2 | ...
The first row : list of attribut / column
The other row : value of the attribut of the Object
True Example of array with object : http://pastebin.com/8Eyf46pb
I tried this : Convert array into csv but it doesn't work for me.
Is it possible to do this (and how ?) or I have to write each attribute in a loop ?
To convert an array into a CSV file we can use fputcsv() function. The fputcsv() function is used to format a line as CSV (comma separated values) file and writes it to an open file.
Can CSV contain array? Importing CSVs does not handle complex types like arrays, it is designed to import simple, flat data. The only types that are currently supported are strings and numbers.
fputcsv() formats a line (passed as a fields array) as CSV and writes it (terminated by a newline) to the specified file stream .
The fgetcsv() function parses a line from an open file, checking for CSV fields.
It would be pretty easy if all your properties are public:
// Test class
class Produit
{
public $id_produit;
public $reference;
// Test data
public function __construct()
{
$this->id_produit = rand(1, 255);
$this->reference = rand(1, 255);
}
}
// Test data array
$array = array(new Produit(), new Produit());
// Notice, you can only use a single character as a delimiter
$delimiter = '|';
if (count($array) > 0) {
// prepare the file
$fp = fopen('test/file.csv', 'w');
// Save header
$header = array_keys((array)$array[0]);
fputcsv($fp, $header, $delimiter);
// Save data
foreach ($array as $element) {
fputcsv($fp, (array)$element, $delimiter);
}
}
But as I can see, your properties are protected. Which means we can't access properties outside the object as well as loop through them or use (array) typecasting. So in this case you must make some changes ot the object:
// Test class
class Produit
{
// ...
public function getProperties()
{
return array('id_produit', 'reference');
}
public function toArray()
{
$result = array();
foreach ($this->getProperties() as $property) {
$result[$property] = $this->$property;
}
return $result;
}
}
And then instead of typecasting you can use new method toArray like this:
// Save data
foreach ($array as $element) {
fputcsv($fp, $element->toArray(), $delimiter);
}
Also thanks to new mehod getProperties we can change header getting:
// Save header
fputcsv($fp, $array[0]->getProperties(), $delimiter);
I've now tested the below code and it does seem to work. Reflection was the answer.
I tried to get it working on phpfiddle hence the php://temp but it didn't work unfortunately
<?php
class Produit
{
public $id_produit;
public $reference;
// Test data
public function __construct()
{
$this->id_produit = rand(1, 255);
$this->reference = rand(1, 255);
}
}
$array = array(new Produit(), new Produit());
$delimiter='|';
$fp=fopen('php://temp', 'w'); //replace this bit with a file name
$header=false;
foreach($array as $Produit){
$Reflection = new ReflectionClass($Produit);
$properties = $Reflection->getProperties();
$row=array();
foreach($properties as $prop){
$row[$prop->getName()] = $prop->getValue($Produit);
}
if(!$header){
fputcsv($fp, array_keys($row), $delimiter);
$header=true;
}
fputcsv($fp, $row, $delimiter);
}
//now show what has been written, you will want to remove this section
fseek($fp, 0);
fpassthru($fp);
//ends
fclose($fp);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With