1

我想将我的对象“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 行中给出

第 494 行是...

fputcsv($fp, $lines);

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

我的 mitgliedRepository 中的公共函数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 行

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

}

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

4

2 回答 2

0

错误信息解释

#1:警告:fputcsv() 期望参数 2 是数组,对象在 /var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Controller_MitgliedController.php 第 494 行中给出

fputcsv期望它的第二个参数是一个数组。该数组将作为 CSV 行写入单个文件,每个数组元素作为列。当迭代你的$records变量时,你会得到你的域对象类的实例(所以可能是 sth. like 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 第 105 行

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

$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。在视图的方法中实现您的 CSV 导出逻辑render()。Flow 将在视图类出现后立即自动获取并使用它。

本文深入解释了实现自定义视图——虽然它是德语的,尽管根据你的类命名我怀疑这不会是一个问题;)。

于 2015-05-03T19:26:01.717 回答
0

我用任意 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);

于 2015-05-05T04:38:19.337 回答