繁体   English   中英

流:将对象转换为数组以进行CSV导出

[英]Flow: Convert object to array for CSV export

我想将我的对象“ mitglied”导出到一个.csv文件。 我的控制器如下所示:

public function exportAction() {

    // find all mitglieds
    $records = $this->mitgliedRepository->findTennis();

    // Set path for export-file
    $csvPath = '/var/www/apps/flow/Packages/Application/ITOOP.Atc/Resources/Private/Export/test.csv';

    $fp = fopen($csvPath, 'w');

    foreach ($records as $lines) {
        fputcsv($fp, $lines);
    }

    fclose($fp);
}

当我调用exportAction时,出现错误:

#1:警告:fputcsv()期望参数2为数组,对象位于/var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Controller_MitgliedController.php行中

494行是...

fputcsv($fp, $lines);

...所以我认为我必须将“ mitglied”对象转换为数组。

我的mitgliedRepository中的public函数findTennis看起来像这样:

public function findTennis() {
    $query = $this->createQuery();
    $result = $query->matching($query->equals('abteilung', 'Tennis'))
                    ->setOrderings(array('name' => \TYPO3\Flow\Persistence\QueryInterface::ORDER_ASCENDING))
                    ->execute();

    return $result;
}

我试图设置toArray(); 在这样的存储库中:

public function findTennis() {
    $query = $this->createQuery();
    $result = $query->matching($query->equals('abteilung', 'Tennis'))
                    ->setOrderings(array('name' => \TYPO3\Flow\Persistence\QueryInterface::ORDER_ASCENDING))
                    ->execute()
                    ->toArray;
    return $result;
}

但是然后我得到以下错误:

#1:注意:未定义的属性:TYPO3 \\ Flow \\ Persistence \\ Doctrine \\ QueryResult :: $ toArray在/var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Domain_Repository_MitgliedRepository.php行中

第105行当然是

 ->toArray;

有人知道如何在流中将对象转换为数组吗?

在下面的示例中,导出有效,因此我认为存储库查询(的格式)是问题所在。

public function exportAction() {
    // Set path for export-file
     $csvPath = '/var/www/apps/flow/Packages/Application/ITOOP.Atc/Resources/Private/Export/test.csv';

 $test = array (
     array('xxx', 'bbb', 'ccc', 'dddd'),
     array('123', '456', '789'),
     array('aaa', 'bbb')
 );


 $fp = fopen($csvPath, 'w');

 foreach ($test as $lines) {
     fputcsv($fp, $lines);
 }

 fclose($fp);

}

请指出正确的方向。 谢谢!

错误消息说明

#1:警告:fputcsv()期望参数2为数组,对象位于/var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Controller_MitgliedController.php行中

fputcsv期望它的第二个参数是一个数组。 该数组将作为CSV行写入到单个文件中,每个数组元素作为一列。 $records变量上进行迭代时,您将获得域对象类的实例(例如ITOOP\\Atc\\Domain\\Model\\Mitglied )。 那是不确定的行为,因此是警告。

#1:注意:未定义的属性:TYPO3 \\ Flow \\ Persistence \\ Doctrine \\ QueryResult :: $ toArray在/var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Domain_Repository_MitgliedRepository.php行中

toArray是Doctrine QueryResult类提供的功能。 通常,Doctrine查询不会获取查询返回的所有对象,而是返回一个迭代器 ,该迭代器按需获取和映射实体。 toArray方法一次获取所有记录,并返回一个数组,而不是迭代器。 发生错误是因为您尝试将toArray 作为属性访问,而不是将其作为method调用 以下代码将是正确的:

$result = $query->matching($query->equals('abteilung', 'Tennis'))
                ->setOrderings(array('name' => \TYPO3\Flow\Persistence\QueryInterface::ORDER_ASCENDING))
                ->execute()
                ->toArray(); // <- Mind the brackets!

但是,这将无济于事,因为在控制器中,您仍将在域实体列表上进行迭代( foreach并不关心其是否在迭代器或数组上进行迭代;这实际上是PHP中迭代器的重点)。

快速与肮脏的解决方案

手动在您的控制器中转换您的域实体。 只有您知道CSV导出的外观 ,因此无法自动进行。 我在想这样的事情:

foreach ($records as $record) {
    $csvLine = [
        $record->getFirstProperty(),
        $record->getSecondProperty(),
        // and so on...
    ];
    fputcsv($fp, $csvLine);
}

更好的解决方案

呈现CSV数据不是控制器应该解决的问题 基本上,它应该进入视图。 您可以实现用于处理CSV输出的自定义视图类。

为此,您需要实现\\TYPO3\\Flow\\Mvc\\View\\ViewInterface 最简单的方法是将\\TYPO3\\Flow\\Mvc\\View\\AbstractView子类化。 将您的视图类命名为<PackageNamespace>\\View\\<Controller>\\Action<Format> (诸如此类,例如ITOOP\\Atc\\View\\Mitglied\\ExportCsv 。在视图的render()方法中实现CSV导出逻辑。流程将开始)并在存在时自动使用视图类。

本文将详细解释实现自定义视图的方法-尽管它是德语版本,但是基于您的类命名,我怀疑这不会有问题;)。

我用任意DQL解决了这个问题。 正如我提到的那样,我认为问题在于查询没有得到数组。 但是,在我的存储库中使用以下查询时,我会这样做:

/**
* @Flow\Inject
* @var \Doctrine\Common\Persistence\ObjectManager
* inject Doctrine's EntityManager to execute arbitrary DQL
*/
protected $entityManager;    

/**
* find mitglieder with Abteilung Tennis und return an array
*/
public function exportTennis() {
    $query = $this->entityManager->createQuery("SELECT mitglied FROM \itoop\atc\Domain\Model\Mitglied mitglied WHERE mitglied.abteilung = 'Tennis'");
    return $query->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
}

我认为重要的部分是getResult(\\ Doctrine \\ ORM \\ Query :: HYDRATE_ARRAY);

暂无
暂无

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

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