簡體   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