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

5
  • Maybe because you're using fopen('php://output', 'w') instead of $_POST variables Commented May 14, 2015 at 18:28
  • He is writing to the output stream, this is perfectly fine. Commented May 14, 2015 at 18:30
  • Sorry, I don't understand the idea Commented May 14, 2015 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... Commented May 14, 2015 at 18:39
  • I edited the question, So after my content in .csv I got and all content of .html Commented May 14, 2015 at 18:53

4 Answers 4

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

2 Comments

The problem is that after the array in .csv is writen the source of page
Sorry, maybe you could try rephrasing it. I'm not understanding.
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;
}

1 Comment

Sorry, I don't understand your idea
0

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

typo here - double single quote before Nom.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.