使用WordPress下载CSV文件的PHP代码

4
我开发了一个用于WordPress的小插件(用于培训)。该插件允许获取表单数据,将其保存到CSV文件中,然后管理员可以下载该文件。
我的问题是我无法下载这个文件。当我点击下载按钮时,它会打开一个download.php页面但没有任何进一步的操作。
我尝试了不同的解决方案,但都没有起作用。这是主文件的代码:
<?php
/*
    Plugin Name: Form to CSV
    Version: 1.0
    Author: Grégory Huyghe
*/


// 1. Shortcode
function ftc_shortcode() {
    readfile("form-to-csv.html", 1);
}

add_shortcode( 'form_csv', 'ftc_shortcode' );

// 1.1 CSS
function ftc_style() {
    wp_register_style('stylesheet', plugins_url('form-to-csv.css', __FILE__));
    wp_enqueue_style('stylesheet');
}

add_action('admin_init', 'ftc_style');


// 2. Onglet plugin dans panneau admin pour voir et télécharger les données collectées
function ftc_menu_item() {
    add_menu_page(
        __( 'Form to CSV', 'textdomain' ),
        'Form to CSV',
        'manage_options',
        'form-to-csv',
        'ftc_menu_plugin',
        'dashicons-portfolio',
        21
    );
}
add_action('admin_menu', 'ftc_menu_item');


// 3. Ecrire les données dans un fichier

// 3.1 Variables
$error = '';
$fname = sanitize_text_field($_POST['prenom']);
$lname = sanitize_text_field($_POST['nom']);
$email = sanitize_email($_POST['email']);
$checkbox = implode(" / ", (array)$_POST['films']);

// 3.2 Clean_text
function clean_text($clean) {
    $trimmed = trim($clean);
    $stripped = stripslashes($clean);
    $special = htmlspecialchars($clean);
    return $clean;
}

// 3.3 Submission form
if(isset($_POST['submit'])) {
    $success = true;

    if(empty($_POST['prenom']) OR empty($_POST['nom']) OR empty($_POST['email'])) {
        $error = '<p>Veuillez réessayer</p>';
    } else {
        $fname = clean_text($_POST['prenom']);
        $lname = clean_text($_POST['nom']);
        $email = clean_text($_POST['email']);
        }

    if($error == '' && $success = true) {

        // Ecriture dans fichier csv
        $file_open = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'a');
        $index = count(file('C:\Users\huygh\Desktop\form-to-csv.csv')); 
        if ($index == 0) {
            $index = $index +1;
        } else if ($index > 0) {
            $index = $index +1;
        }

        $form_data = array(
        'id' => $index,
        'prenom' => $fname,
        'nom' => $lname,
        'email' => $email,
        'films' => $checkbox
    );
        fputcsv($file_open, $form_data);
        header( 'Location: index.php' );
        exit();
    }           
}


// 4. Récupérer ses infos dans un custom post accessible depuis le panneau admin. Pas d'envoi de mail.

// 4.1 Récupérer et  Afficher les données dans l'onglet du plugin

function ftc_menu_plugin() {

//    if (isset($_GET['action']) && $_GET['action'] == 'download') {
//        header('Location: C:\Users\huygh\Desktop\form-to-csv.csv');
//        header('Content-Disposition: attachment; filename="form-to-csv.csv"');
//        header("Content-Type: application/force-download");
//        header("Content-Transfer-Encoding: Binary");
//        header("Pragma: no-cache");
//        header("Expires: 0");
//
//        readfile('form-to-csv.csv');
//        
//        echo "toto";
//    }

    $counter = 0;

    echo "<html><body><table>\n\n";

    // Titres du tableau
    echo "<thead>";
    echo "<tr class=\"titles\">";
    echo "<th>ID</th>";
    echo "<th>Prénom</th>";
    echo "<th>Nom</th>";
    echo "<th>Email</th>";
    echo "<th>Sélection</th>";
    echo "</tr>\n";
    echo "</thead>";

    if (($file_read = fopen('C:\Users\huygh\Desktop\form-to-csv.csv', 'r')) !== FALSE) {
        while (($data = fgetcsv($file_read)) !== FALSE && $counter < 20) {
            echo "<tr>";
            $counter++;
            foreach ($data as $cell) {
                    echo "<td>" . $cell . "</td>";
            }
            echo "</tr>\n";
        }
    }
    fclose($file_read);
    echo "\n</table></body></html>";

    // 4.2 Télécharger ce fichier .csv depuis l'onglet du plugin

    ?>
        <a href="download.php" target="_blank">
            <button class="button__csv">Télécharger fichier CSV</button>
        </a>

        <a href="delete.php" target="blank">
            <button class="button__csv button__csv--delete">Supprimer données</button> 
        </a>
<?php

下载.php的代码如下:

<?php
header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');
readfile('C:\\Users\\huygh\\Desktop\\form-to-csv.csv');

从主文件代码中可以看到,我还尝试了一种不使用download.php页面的解决方案,将a标签编写为以下形式:

<a href="?action=download" target="blank">

但是什么都没起作用。问题是来自头文件吗?还是来自WordPress,需要特定的编写方式?
以下是开发者工具中响应头的截图: enter image description here

1
你为什么要使用 Location 头部? - Jamie_D
Grégory,请在打开download.php时打开Web开发人员工具(F12),刷新页面,在工具中导航到“网络”,过滤“Doc”节点,然后发布响应头和响应本身的屏幕截图? - SaschaM78
@SaschaM78,我刚刚添加了截图。下次编辑时,我会保留之前的代码。 - Grégory Huyghe
1
正如您所看到的,“download.php”找不到,404意味着“页面未找到”。请确保文件确实在“plugins/wp-admin”中。 - SaschaM78
@SaschaM78 很好,它可以工作。我将用你的信息回答我的问题。 - Grégory Huyghe
3个回答

1
正如Jamie_D所提到的,使用Location将会把用户重定向到指定的地址(就像你的3.3提交表单代码块中那样)。
从你的代码块中删除该行,你就可以得到所需的下载页面了。
<?php
header('Content-Disposition: attachment; filename="form-to-csv.csv"');
header('Content-Type: text/csv');
// take care to escape the backslashes properly:
readfile('C:\\Users\huygh\\Desktop\\form-to-csv.csv'); 

关于您的代码的其他评论:

  1. 链接中缺少下划线; 应该是: <a href="download.php" target="_blank">Link</a>

  2. 删除闭合的?php>标签:我看到过一些情况,关闭标签后控制/不可见字符会导致下载问题,因为它们随后被传输为文件内容的一部分。

解决方案

在问题提问者的情况下,问题不是由于向客户端发送的标题不正确,而是指向download.php的路径不正确。


我已经修改了您的代码,但仍然无法运行。我在问题中编辑了代码供您查看。 - Grégory Huyghe
@GrégoryHuyghe 刚刚看到您更改了代码。未来的一个小建议,如果您更新问题,请将更改部分添加到原始问题下方。这有助于保留原始问题,如果其他人遇到类似的问题,他们可以使用您的问题来解决问题。我已在您的问题上方添加了一条评论。 - SaschaM78

0

这里是解决方案,一个简单的错误是download.php文件位置应该在wp-admin文件夹中。

为了将download.php文件保留在插件文件夹中,我为a标签编写了一个相对URL:

<a href="/Plugin/wp-content/plugins/form-to-csv/download.php"

SaschaM78的回答: 正如您所看到的,“download.php”找不到,404表示“页面未找到”。确保文件确实在“plugins/wp-admin”中。- SaschaM78 54分钟前


我在我的回答中包含了解决方案。如果您能将其标记为答案,我将不胜感激 :-)。谢谢,很高兴您找到了解决方案! - SaschaM78
2
@Greogry,这不是在WordPress中访问路径的正确方式,你必须创建动作,然后使用add_action触发这些动作。这种方式存在安全风险。 - Problem Solver
@ProblemSolver 好的,下载的正确操作是什么?初始化吗? - Grégory Huyghe
@GrégoryHuyghe 抱歉,我不太明白你在这里的意思。如果你的意思是将下载操作作为URL参数传递,那么"?action=download"听起来就像是正确的方式。 - SaschaM78

0
你可以使用HTML5的download属性直接下载文件。
<a href="C:\\Users\\huygh\\Desktop\\form-to-csv.csv" download="form-to-csv.csv">download form-to-csv.csv</a>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接