Symfony: экспорт (CSV) файл имеет ограничение? - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь отправить сгенерированный файл CSV, используя Symfony 5, и каким-то образом кажется, что достигнут предел, который я не могу преодолеть. По причинам тестирования я разбил его на основы c основ; поэтому я отправляю данные c, создаю txt-файл и не делаю логи c. В приведенном ниже примере кода, если я сделаю 65 итераций, файл будет сгенерирован и отправлен в браузер для загрузки (это 4 КБ). Если я наберу 66 или добавлю одну букву в строку данных образца $ data, все это отобразится в окне браузера. Точно такой же код отлично работает вне Symfony даже с 1000 итерациями. Я также не получаю сообщение об ошибке или что-то из журнала dev.log, которое может помочь.

public function saveCSV(Request $request, DelcampeParser $parser) {
    $response = new Response();

// same with
//  $response = new StreamedResponse();
//  $response->setCallback(function(){});

    $response->headers->set('Content-Type', 'text/plain; charset=utf-8');
    $disposition = HeaderUtils::makeDisposition(
        HeaderUtils::DISPOSITION_ATTACHMENT,
        'foo.txt'
    );
    $response->headers->set('Content-Disposition', $disposition);

    $data = array(0 => 'abcdefghijklmnopqrstuvwxyz');
    for ($a=1;$a<=66;$a++) {
        var_dump($data);
    }

    return $response;
}

Что не так? Почему я не могу создать файл большего размера в Symfony?

Спасибо.

[править] У меня есть новая теория: выходная буферизация PHP установлена ​​в 4 КБ , Всякий раз, когда буфер заполнен, буферизованные данные отправляются в браузер. К сожалению, это происходит до того, как заголовки были отправлены Symfony, создавая вывод браузера. Как я могу изменить это поведение?

1 Ответ

0 голосов
/ 23 января 2020

У меня теперь есть ответ с StreamedResponse, который работает и, надеюсь, также выполнит все требования и рекомендации Symfony:

// in the Controller
public function saveCSV(Request $request, Parser $parser) {
    $response = new StreamedResponse();

    $data = $request->get("sd");    // sd comes out of a form that posts a multidimensional array
    $response->setCallback(function() use ($data, $parser) {
        $parser->generateCSV($data);
    });

    $response->headers->set('Content-Type', 'text/csv; charset=utf-8');
    $disposition = HeaderUtils::makeDisposition(
        HeaderUtils::DISPOSITION_ATTACHMENT,
        "delcampeimport_".date("Ymd-Hi").".csv",
    );
    $response->headers->set('Content-Disposition', $disposition);

    return $response;
}

и моего Сервиса

public function generateCSV($dataarray) {
    $out = fopen('php://output', 'w+');

    // send header rows of csv file
    fputs($out, "website_visibility,category_id,title, /* ..., */ images\r\n");

    // generate data
    foreach($dataarray AS $stamp) {
        $stampdata = array ( 
            'a' => 'CH',
            'b' => $stamp['category'],
            'c' => htmlentities($stamp['title']),
            // ...
            'aa' => $stamp['img1'].
            ($stamp['img2'] ? ";".$stamp['img2']:"").
            ($stamp['img3'] ? ";".$stamp['img3']:"")
        );

        // send csv data
        fputcsv($out, $stampdata);
    }
    fclose($out);
}

Спасибо за ввод

...