web-dev-qa-db-fra.com

Échec de la génération de fichier CSV

J'utilise un plugin pour un client (que j'ai modifié dans une certaine mesure) qui crée et maintient une base de données des membres de l'organisation (en utilisant une nouvelle table wp pour le faire).

Il existe une fonctionnalité Nice qui effectue une importation et une insertion au format csv et qui fonctionne très bien. Il existe également une fonctionnalité permettant de télécharger le contenu de cette table en tant que csv, qui fonctionne correctement sur mon système local, mais échoue lors de son exécution à partir du serveur. Franchement, je ne sais pas pourquoi.

Le fichier php contenant la logique est simplement lié à. Le fichier:

<?php
    //include some files
    include('../../../wp-blog-header.php');

    //DIAG: phpinfo();   

    function fputcsv4($fh, $arr) {
        $csv = "";
        while (list($key, $val) = each($arr)) {
            $val = str_replace('"', '""', $val);
            $csv .= '"'.$val.'",';
        }
        $csv = substr($csv, 0, -1);
        $csv .= "\n";
        if (!@fwrite($fh, $csv)) 
            return FALSE;
    }

    //get member info and column data
    $table_name = $wpdb->prefix . "member_db";
    $year = date ('Y');
    $members = $wpdb->get_results("SELECT * FROM ".$table_name, ARRAY_A);
    $columns = $wpdb->get_results("SHOW COLUMNS FROM ".$table_name, ARRAY_A);
    //DIAG: echo 'SQL: '.$sql.', RESULT: '.$result.'<br>';

    //output headers
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"members.csv\"");

    //open output stream
    $output = fopen("php://output",'w'); 

    //output column headings
    $data[0] = "ID";
    $i = 1;
    foreach ($columns as $column){
        //DIAG: echo '<pre>'; print_r($column); echo '</pre>';
        $field_name = '';
        $words = explode("_", $column['Field']);
        foreach ($words as $Word) $field_name .= $Word.' ';
        if ( $column['Field'] != 'id' && $column['Field'] != 'date_updated' ) {
            $data[$i] = ucwords($field_name);
            $i++;
        }
    }
    $data[$i] = "Date Updated";
    fputcsv4($output, $data);

    //output data
    foreach ($members as $member){
        //DIAG: echo '<pre>'; print_r($member); echo '</pre>';
        $data[0] = $member['id'];
        $i = 1;
        foreach ($columns as $column){
            //DIAG: echo '<pre>'; print_r($column); echo '</pre>';
            if ( $column['Field'] != 'id' && $column['Field'] != 'date_updated' ) {
                $data[$i] = $member[$column['Field']];
                $i++;
            }
        }
        $data[$i] = $member['date_updated'];
        //echo '<pre>'; print_r($data); echo '</pre>';
        fputcsv4($output, $data); 
    }
    fclose($output);
?>

Donc, nous avons une routine dans laquelle une requête est exécutée, $output est établi avec fopen, ajouté à via des instructions foreach, et enfin fclosed.

L'erreur que je reçois (du serveur) est

Error 6 (net::ERR_FILE_NOT_FOUND): The file or directory could not be found.

Mais il est clair qu’on le trouve, c’est tout simplement son échec. Si j'active phpinfo() (PHP Version 5.2.17) en haut du fichier, j'obtiens une réponse, notamment Cannot modify header information (car phpinfo() a déjà généré un en-tête). Cependant, toutes les données attendues sont imprimées sur la page, de sorte que tout fonctionne au moins correctement.

J'imagine que quelque chose empêche le bon fonctionnement des fonctions fermées et fermées, mais je n'ai pas suffisamment d'expérience en la matière pour identifier exactement le problème.

Je noterai à nouveau que cela fonctionne exactement comme prévu dans mon environnement de test (localhost/XAMPP, netbeans).

Toutes les pensées seraient les plus appréciées.

1
Bosworth99

Essaye ça:

<?php
   header("Content-type: application/csv");
   header('Content-Disposition: inline; filename="export.csv"'); // change this filename
   include ('../../../wp-load.php'); // may need to change number of "../" depending upon location
   global $wpdb;
   $rows = $wpdb->get_results ("SELECT * FROM {$wpdb->prefix}table_name"); // change the table name
   echo strtolower(implode(',', array_keys((array)$rows[0]))) . "\r\n"; // fixes an Excel bug if the first column is "ID"
   foreach($rows as $row) echo '"' . implode ('","', array_values((array)$row)) . '"' . "\r\n";
?>

Cela formatera automatiquement le contenu entier de la table en tant que CSV et diffusera le téléchargement directement dans le navigateur, ce qui ouvrira une boîte de dialogue invitant l'utilisateur à enregistrer le fichier.

1
JMichael