首頁 > 後端開發 > php教程 > 靈活的API設計:為您的PHP API管道創建鉤子

靈活的API設計:為您的PHP API管道創建鉤子

Joseph Gordon-Levitt
發布: 2025-02-08 10:57:09
原創
340 人瀏覽過

靈活的API設計:為您的PHP API管道創建鉤子

設計應用程序編程接口(API)可能是一項具有挑戰性的努力。良好的API具有簡單易用的簡單接口。在這個簡單的接口背後可以是許多複雜的系統交互,這些交互實際上可能會使原本明確定義的端點任務的水域變得混亂。隨著時間的流逝,可能會要求開發人員為現有終點“了解”其他業務邏輯。然後,在您不知不覺中,作為主要流程的一部分,一個API調用正在與十幾個系統進行交互。

>如果我們可以開發一個簡單的管道,但是可以在以後添加其他任務而不掩蓋主流量的情況下添加其他任務,那不是很好嗎?本文將向您展示如何從WordPress和編程中調整一個想法,以使您的API能夠進行更強大的互動。

>

鑰匙要點

  • >利用PHP API中的掛鉤來增強靈活性並通過允許在不更改核心端點代碼的情況下動態添加其他功能來保持乾淨的主流量。 > 通過定義添加,刪除和触發這些鉤子的全局函數來實現掛鉤,這些鉤可在API的不同部分中使用,從而確保對主要應用程序邏輯的最小破壞。
  • >考慮將鉤子放在API生命週期內的戰略點上,例如成功的數據庫插入或請求驗證期間,根據API的狀態或操作有條件地執行其他任務。
  • > 通過保持與掛鉤相關的回調精益,以避免性能瓶頸,隔離回調功能以簡化調試,並註意維持API響應的主動回調數量。
  • >保持與開發人員社區的互動,以接收反饋和要求新掛鉤的請求,這可能會導致API的功能和靈活性不斷提高,從而輕鬆地適應新的業務需求而無需進行大量重寫。
  • >
  • 什麼是掛鉤/動作?
  • >鉤子(又稱操作/過濾器)是WordPress社區給事件及其相關回調的名稱。如果您在編程方面有任何經驗,那麼您可能熟悉回調和發布者 - subscriber模式。在處理過程中,系統可能會觸發一個事件,該事件將零歸為零,以訂閱該事件的許多功能。例如,在響應加載頁面時,WordPress呼籲加載標題,加載標題,列出帖子或查找正確模板的功能。這些任務是在不混亂生成頁面的主要過程的情況下運行的。
  • >

    鉤背後的想法並不是什麼新鮮事物,也不是WordPress發明的。但是,WordPress在其服務器端處理生命週期期間實現了它們,做得很好。在我看來,這種鉤子的使用可能是平台擁有的最大功能。使用這些掛鉤,用戶可以編寫自己的功能(無論是插件還是主題),可以將其連接到WordPress中,並在需要時運行您想要的任何代碼。您需要更改發送給用戶的標頭嗎?沒問題:進入WP_headers事件,您可以在發現合適的情況下更改標題。

    為什麼在API中使用鉤?

    >鉤子對許多事情都有好處,包括觸發某些側面任務,通過PHP curl命令召集另一個系統,構建對象並將其放入任務隊列中,以後再由另一個系統撿起,發送電子郵件,發送電子郵件,發送電子郵件還有更多。這一切都可以完成,而無需蒙蔽給定端點的主要流(並且可能在此過程中強迫新的API版本)。

    如果端點是用於創建用戶的終點,我們可以專注於在數據庫中創建該用戶記錄,並在此過程中召集在此過程中正在偵聽的任何人。也許在創建用戶記錄之後,我們發出了一個事件,上面寫著“任何人都在聽此操作,我只是創建了一個用戶,這是他們的信息”。也許某些回調功能已經訂閱了該事件,並且正在聽,或者也沒有。該活動並不真正在乎。

    >使用此系統,我們可以將API呼喚到可能在以後的某個時間編寫的代碼。我們可以做到這一點,而無需觸摸API端點代碼本身。為了證明這可能是如何工作的,讓我們更改齒輪,並展示如何以PHP API開始實現這一目標的基本機制。請記住,當我們在此處使用PHP時,我們實際上可以使用其他語言在Web應用程序中實現類似的邏輯。

    構建基本機制

    為了開始,我們需要能夠添加一個鉤子/操作(從現在開始我將其稱為“鉤子”)。我們還需要能夠卸下鉤子並觸發鉤子的能力。定義這些機制後,我們只需要確保它們包含在API中,然後在API中找到可能需要調用這些鉤子的位置即可。以下是我們可能想設置此的一種方式。

    這是hooks.php:

    >現在我們已經創建了hooks.php文件,我們只需要將其包含在我們的API中,以便可以看到這些功能。完成此操作後,這只是使用DO_HOOK將鉤子插入我們的API的問題。

