简体   繁体   English

PHP - 将对象数组导出为CSV

[英]PHP - Export to CSV an array of objects

I want to export an array of objects in CSV : 我想以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 第一行: attribut /列的列表

The other row : value of the attribut of the Object 另一行: Object的attribut的值

True Example of array with object : http://pastebin.com/8Eyf46pb True对象的数组示例: http //pastebin.com/8Eyf46pb

I tried this : Convert array into csv but it doesn't work for me. 我试过这个: 将数组转换为csv,但它对我不起作用。

Is it possible to do this (and how ?) or I have to write each attribute in a loop ? 是否可以这样做(以及如何?)或者我必须在循环中编写每个属性?

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: 然后你可以使用new方法来代替类型转换,如下所示:

// Save data
foreach ($array as $element) {
    fputcsv($fp, $element->toArray(), $delimiter);
}

Also thanks to new mehod getProperties we can change header getting: 还要感谢新的mehod getProperties,我们可以改变标题:

// 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 我试图让它在phpfiddle上工作,因此php:// temp但不幸的是它没有用

<?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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM