I am trying to use PHP headers() in WordPress to download files from my plugin page view , but it is not working as this error message is returned for each header line present in my script:
Warning: Cannot modify header information - headers already sent by (output started at D:\\xampp\\wordpress\\wp-includes\\formatting.php:5100) in D:\\xampp\\wordpress\\wp-content\\plugins\\pxw-test\\pxw-test.php on line 33
And so on for each line of present headers(); in my script...
You can have a look at the pxw-test.php file content (the plugin itself) below:
<?php
/*
Plugin Name: Test Headers
Description: Download File Test Plugin for Headers Response errors.
Version: 1.0
Author: Tester
Text Domain: pxw_test
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
//Admin Menu
function pxw_test_menu() {
// Create custom top-level menu
add_menu_page(
'Dashboard',
'Test Headers',
'manage_options',
'pxw_test',
'pxw_test_dashboard_page',
null,
20
);
}
//Function needed to display top-level page as the main page
function pxw_test_dashboard_page(){
// Download
if(isset($_POST['download'])){
// File to download
$filename = 'file.txt';
// HTTP headers for downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize(plugin_dir_path(__FILE__).$filename));
//You can try the following
// while (ob_get_level()) {
// ob_end_clean();
// }
// @readfile(plugin_dir_path(__FILE__).$filename);
}
else {
}
?>
<form action="" method="POST" enctype="multipart/form-data" style="text-align:center;padding: 100px 0;">
<button type="submit" onclick="this.form.submit();" style="background:red;padding:10px;color:#fff;cursor:pointer;"><b>Download File</b></button>
<input type="hidden" name="download" />
</form>
<?php
} # End of function pxw_test_dashboard_page().
// Finally display the menu
add_action('admin_menu', 'pxw_test_menu');
?>
My goal is to download a file and delete the file after download.
Of course I am not looking for:
A function.php solution as I am building a plugin.
But anything short and manageable from my plugin folder is welcomed.
Such as:
PHP
JavaScript
jQuery
HTML5, such as <iframe>
, but not the <a download></a>
as I will need to make actions such as deleting the file after download and if the file was downloaded or not.
I understand now that while being inside the function, PHP headers are initiated by the function and stopped when the function ends.
function pxw_test_dashboard_page(){
// You can not use header() here!
// For example when you include a PHP file here to display your page view,
// you have to separate you headers function in a external file
//then display the output in your file view.
}
So the best solution I have found instead of many trouble hacks is to add:
ob_start();
Somewhere at the beginning of the PHP tags and outside your functions.
Here is the full working Code :
Plugin folder: pxw-test
Plugin folder content:
pxw-test.php
file.txt - Just a file with something inside
pxw-test.php
<?php
/*
Plugin Name: Test Headers
Description: Download File Test Plugin for Headers Response errors.
Version: 1.0
Author: Tester
Text Domain: pxw_test
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ){
exit;
}
// Fix PHP headers
ob_start();
// Set DB version
//global $pxw_test_db_version;
$pxw_test_db_version = '1.0';
// Admin menu
function pxw_test_menu() {
//create custom top-level menu
add_menu_page(
'Dashboard',
'Test Headers',
'manage_options',
'pxw_test',
'pxw_test_dashboard_page',
null,
20
);
}
// Function needed to display top-level page as the main page
function pxw_test_dashboard_page() {
$target_dir = plugin_dir_path( __FILE__);
// Download
if(isset($_POST['download'])){
// File To Download
$filename = 'file.txt';
// HTTP headers for downloads
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$filename");
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($target_dir.$filename));
while (ob_get_level()) {
ob_end_clean();
@readfile($target_dir.$filename);
}
// Do something else after download like delete file
unlink($target_dir.$filename);
}
else{
}
?>
<form action="" method="POST" enctype="multipart/form-data" style="text-align:center;padding: 100px 0;">
<button type="submit" onclick="this.form.submit();" style="background:red;padding:10px;color:#fff;cursor:pointer;"><b>Download File</b></button>
<input type="hidden" name="download" />
</form>
<?php
} # End of function pxw_test_dashboard_page()
// Finally display the menu
add_action('admin_menu', 'pxw_test_menu');
?>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.