問題描述
我想新增一個 「點選下載」 按鈕到我的一個 WordPress 外掛,我不知道使用哪個鉤子。到目前為止,將’admin_init’ 掛接到此程式碼似乎工作:
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
這似乎是有效的,但我只想看看是否有最佳實踐。
謝謝,戴夫
最佳解決方案
如果我正確理解您的意圖,您希望擁有一個如下所示的 URL,那麼對瀏覽器的響應將是您生成的內容,即您的.CSV 檔案,並且沒有從 WordPress 生成的內容?
http://example.com/download/data.csv
我想你正在尋找'template_redirect'鉤。您可以在/wp-includes/template-loader.php 中找到'template_redirect',這是所有 WordPress 開發人員應該熟悉的檔案; 它是短暫和甜蜜,路線每一個 non-admin 頁面載入,所以一定要看看它。
只需將以下內容新增到主題的 functions.php 檔案或 include 在 functions.php 中的另一個檔案中即可:
add_action('template_redirect','yoursite_template_redirect');
function yoursite_template_redirect() {
if ($_SERVER['REQUEST_URI']=='/downloads/data.csv') {
header("Content-type: application/x-msdownload",true,200);
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
透過檢查 $_SERVER['REQUEST_URI']來注意'/downloads/data.csv' URL 的測試。另請注意新增,true,200 到您的 header()呼叫,您設定 Content-type; 這是因為 WordPress 會設定 404 “Not Found” 狀態程式碼,因為它不能識別該 URL 。這是沒有問題的,因為 true 告訴 header()替換 404 WordPress 已經設定並使用 HTTP 200 “Okay” 狀態程式碼。
FireFox 這是什麼樣子 (請注意,螢幕截圖沒有/downloads/虛擬目錄,因為在拍攝和註釋螢幕截圖後,似乎最好新增一個'/downloads/'虛擬目錄):
UPDATE
如果您希望從一個字首為/wp-admin/的 URL 處理下載,以向使用者提供受到登入保護的可視指示,那麼您也可以這樣做:下面描述一種方法。
這次我封裝成一個類,稱為 DownloadCSV,併為 「管理員」 角色建立了一個名為 「download_csv」 的使用者 「功能」(請閱讀此處的角色和功能) 您可以搭載預定義的 「匯出」 角色,如果你喜歡,如果是這樣搜尋& 用’export’ 替換’download_csv’,並刪除 register_activation_hook() 呼叫和 activate() 函式。順便說一句,需要一個啟用鉤子是我把這個移植到外掛而不是保留在主題的 functions.php 檔案中的一個原因。*
我還使用 add_submenu_page()從”Tools” 選單中新增了”Download CSV” 選單選項,並將其連結到'download_csv'功能。
最後我選擇了'plugins_loaded'鉤子,因為它是我可以使用的最早的適當鉤子。你可以使用'admin_init',但這個鉤子執行得比較晚 (第 1130 次鉤子呼叫和第 3 個鉤子呼叫),所以為什麼讓 WordPress 做更多的 throw-away 工作呢? (我用我的 Instrument Hooks plugin 找出要使用的鉤子。)
在鉤子中,我檢查以確保我的 URL 從/wp-admin/tools.php 透過檢查 $ pagenow 變數開始,我驗證 current_user_can(‘download_csv’),如果透過,我測試 $ _GET [‘download’] 看它是否包含資料。 CSV; 如果是,我們幾乎執行與之前相同的程式碼。我也刪除了前面的例子中的來自 header() 的 200 的 true,因為這裡 WordPress 知道這是一個很好的 URL,所以沒有設定 404 狀態。所以這裡是你的程式碼:
<?php
/*
Plugin Name: Download CSV
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
*/
if (!class_exists('DownloadCSV')) {
class DownloadCSV {
static function on_load() {
add_action('plugins_loaded',array(__CLASS__,'plugins_loaded'));
add_action('admin_menu',array(__CLASS__,'admin_menu'));
register_activation_hook(__FILE__,array(__CLASS__,'activate'));
}
static function activate() {
$role = get_role('administrator');
$role->add_cap('download_csv');
}
static function admin_menu() {
add_submenu_page('tools.php', // Parent Menu
'Download CSV', // Page Title
'Download CSV', // Menu Option Label
'download_csv', // Capability
'tools.php?download=data.csv');// Option URL relative to /wp-admin/
}
static function plugins_loaded() {
global $pagenow;
if ($pagenow=='tools.php' &&
current_user_can('download_csv') &&
isset($_GET['download']) &&
$_GET['download']=='data.csv') {
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
}
DownloadCSV::on_load();
}
這裡是啟用的外掛的螢幕截圖:
最後這是一個觸發下載的螢幕截圖:
次佳解決方案
一個更有用的外掛,用於匯出到 CSV 。可能對某些人有用
<?php
class CSVExport
{
/**
* Constructor
*/
public function __construct()
{
if(isset($_GET['download_report']))
{
$csv = $this->generate_csv();
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename="report.csv";" );
header("Content-Transfer-Encoding: binary");
echo $csv;
exit;
}
// Add extra menu items for admins
add_action('admin_menu', array($this, 'admin_menu'));
// Create end-points
add_filter('query_vars', array($this, 'query_vars'));
add_action('parse_request', array($this, 'parse_request'));
}
/**
* Add extra menu items for admins
*/
public function admin_menu()
{
add_menu_page('Download Report', 'Download Report', 'manage_options', 'download_report', array($this, 'download_report'));
}
/**
* Allow for custom query variables
*/
public function query_vars($query_vars)
{
$query_vars[] = 'download_report';
return $query_vars;
}
/**
* Parse the request
*/
public function parse_request(&$wp)
{
if(array_key_exists('download_report', $wp->query_vars))
{
$this->download_report();
exit;
}
}
/**
* Download report
*/
public function download_report()
{
echo '<div class="wrap">';
echo '<div id="icon-tools" class="icon32">
</div>';
echo '<h2>Download Report</h2>';
//$url = site_url();
echo '<p>Export the Users';
}
/**
* Converting data to CSV
*/
public function generate_csv()
{
$csv_output = '';
$table = 'users';
$result = mysql_query("SHOW COLUMNS FROM ".$table."");
$i = 0;
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_assoc($result)) {
$csv_output = $csv_output . $row['Field'].",";
$i++;
}
}
$csv_output .= "n";
$values = mysql_query("SELECT * FROM ".$table."");
while ($rowr = mysql_fetch_row($values)) {
for ($j=0;$j<$i;$j++) {
$csv_output .= $rowr[$j].",";
}
$csv_output .= "n";
}
return $csv_output;
}
}
// Instantiate a singleton of this plugin
$csvExport = new CSVExport();
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。


