實現AJAX通信所需的服務器端PHP腳本有兩個部分。 首先,我們需要在網頁上排列jQuery腳本,并本地化jQuery腳本需要的任何PHP值。 其次是AJAX請求的實際處理。
## 入隊腳本
本部分介紹了WordPress中AJAX的兩大難點,它將經驗豐富的編程人員新增至WordPress。 一個是需要排入腳本,以便獲得元鏈接在頁面的頭部分中正確顯示。 另一個是所有AJAX請求需要通過wp-admin / admin-ajax.php發送。 不要將請求直接發送到您的插件頁面。
## 排隊
使用函數wp_enqueue_script()讓WordPress在頁面的部分插入一個元鏈接到您的腳本。 不要在標題模板中硬編碼這樣的鏈接。 作為一個插件開發人員,您沒有準備好訪問標題模板,但是這個規則不管怎么說。
入隊功能有三個參數。 第一個是用于在其他功能中引用腳本的任意標簽或句柄。 第二個是腳本文件的完整URL。 為了便于攜帶,請使用plugins_url()來構建正確的URL。 如果你為插件之外的東西排隊腳本,使用一些相關的功能創建一個正確的URL - 從來沒有硬編碼。 第三個參數是腳本依賴的任何腳本標記的數組。 由于我們使用jQuery發送一個AJAX請求,所以至少需要在數組中列出'jquery'。 始終使用數組,即使它是單個依賴項。 我們的示例的入隊呼叫如下所示:
```
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array('jquery')
);
```
加載腳本時,您無法直接從插件代碼頁排入腳本。 腳本必須從幾個動作鉤子之一排隊 - 哪一個取決于腳本需要鏈接到哪個頁面。 對于管理頁面,請使用admin_enqueue_scripts。 對于前端頁面使用wp_enqueue_scripts,除了登錄頁面,在這種情況下使用login_enqueue_scripts。
admin_enqueue_scripts鉤子將當前頁面文件名傳遞給您的回調。 使用此信息僅將腳本排列在需要的頁面上。 前端版本沒有通過任何內容。 在這種情況下,使用模板標簽(如is_home(),is_single()等)來確保您只需將腳本排列在需要的位置。 這是我們的示例的完整的入隊代碼:
```
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' != $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
);
}
```
為什么我們在這里使用命名函數,但是使用jQuery的匿名函數?因為閉包最近才被PHP支持。 jQuery已經支持了很多時間。由于有些人可能仍在運行舊版本的PHP,因此我們總是使用命名函數來實現最大的兼容性。如果您有最新的PHP版本,并且僅針對您自己的安裝開發,請繼續使用閉包。
##注冊與入隊
您將在其他教程中看到宗教使用wp_register_script()的示例。這很好,但它的使用是可選的。什么是不可選的是wp_enqueue_script()。必須調用此函數才能使您的腳本文件在網頁上正確鏈接。那么為什么要注冊腳本?它創建一個有用的標簽或句柄,您可以根據需要輕松地在代碼的各個部分中引用該腳本。如果您只需要加載腳本,而不是在代碼中的其他地方引用它,則無需注冊。
##隨機
您需要創建一個隨機數,以便jQuery AJAX請求可以被驗證為合法請求,而不是來自某個未知的壞行為者的潛在的惡意請求。只有你的PHP腳本和你的jQuery腳本才能知道這個值。收到請求后,您可以驗證它是在此創建的相同值。這是為了創建一個我們的例子的隨機數
```
$title_nonce = wp_create_nonce( 'title_example' );
```
參數title_example可以是任意任意的字符串。 建議字符串與所使用的內容相關,但它可以是適合您的任何東西。
##本地化
如果您從jQuery部分回想起,由jQuery創建的由jQuery創建的數據被傳遞給一個名為my_ajax_obj的全局對象。 在我們的示例中,此數據是一個隨機數,并且是admin-ajax.php的完整URL。 分配對象屬性和創建全局jQuery對象的過程稱為本地化。 這是我們使用wp_localize_script()的示例中使用的本地化代碼。
```
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce, // It is common practice to comma after
) ); // the last array item for easier maintenance
```
>[info] 注意我們的腳本如何處理ajax腳本被使用,以便將全局對象分配給正確的腳本。 對象對我們的腳本是全局的,而不是所有的腳本。 也可以從用于排入腳本的同一個鉤子調用本地化。 創建一個隨機數也同樣如此,盡管這個特定的功能可以在幾乎任何地方被調用。 所有這些組合在一起的單個鉤子回調看起來像這樣:
```
add_action( 'admin_enqueue_scripts', 'my_enqueue' );
function my_enqueue( $hook ) {
if( 'myplugin_settings.php' != $hook ) return;
wp_enqueue_script( 'ajax-script',
plugins_url( '/js/myjquery.js', __FILE__ ),
array( 'jquery' )
);
$title_nonce = wp_create_nonce( 'title_example' );
wp_localize_script( 'ajax-script', 'my_ajax_obj', array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
) );
}
```
## AJAX行動
服務器端PHP代碼的另一個主要部分是接收POSTed數據的實際AJAX處理程序,執行一些操作,然后將相應的響應發送回瀏覽器。 這采用WordPress動作鉤子的形式。 您使用哪個掛鉤標簽取決于用戶是否登錄,并且您的jQuery腳本作為action:value傳遞的值是多少。
>[info] 注意:$_GET , $_POST and $_COOKIE vs $_REQUEST
您可能已經使用一個或多個PHP超級全局變量(如$ _GET或$ _POST)從表單或Cookie(使用$ _COOKIE)檢索值。也許你更喜歡$ _REQUEST,或至少看過它使用。這很酷 - 無論請求方法,POST或GET,它將具有表單值。適用于使用這兩種方法的頁面。除此之外,它還具有cookie值。一站式購物!其中有它的悲劇性缺陷。在名稱沖突的情況下,cookie值將覆蓋任何表單值。因此,糟糕的演員在他們的瀏覽器上制作一個假冒的cookie是非常容易的,這將覆蓋您可能期望的請求的任何表單值。 $ _REQUEST是黑客將任意數據注入到表單值中的簡單路徑。要特別安全,堅持特定的變量,避免一切都適合。
由于我們的AJAX交換是用于插件的設置頁面,所以用戶必須登錄。如果從jQuery部分回想起來,action:value是“my_tag_count”。這意味著我們的動作鉤子標簽將是wp_ajax_my_tag_count。如果我們的AJAX交換機被當前未登錄的用戶使用,則動作掛鉤標簽將是wp_ajax_nopriv_my_tag_count用于掛起動作的基本代碼如下所示:
```
add_action( 'wp_ajax_my_tag_count', 'my_ajax_handler' );
function my_ajax_handler() {
// Handle the ajax request
wp_die(); // All ajax handlers die when finished
}
```
您的AJAX處理程序應該做的第一件事情是驗證jQuery與check_ajax_referer()發送的隨機數,該值應與腳本入隊時本地化的值相同。
```
check_ajax_referer( 'title_example' );
```
提供的參數必須與之前提供的參數wp_create_nonce()相同。 如果隨機數不檢出,該函數就會死機。 如果這是一個真正的現在,現在使用它,這個價值不再是好的。 然后,您將生成一個新的并將其發送到回調腳本,以便它可以用于下一個請求。 但是由于WordPress的內容有二十四個小時的好處,所以你不需要做任何事情,但檢查它。
##數據
隨著nonce不可用,我們的處理程序可以處理由$ _POST ['title']中包含的jQuery腳本發送的數據。 我們可以使用update_user_meta()將用戶的選擇保存在用戶元中。
```
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title']);
```
然后,我們構建一個查詢以獲取所選標題標簽的發布數。
```
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
```
最后我們可以將響應發送回jQuery腳本。有幾種傳輸數據的方法。在我們處理我們的例子的細節之前,我們來看一些選項。
## XML
對XML的PHP??支持留下了一些希望。幸運的是,WordPress提供了WP_Ajax_Response類,使任務更容易。 WP_Ajax_Response類將生成XML格式的響應,為標題設置正確的內容類型,輸出響應xml,然后死 - 確保正確的XML響應。
## JSON
這種格式是輕量級和易于使用的,WordPress提供的wp_send_json函數來json編碼您的響應,打印它,并死 - 有效地替換WP_Ajax_Response。 WordPress還提供了wp_send_json_success和wp_send_json_error函數,這些函數允許在JS中觸發適當的done()或fail()回調。
##其他
只要發送者和接收者協調一致,就可以傳輸任何你喜歡的數據。諸如逗號分隔或制表符分隔的文本格式是許多可能性之一。對于少量的數據,發送原始流可能是足夠的。這就是我們將使用我們的例子 - 我們將發送實際的替換HTML,沒有別的。
```
echo $_POST['title'].' ('.$the_query->post_count.') ';
```
在現實世界的應用程序中,您必須考慮到由于某種原因可能會失敗的可能性 - 例如,數據庫服務器可能已關閉。 響應應該允許這種偶然性,并且接收響應的jQuery腳本應該相應地行動,或許告訴用戶稍后再試。
## die
當處理程序完成所有任務時,它需要死機。 如果您使用WP_Ajax_Response或wp_send_json *函數,則會自動為您處理。 如果沒有,只需使用WordPress wp_die()函數。
```
wp_die();
// That's all folks!
```
## AJAX處理者總結
我們的示例的完整AJAX處理程序如下所示:
```
//JSON
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
wp_send_json( $_POST['title'] . ' (' . $the_query->post_count . ') ' );
}
//Other
function my_ajax_handler() {
check_ajax_referer( 'title_example' );
update_user_meta( get_current_user_id(), 'title_preference', $_POST['title'] );
$args = array(
'tag' => $_POST['title'],
);
$the_query = new WP_Query( $args );
echo $_POST['title'].' ('.$the_query->post_count.') ';
wp_die(); // All ajax handlers should die when finished
}
```
- 簡介
- 主題開發
- WordPress許可證
- 什么是主題
- 開發環境
- 主題開發示例
- 主題基礎
- 模板文件
- 主樣式表(style.css)
- 文章類型
- 規劃主題文件
- 模板層級
- 模板標簽
- 循環
- 主題函數
- 連接主題文件和目錄
- 使用CSS和JavaScript
- 條件標簽
- 類別,標簽和自定義分類
- 模板文件
- 內容模板文件
- 頁面模板文件
- 附件模板文件
- 自定義內容類型
- 部分和其他模板文件
- 評論模板
- 分類模板
- 404頁面
- 主題功能
- 核心支持的功能
- 管理菜單
- 自定義Headers
- 自定義Logo
- 文章格式
- 置頂文章
- Sidebars
- Widgets
- 導航菜單
- 分頁
- 媒體
- Audio
- Images
- Galleries
- Video
- 精選圖片和縮略圖
- 國際化
- 本地化
- 輔助功能
- 主題選項 – 自定義API
- 定制對象
- 改進用戶體驗的工具
- 定制JavaScript API
- JavaScript / Underscore.js渲染的自定義控件
- 高級用法
- 主題安全
- 數據消毒/逃避
- 數據驗證
- 使用隨機數
- 常見漏洞
- 高級主題
- 子主題
- UI最佳實踐
- JavaScript最佳做法
- 主題單元測試
- 驗證你的主題
- Plugin API Hooks
- 發布你的主題
- 所需的主題文件
- 測試
- 主題評論指南
- 寫文檔
- 提交你的主題到WordPress.org
- 參考文獻
- 模板標簽列表
- 條件標簽列表
- 編碼標準
- HTML編碼標準
- CSS編碼標準
- JavaScript編碼標準
- PHP編碼標準
- 插件開發
- 插件開發簡介
- 什么是插件
- 插件基礎
- 頭部要求
- 包括軟件許可證
- 啟用 / 停用 Hooks
- 卸載方法
- 最佳做法
- 插件安全
- 檢查用戶功能
- 數據驗證
- 保護輸入
- 保護輸出
- 隨機數
- Hooks
- Actions
- Filters
- 自定義Hooks
- 高級主題
- 管理菜單
- 頂級菜單
- 子菜單
- 短代碼
- 基本短碼
- 封閉短碼
- 帶參數的短代碼
- TinyMCE增強型短碼
- 設置
- 設置API
- 使用設置API
- 選項API
- 自定義設置頁面
- 元數據
- 管理帖子元數據
- 自定義元數據
- 渲染元數據
- 自定義文章類型
- 注冊自定義文章類型
- 使用自定義文章類型
- 分類
- 使用自定義分類
- 在WP 4.2+中使用“split術語”
- 用戶
- 創建和管理用戶
- 使用用戶元數據
- 角色和功能
- HTTP API
- JavaScript
- jQuery
- Ajax
- 服務器端PHP和入隊
- Heartbeat API
- 概要
- 計劃任務
- 了解WP-Cron計劃
- 安排WP-Cron 事件
- 將WP-Cron掛接到系統任務計劃程序中
- WP-Cron簡單測試
- 國際化
- 本地化
- 如何國際化您的插件
- 國際化安全
- WordPress.org
- 詳細插件指南
- 規劃您的插件
- 如何使用Subversion
- 插件開發者常見問題
- 開發工具
- Debug Bar 和附加組件
- 輔助插件
- REST API手冊
- 資源
- 文章
- 文章修訂
- 文章類型
- 文章狀態
- 類別
- 標簽
- 頁面
- 評論
- 分類
- 媒體
- 用戶
- 設置
- 使用REST API
- 全局參數
- 分頁
- 鏈接和嵌入
- 發現
- 認證
- 經常問的問題
- 骨干JavaScript客戶端
- 客戶端庫
- 擴展REST API
- 添加自定義端點
- 自定義內容類型
- 修改回應
- 模式
- 詞匯表
- 路由和端點
- 控制器類