2014-07-17 56 views
1

上下文:我正在開發需要客戶端 - 服務器通信的回合制遊戲。客戶端通過HTTPS使用RESTful請求,服務器使用JSON響應。我沒有使用REST,因爲我需要公開API,但是因爲REST範例很適合客戶端/服務器之間的交互。服務器將用PHP編寫。以下基於條件的REST路由

爲了幫助我解決REST請求的路由問題,我一直在尋找一個有用的路由庫。它們的數量是驚人的,但我很難找到符合我特定需求的產品。我的問題是:只有在滿足某些條件的情況下才允許玩家遵循某些路線。顯然,我可以檢查路由匹配後調用的方法是否滿足條件,但這似乎是一種容易出錯的方法,因爲許多路由的條件相同。首先進行部分匹配會更簡單,然後決定在部分匹配下必須滿足一些條件才能遵循更具體的路線。

爲了說明,有4個級別的比賽 '驗證' 的:

  1. 沒有通過認證
  2. 身份驗證爲{ID}(我們知道這是哪個球員)
  3. 身份驗證爲{ID }和{會話參與者sesid}
  4. 身份驗證爲{ID},參與者的會話{} sesid,它是玩家的回合

現在假定認證發生在後臺。路由你可以按照每個級別上,逐步:

LEVEL 1:

  • POST \ Players-註冊

LEVEL 2:

  • PUT \玩家\ {ID } - 更改個人資料
  • GET \ Players \ {id} \ Sessions - 獲取會話列表
  • 名POST \玩家\ {ID} \會議 - 創建會話
  • POST \玩家\ {ID} \庫存 - 購買物品
  • PUT \玩家\ {ID} \邀請\ {sesid} - 參加了會議
  • 邀請
  • 刪除\玩家\ {ID} \邀請\ {sesid} - 會話

3級拒絕邀請:

  • GET \玩家\ {ID} \會議\ {sesid} - 獲得會話狀態
  • DELE TE \播放器{ID} \會議\ {} sesid - 取消會議

LEVEL 4:

  • PUT \玩家\ {ID} \會議\ {sesid} \ ... - 設置多個會話狀態參數

所以我希望在匹配下一組路由之前檢查幾個參數。我花了不少時間找到一個合適的路由包(我已經看過Klein,Zend,PHP-Router,Fat_free,Slim,TORO,Aura,FlightPHP,Phalcon,FuelPHP的文檔) ),但幾乎所有的圖書館都要求您預先定義路線並一次性查找單個匹配項 - 有時允許您設置訂單,有時可以從最具體到最不具體的,但大多隻執行一條路線。

如果我可以按照定義的順序進行部分路線匹配,例如任何以players \ {id}開頭的路線首先檢查身份驗證,當它不在時退出,同時繼續檢查下一個如果認證正常,按照定義的順序排列模式

任何能夠讓我在現場匹配和執行路由的路由庫也會有所幫助 - 只要它可以進行部分匹配,以便我可以獲取我需要的參數以檢查身份驗證級別要求(id,sesid )。顯然,爲了保持苗條,我更喜歡一個不屬於更大框架的庫。

從我在Packagist看到的文檔頁面中,我很難確定您是否可以在某些庫中匹配路徑 - 匹配參數,是的,但是路由? - 有時還不清楚第一場比賽是否是唯一的比賽。任何指針?

或者我錯過了一個更直接的解決方案嗎?

+1

最好的選擇是自己寫或找到一個接近您的需求並改變它的框架。 –

+0

我同意這種觀點,但我對PHP相當陌生 - 這就是爲什麼我希望能用一個庫來解決這個問題(我將要使用幾個 - PHP是那些包含大量包的庫的贏家。 ),而不是寫我自己的;更不用說鑽研其他開發人員的代碼庫了。我還不完全適應,但是用字符串例程過濾掉部分URI,將模式匹配爲值,對結果進行一些驗證,然後將它們作爲參數傳遞給方法。 –

+0

我確實知道Slim可以使用RegEx來匹配網址,所以雖然不是很理想,並且可能最終看起來有點醜陋,但它可能會對您有所幫助。 –

回答

1

好了,開始用,Klein將讓你同樣的回調執行一個以上的路線,像這樣:

// This route matches everything 
$klein->respond('*', function ($request, $response, $service) { myAuthFunction($request); }); 
//other routes 
// This route matches only a specific path 
$klein->respond('GET', '/Players/[i:id]/Sessions', function ($request, $response, $service) { echo "This is the Sessions page for User ID $request->id"; }) 

檢查出routing的部分,滾動到以「開頭的段落注意。」如果我沒有記錯的話,這些路由按照它們聲明的順序執行,所以你捕獲所有用於檢查憑證的路由將需要在更具體的路由之前爲第一路。

在你的auth函數中,你需要拋出一個異常,以防止稍後的路由被運行,然後捕獲它。 This link顯示如何捕獲拋出HTTP錯誤。要拋出一個,只需在回調中撥打$router->abort(404)即可。您可以使用用於發送$路由器(您克萊恩實例),所以你的回調實際上是:

$klein->respond('*', function ($request, $response, $service) use ($klein) { myAuthFunction($request); }); 

還有一個路由namespace系統,我看了看,但沒有使用過自己,但可能是對你正在嘗試做的事有幫助。

最後,我最終做的是將我的操作分組到Controllers中,並在控制器的構造函數中進行權限檢查。我不想浪費大量的時間來解釋如何設置這個,如果你認爲它不適合你,但我可以根據要求提供更多細節。

最後需要說明的,該文件說要安裝克萊恩這樣的:

php composer.phar require klein/klein v2.0.x 

但我發現,DEV-主代碼工作得更好,所以我會建議這樣做:

php composer.phar require klein/klein dev-master 

希望有所幫助!

+0

非常感謝!看起來我在瀏覽Klein文檔時忽略了註釋。你的例子非常有幫助。關於控制器,我已經考慮過了,但發現通過權限將操作分組到控制器中很麻煩。我現在就去嘗試克萊恩。 :) –

+0

我真的很喜歡我與克萊恩的經歷。代碼編寫得很好,而且API既簡單又強大。它在做好需要做的事情方面做得很好,而不必告訴你該做什麼。希望它可以滿足您的需求。如果遇到任何問題,開發人員在回答GitHub回購問題時會相當好。我也試着在SO和GitHub上留意Klein相關的問題。最後,不要害怕跳入代碼。這是一個很小的,寫得很好的項目,我也從中學到了很多東西。請享用! – eimajenthat

+0

會這樣做,聽起來像一個守門員。感謝您的建議,非常感謝。 –