<span>// Global array which will hold all of our hooks
</span><span>// We will reference this array in each function to add/remove/call our hooks
</span><span>// The code below should also be seen by any callbacks we write for the system later.
</span><span>$hooks = [];
</span>
<span>// Below are global functions that can be seen from our API code
</span><span>// The add_hook method will allow us to attach a function (callback) to a given event name 
</span><span>function add_hook($event_name, $callback) {
</span>    <span>global $hooks;
</span>
    <span>if ($callback !== null) {
</span>        <span>if ($callback) {
</span>          <span>// We can set up multiple callbacks under a single event name
</span>            <span>$hooks[$event_name][] = $callback;
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
<span>// Super easy to implement, we remove the given hook by its name
</span><span>function remove_hook($event_name) {
</span>    <span>global $hooks;
</span>
    <span>unset($hooks[$event_name]);
</span><span>}
</span>
<span>// When we want to trigger our callbacks, we can call this function 
</span><span>// with its name and any parameters we want to pass.
</span><span>function do_hook($event_name, ...$params) {
</span>    <span>global $hooks;
</span>
    <span>if (isset($hooks[$event_name])) {
</span>      <span>// Loop through all the callbacks on this event name and call them (if defined that is)
</span>      <span>// As we call each callback, we given it our parameters.
</span>        <span>foreach ($hooks[$event_name] as $function) {
</span>            <span>if (function_exists($function)) {
</span>                <span>call_user_func($function, ...$params);
</span>            <span>}
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
登入後複製
登入後複製
登入後複製
作為一個簡單的例子,假設我們有一個用於使用系統註冊新用戶的API。我們可能有一個REST API端點,稱為 /adduser。以簡單性的名義,我們還假設這裡的目標是將新用戶的名稱和年齡插入我們的數據庫用戶表中。很簡單,對嗎?

>

<span>// Global array which will hold all of our hooks
</span><span>// We will reference this array in each function to add/remove/call our hooks
</span><span>// The code below should also be seen by any callbacks we write for the system later.
</span><span>$hooks = [];
</span>
<span>// Below are global functions that can be seen from our API code
</span><span>// The add_hook method will allow us to attach a function (callback) to a given event name 
</span><span>function add_hook($event_name, $callback) {
</span>    <span>global $hooks;
</span>
    <span>if ($callback !== null) {
</span>        <span>if ($callback) {
</span>          <span>// We can set up multiple callbacks under a single event name
</span>            <span>$hooks[$event_name][] = $callback;
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
<span>// Super easy to implement, we remove the given hook by its name
</span><span>function remove_hook($event_name) {
</span>    <span>global $hooks;
</span>
    <span>unset($hooks[$event_name]);
</span><span>}
</span>
<span>// When we want to trigger our callbacks, we can call this function 
</span><span>// with its name and any parameters we want to pass.
</span><span>function do_hook($event_name, ...$params) {
</span>    <span>global $hooks;
</span>
    <span>if (isset($hooks[$event_name])) {
</span>      <span>// Loop through all the callbacks on this event name and call them (if defined that is)
</span>      <span>// As we call each callback, we given it our parameters.
</span>        <span>foreach ($hooks[$event_name] as $function) {
</span>            <span>if (function_exists($function)) {
</span>                <span>call_user_func($function, ...$params);
</span>            <span>}
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
登入後複製
登入後複製
登入後複製

上面的代碼是我們如何添加新用戶的過度簡單和普遍的視圖。這個想法是,如果某人打電話給我們的API /Adduser端點,他們最終將在此功能中得出此功能,從而將用戶的名稱和年齡從已發布的數據中提取出來。我們首先檢查以確保他們發布(作為適當的休息規則規定),然後嘗試將用戶插入用戶表中。

接下來,如果成功插入了用戶,我們想調用鉤子,以使任何創建用戶的代碼偵聽(這類似於用其他語言提出事件)。

當需求變化時該怎麼辦

幾個月後,我們讓我們的營銷部門堅持認為,當創建新用戶時,應將電子郵件發送給用戶的詳細信息。我們可能傾向於將助手功能寫入API,然後從此端點代碼中調用它。太好了……如果這就是要求的。但是,如果支持團隊後來來到您身邊,並希望您還將用戶添加到他們的Zendesk系統中。因此,您還編寫另一個功能,並將其撥打到此端點。

接下來,您知道,此端點不僅是將用戶添加到我們的網站數據庫中,而且還呼籲發送電子郵件,將用戶添加到Zendesk,Jira和Microsoft Cloud,然後處理其成功/失敗結果。所有這些其他東西確實從將用戶添加到我們的數據庫的清晰點中。我們想調用一個事件,並讓其他代碼在創建用戶並做自己的事情時聆聽 - 而無需我們修改此端點。也許沒有其他服務在乎添加新用戶,因此沒有人被要求做任何事情。終點不必關心。很棒,對

>讓我們以鉤子的名字來繼續我們的榜樣。這是所有回調代碼都需要使用的名稱。同樣,其他語言將此設置稱為“事件”,因此請務必用給定的語言查找它以了解更多信息。

我們將調用hook add_user。簡單而直截了當,你不覺得嗎?一旦有名,我們就可以決定要在哪裡稱呼此鉤子。我認為成功插入後是個好主意:

<span>// POST endpoint for adding a user (part of a larger API class)
</span><span>public function addUser($name, $age) {
</span>  <span>if ($this->request->method === 'post') {
</span>    <span>try {
</span>      <span>$this->db->insert('users', ['name' => $name, 'age' => $age]);
</span>      <span>return new Response(200, 'User created successfully!');
</span>    <span>} catch (Exception $e) {
</span>      <span>// Oops, something went wrong.
</span>      <span>// Do some logging or whatever.
</span>    <span>}
</span>  <span>}
</span>
  <span>// If not a POST request, return http status 400
</span>  <span>return new Response(400, 'Bad request');
</span><span>}
</span>
登入後複製

>現在,我們可以有數十個回調函數收聽添加_user鉤或根本沒有。也許我們有一個回調,負責將用戶插入Zendesk,而另一個將插入姓名和年齡並為營銷生成電子郵件。只要可以在API項目中看到hooks.php代碼,就可以在代碼庫中的其他地方生活。我通常將回調函數放在單獨的文件中,並將該文件也包括在API中。以下是回調的一個示例,現在可以利用我們創建的這個新鉤子:

<span>// Global array which will hold all of our hooks
</span><span>// We will reference this array in each function to add/remove/call our hooks
</span><span>// The code below should also be seen by any callbacks we write for the system later.
</span><span>$hooks = [];
</span>
<span>// Below are global functions that can be seen from our API code
</span><span>// The add_hook method will allow us to attach a function (callback) to a given event name 
</span><span>function add_hook($event_name, $callback) {
</span>    <span>global $hooks;
</span>
    <span>if ($callback !== null) {
</span>        <span>if ($callback) {
</span>          <span>// We can set up multiple callbacks under a single event name
</span>            <span>$hooks[$event_name][] = $callback;
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
<span>// Super easy to implement, we remove the given hook by its name
</span><span>function remove_hook($event_name) {
</span>    <span>global $hooks;
</span>
    <span>unset($hooks[$event_name]);
</span><span>}
</span>
<span>// When we want to trigger our callbacks, we can call this function 
</span><span>// with its name and any parameters we want to pass.
</span><span>function do_hook($event_name, ...$params) {
</span>    <span>global $hooks;
</span>
    <span>if (isset($hooks[$event_name])) {
</span>      <span>// Loop through all the callbacks on this event name and call them (if defined that is)
</span>      <span>// As we call each callback, we given it our parameters.
</span>        <span>foreach ($hooks[$event_name] as $function) {
</span>            <span>if (function_exists($function)) {
</span>                <span>call_user_func($function, ...$params);
</span>            <span>}
</span>        <span>}
</span>    <span>}
</span><span>}
</span>
登入後複製
登入後複製
登入後複製

我們可以在哪裡放置這些鉤子?

在上面的代碼中,我們在單個端點中使用鉤子演示。僅在調用 /adduser端點時才觸發此鉤子,並且只有在插入成功後才觸發。但這不是您唯一可以使用這些鉤子的地方。也許您在API類中有一些路由代碼,可以通過檢查API密鑰是否有效,或者您甚至收到某種類型的請求。

>您可以在API中的全球級別上放置一個鉤子,以便每個請求觸發它。然後,在以後的某個時間,有人可以編寫一個記錄器,將其附加到您創建的API_Init掛鉤上,然後突然開始記錄對API的所有請求,同樣,不是觸摸主API類代碼。同樣的鉤子還可能附加一個回調,如果它開始看到有人用請求猛擊您的API,則可以檢查API濫用並將其報告給您的信息技術部門。

下面的圖像是所有這些圖表的圖表。

靈活的API設計:為您的PHP API管道創建鉤子>由於您可以在多個位置使用此機制,因此您甚至可以在API端點的開頭,中間和結尾處使用鉤子。您還可以在處理請求的整個API生命週期的各個點上有鉤子。這實際上取決於您在插入這些do_hook呼叫的位置上的設計。

>

最佳實踐

>現在讓我們介紹一些最佳實踐,以供您和您的開發人員遵循。

>提示1:保持鉤子瘦弱和平均

>

>要記住的一件事是,這些掛鉤仍然會呼喚將在單個線程中執行的代碼。除非您在回調中觸發某些內容將任務踢到某些背景過程或其他服務,否則API仍將運行此額外的代碼(觸發鉤子時)。這意味著我們應該盡最大努力保持任何回調代碼精益和卑鄙。長期運行的回調代碼將減慢端點或整個API。

>提示2:使每個回調隔離且易於調試

>但是,通過設計該結構的方式,為您的鉤子添加和刪除回調功能很容易做,並且調試同樣容易。查找哪個回調是罪犯(也許每個回調記錄一些數據),並找出卡住的位置。然後,在錯誤修復或通過回調代碼工作之前,根本沒有訂閱鉤子,又不觸摸端點/API代碼中的任何內容,而不會阻止您的API代碼在生產中運行。

提示3:考慮性能,不要濫用鉤子

>請注意您在鉤子上附加多少個回調也很重要。少數幾個快速回調是可以的,但是單個掛鉤上的100個回調,每秒鐘執行一秒鐘確實可以阻止您的API。我們需要快速的API調用,並且每個回調都可以輕鬆拖動響應時間。同樣,如果您發現回調速度慢,請將任務扔到背景過程或隊列系統中,以後將由另一個服務撿起。我經常在Laravel之類的系統中使用工作來處理此類任務。也許將用戶任務添加到Laravel作業隊列中,然後繼續進行API處理。

>

提示4:與您的開發社區保持聯繫 最後,確保您與可能使用這些掛鉤的開發人員保持聯繫。通常,開發人員使用您的鉤子和編寫回調,與創建API中創建鉤子的人並不是一開始。隨著API的成熟,您可能會開始看到在不同地方添加更多鉤子和更精細的粒度的請求。他們可能會要求在插入用戶之前和之後插入用戶之前/之後的掛鉤之前/之後。他們還可能要求將其他信息傳遞給他們的回調(不僅是他們的名稱和年齡,還包括插入用戶的新ID)。以這些要求為一個好兆頭,表明您的開發人員發現該機制有用,並看到擴大API在相關係統中的影響的潛力。擁有一個非常容易“掛接”並執行一小塊代碼以產生巨大影響的系統真的感覺很好。

>

使用這種方法,天空是您可以擁有的API所做的限制。在與其他系統打交道時,這一切都可以實現,同時保持端點的主要流量清晰,沒有噪音。

結論

在本文中,我們討論了什麼是鉤子/動作以及如何使用它們。我們提供了一些示例PHP代碼,您可以在PHP API中使用這些代碼來實現“鉤”,以及如何使用回調將其綁在該鉤子中。我們還討論了在一般API級別(全球範圍內更多)以及端點上添加鉤子。除此之外,我們還討論了該系統的一些缺點,並且可以使您的回調變得精明和卑鄙,這是一個好主意。但是,如果您確實有一個長期運行的回調,我們提到了一些處理此類流程以防止它們影響您的API管道的策略。

如果您實現了此系統,則您也可以獲得WordPress社區(以及總體程序員)多年來所享受的一些最大功能。您還可以節省很多時間和頭痛,從必須直接修改API代碼,並且可以專注於小回調代碼。您還可以添加和刪除可能與其他系統的整個集成在一起的回調。所有這些功能 - 不必重新發布您的API管道代碼!這是一個很好的交易,對吧?有了這個系統,我一天都設法進行了一些簡單的集成,現在您也可以做到。

>

感謝您的閱讀!

關於靈活的API設計和PHP掛鉤的常見問題(常見問題解答)

> PHP API管道中掛鉤在PHP API管道中的重要性是什麼?它們允許開發人員在程序執行中的特定點插入自定義代碼,而無需更改核心代碼。這使得在不破壞整個系統的情況下更容易添加,修改或刪除功能。鉤子本質上是由特定動作觸發的事件,可以用來以乾淨且有條理的方式擴展應用程序。

>

>如何為我的PHP API管道創建掛鉤?對於您的PHP API管道,涉及定義可以執行自定義代碼的代碼中的特定點。這通常是使用事件和聽眾完成的。當發生特定事件時,觸發相應的偵聽器,執行自定義代碼。這使您可以在運行時修改應用程序的行為,提供高度的靈活性和適應性。

>

>設計靈活的API的最佳實踐是什麼?幾種最佳實踐。首先,保持API簡單而直觀非常重要,從而使開發人員易於理解和使用。其次,應將API設計為可擴展的,從而允許添加新功能而不會破壞現有功能。第三,提供清晰,全面的文檔至關重要,幫助開發人員了解如何有效使用API​​。最後,使用標準的HTTP方法和狀態代碼可以使API更容易預測,更易於使用。

>

PHP與API設計的其他語言相比如何?

PHP是API的流行選擇設計由於其簡單性和靈活性。它支持包括JSON和XML在內的廣泛的數據格式,使創建可以被各種客戶消費的API易於使用。 PHP還擁有一個龐大而活躍的社區,為開發人員提供了豐富的資源和支持。但是,像任何語言一樣,它具有其優點和劣勢,並且語言的選擇應基於項目的特定要求。

> API設計中有哪些共同的挑戰,如何解決?

API設計可以提出一些挑戰,包括確保一致性,管理版本控制和有效處理錯誤。一致性可以通過遵循既定的慣例和標準來維持。可以通過在API URL或請求標頭中包含版本編號來管理版本控制。應該優雅地處理錯誤,提供清晰且有用的錯誤消息,以幫助開發人員診斷和解決問題。

>

>我如何確保API的安全性?措施。這包括使用安全通信協議,例如HTTP,實施身份驗證和授權機制,以及驗證和消毒輸入數據以防止注射攻擊。定期的安全審核和更新還可以幫助識別和修復潛在的漏洞。

>

>如何測試我的API以確保其正常工作正確嗎?

>測試您的API涉及向API端點和API的請求驗證響應。這可以使用郵遞員等工具手動完成,也可以自動使用測試框架來完成。測試API的各個方面,包括功能,性能和安全性很重要。

>如何處理API中的錯誤?

>處理API中的處理錯誤涉及返回適當的HTTP狀態代碼和錯誤消息。這有助於開發人員了解出了什麼問題以及如何解決問題。記錄錯誤和分析的錯誤也很重要。

>我如何提高API的性能?

提高API的性能可能涉及多種策略,包括優化數據庫查詢,實施,實施緩存,並使用有效的數據結構和算法。定期的性能測試和監控可以幫助識別瓶頸和改進區域。

>如何使我的API保持最新狀態?根據開發人員的反饋和業務需求的變化來更新API設計。及時向API用戶傳達任何更改,並在必要時為API的舊版本提供支持。

以上是靈活的API設計:為您的PHP API管道創建鉤子的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板