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」オブジェクトを配列に変換する必要があると思います。

findTennis私のmitgliedRepositoryのパブリック関数は次のようになります。

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 in /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 で指定されます

fputcsv2 番目のパラメーターが配列であることが期待されます。その配列は、各配列要素を列として、CSV 行として単一のファイルに書き込まれます。変数を反復処理する$recordsと、ドメイン オブジェクト クラスのインスタンスが取得されます (おそらく sth. like ITOOP\Atc\Domain\Model\Mitglied)。これは未定義の動作であるため、警告です。

#1: 注意: 未定義のプロパティ: TYPO3\Flow\Persistence\Doctrine\QueryResult::$toArray in /var/www/apps/flow/Data/Temporary/Development/Cache/Code/Flow_Object_Classes/itoop_atc_Domain_Repository_MitgliedRepository.php 105 行目

toArrayQueryResultDoctrineクラスが提供する機能です。通常、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 の反復子のポイントです)。

Quick&Dirty ソリューション

コントローラーで手動でドメイン エンティティを変換します。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>(sth. like ITOOP\Atc\View\Mitglied\ExportCsv. CSV エクスポート ロジックをビューのrender()メソッドに実装します。フローは、ビュー クラスが存在するとすぐに自動的に取得して使用します。

カスタム ビューの実装については、この記事で詳しく説明しています。ただし、ドイツ語ですが、クラスの命名に基づいて、問題にはならないと思います ;)。

于 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 に答える