0

I have a problem with my .csv. So I tried to generate a .csv from an array using php. In the view I have :

<form id="form_logistique" action="myroute" method="post">
            <div class="form-group " style="float: left;">
                <label class="control-label" for="" style="display: inline-block; padding-right: 20px;">Date min</label>
                <input type="text" id="date_min" name="date_min.name" value="date_min" placeholder="Date min" class="form-control datepicker"  />
            </div>

            <div class="form-group" style="float: left;padding-left: 20px;">
                <label class="control-label" for="" style="display: inline-block; padding-right: 20px;">Date max</label>
                <input type="text" id="date_max" name="date_max" value="{{ date_max" placeholder="Date max" class="form-control datepicker"  />
            </div>


            <input type="submit" class="btn btn-primary" style="margin-top: 25px;margin-left: 20px;" value="Rechercher"></input>
            <input type="submit" class="btn btn-succes" style="margin-top: 25px;margin-left: 20px;" name="export" value="Exporter"></input>
    </form>

In php :

 public function getLogistique()
{
    $this->form_logistique = new Form\Form(
        new Form\Field\Text('date_min', '', true),
        new Form\Field\Text('date_max','',true),
    );
    $date_min = '';
    $date_max = '';
    if ($this->getRequest()->isPostMethod() && $this->form_logistique->bind($_POST)){
        $date_min = $this->form_logistique->date_min->getValue();
        $date_max = $this->form_logistique->date_max->getValue();
    }
    $interdit  = array(";", ",", ":", "*", "/", "|", "?", '"', "<", ">", "!", "_", "@", "[", "]", "\\", "{", "}", "~");
    $aGifts = Gain::getGiftForLogistique($date_min, $date_max, $statut);
    foreach($aGifts as $gift){
        $date = explode(' ', $gift['date_gain']);
        $gift['ref_article']        = $gift['ref_article'];
        $gift['nom']                = str_replace($interdit,"",$gift['nom']);
        $gift['prenom']             = str_replace($interdit,"",$gift['prenom']);
        $gift['pseudo']             = $gift['pseudo'];
        $gift['numero']             = trim(str_replace(";",",",str_replace("\\"," ",$gift['numero'])));
        $gift['rue']                = str_replace($interdit,"",$gift['rue']);
        $gift['complement']         = str_replace($interdit,"",$gift['complement']);
        $gift['code_postal']        = $gift['code_postal'];
        $gift['ville']              = str_replace(";",",",str_replace("\\"," ",$gift['ville']));
        $gift['pays']               = $gift['pays'];
        $gift['email']              = Gain::getEmailByIdm($gift['pseudo']);
        $gift['tel']                = str_replace(";",",",str_replace("\\"," ",$gift['tel']));
        $gift['id_instant_gagnant'] = $gift['id_instant_gagnant'];
        $gift['date_gain']          = $date[0];
        $aFilterGifts[] = $gift;
    }
    $this->aFilterGifts = $aFilterGifts;
    if (isset($_POST['export'])) {
        $output = fopen('php://output', 'w');
        $sFileName = 'Fichier_de_logistique.csv';
        header('Content-Disposition: attachement; filename="' . $sFileName . '";');
        header('Content-Type: application/download');
        fwrite($output, "sep=;\n");
        fputcsv($output, array(''Nom', 'Prenom'), ";");
        foreach ($aFilterGifts as $value) {
            fputcsv($output, $value, ";");
        }
        fpassthru($output);
        fclose($output);
    }
    return $this->render('template/customer_service/member/logistique.twig');
}

The .csv is generated, but the problem is that after the array in .csv I have all content .html of page and I don't understand where is the problem.Please help me! Thx in advance

TanGio
  • 766
  • 2
  • 12
  • 34
  • Maybe because you're using `fopen('php://output', 'w')` instead of `$_POST` variables – Machavity May 14 '15 at 18:28
  • He is writing to the output stream, this is perfectly fine. – John Cartwright May 14 '15 at 18:30
  • Sorry, I don't understand the idea – TanGio May 14 '15 at 18:30
  • there isn't any other html in the source you've provided....so it's coming from somewhere else and we have no way of knowing. Some cms do print the header/footer...this could be what's happening but it's impossible to know without more details about where this is being called, ect... – RightClick May 14 '15 at 18:39
  • I edited the question, So after my content in .csv I got and all content of .html – TanGio May 14 '15 at 18:53

4 Answers4

2

The problem problem lies here:

if (isset($_POST['export'])) {
    $output = fopen('php://output', 'w');
    $sFileName = 'Fichier_de_logistique.csv';
    header('Content-Disposition: attachement; filename="' . $sFileName . '";');
    header('Content-Type: application/download');
    fwrite($output, "sep=;\n");
    fputcsv($output, array('Nom', 'Prenom'), ";");
    foreach ($aFilterGifts as $value) {
        fputcsv($output, $value, ";");
    }
    fpassthru($output);
    fclose($output);
}
return $this->render('template/customer_service/member/logistique.twig');

The function writes headers and the content of the CSV file to STDOUT (php://output), but then the whole circus goes on. This function returns content of a template to it's parent function and this probably renderes it to STDOUT as well (using echo, print or something else). The easiest thing to do here (but not the correct) would be to put die(); after fclose($output);:

if (isset($_POST['export'])) {
    $output = fopen('php://output', 'w');
    $sFileName = 'Fichier_de_logistique.csv';
    header('Content-Disposition: attachement; filename="' . $sFileName . '";');
    header('Content-Type: application/download');
    fwrite($output, "sep=;\n");
    fputcsv($output, array('Nom', 'Prenom'), ";");
    foreach ($aFilterGifts as $value) {
        fputcsv($output, $value, ";");
    }
    fpassthru($output);
    fclose($output);
    die();
}
return $this->render('template/customer_service/member/logistique.twig');

The correct way in my opinion is to create a new route and controller action for CSV exports, that has no HTML output.

0

Your question isn't very clear, but it may be you want to terminate the execution of the script after the fclose().

John Cartwright
  • 5,109
  • 22
  • 25
0

its because at some point in the code you may have echo or print something. A better approach would be to write the csv to a file. And then send that file as Content-Disposition: attachment. Like in the code below where file is the path of file.

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
Mudassar Ali
  • 116
  • 1
  • 4
0

fputcsv($output, array(''Nom', 'Prenom'), ";");

typo here - double single quote before Nom.

Kris Zani
  • 216
  • 1
  • 7