📜 ⬆️ ⬇️

Simple Restful implementation for Yii

Introduction

I decided to write a medal google chrome extension for the project of the company in which I work. Expansion and the project itself is dedicated to auto themes. In the process of writing, I was annoyed by the server part, which gave the extension ready-made data markup and styles, but I wanted json. I came across an article about restful and decided to write a part on restful architecture.
Our project is implemented on native php without using any frameworks. I wrote a simple class that implements the necessary gadgets, but I couldn’t stop there, since I, a fan of yii, decided to implement this for him. I looked at third-party developments, but I wanted my own, and besides, the class I wrote normally coped with the tasks assigned to it. Adapted my class for yii showed my colleagues, telling me how much they liked it. But then I suffered, I wanted even easier.

so

In yii there is such a great feature “ Binding of action parameters ” as the guide says - you can set named parameters that automatically get the corresponding value from $ _GET.

class UpdateAction extends CAction { public function run($id) { // $id     $_GET['id'] } } 


Here the idea was visited not only to get from GET but also POST, PUT, DELETE according to restful. As a result, we had to override the CController class with its runAction method and add the missing one.
GetActionParams is responsible for getting GET, it is simple to disgrace.
 /** * Returns the request parameters that will be used for action parameter binding. * By default, this method will return $_GET. You may override this method if you * want to use other request parameters (eg $_GET+$_POST). * @return array the request parameters to be used for action parameter binding * @since 1.1.7 */ public function getActionParams() { return $_GET; } 

Adding your methods to the overridden ORestController class.
(I used the latest version of the framework 1.1.9 and I could not get the data from $ _POST as I didn’t try to take everything from the stream)
 // POST  public function getActionParamsPOST() { //  $fh = fopen("php://input", 'r'); $post_string=stream_get_contents($fh); $post_param = explode("&", $post_string); $array_put=array(); foreach($post_param as $post_val) { $param = explode("=", $post_val); $array_post[$param[0]]=urldecode($param[1]); } return $array_post; } // DELETE  public function getActionParamsDELETE() { //  $fh = fopen("php://input", 'r'); $delete_string=stream_get_contents($fh); $delete_param = explode("&", $delete_string); $array_delete=array(); foreach($delete_param as $delete_val) { $param = explode("=", $delete_val); $array_delete[$param[0]]=urldecode($param[1]); } if($_GET) $_delete=$_GET; else $_delete=$array_delete; return $_delete; } // PUT  public function getActionParamsPUT() { //   PUT $fh = fopen("php://input", 'r'); $put_string=stream_get_contents($fh); $put_param = explode("&", $put_string); $array_put=array(); foreach($put_param as $put_val) { $param = explode("=", $put_val); $array_put[$param[0]]=urldecode($param[1]); } return $array_put; } 

')
And slightly changing the original method
 /** * Runs the action after passing through all filters. * This method is invoked by {@link runActionWithFilters} after all possible filters have been executed * and the action starts to run. * @param CAction $action action to run * *  runAction   PUT,DELETE,POST */ public function runAction($action) { $priorAction=$this->_action; $this->_action=$action; $params=false; if($this->beforeAction($action)) { switch ($_SERVER['REQUEST_METHOD']) { case "POST": $params= $this->getActionParamsPOST(); break; case "PUT": $params= $this->getActionParamsPUT(); break; case "DELETE": $params= $this->getActionParamsDELETE(); break; default: $params= $this->getActionParams(); } if($action->runWithParams($params)===false) $this->invalidActionParams($action); else $this->afterAction($action); } $this->_action=$priorAction; } 


Well, that's all, in principle, we inherit our new controller and work.
Example:
 class ApiController extends ORestController { public function actions() { return array ( 'test' => 'application.controllers.actionsApi.actionTest', ); } } 


 class actionTest extends CAction { public function run($params='') { switch ($_SERVER['REQUEST_METHOD']) { case "POST": echo "POST ".$params; break; case "PUT": echo "PUT ".$params; break; case "DELETE": echo "DELETE ".$params; break; default: echo "GET ".$params; } } } 

It remains to implement the necessary functionality for each action, each action works with a separate entity as described in restful. No need to specify the URL of the rule therefore does not affect the application performance.
PS: The methods getActionParamsPOST, getActionParamsPUT, getActionParamsDELETE can be reduced to one method, thereby reducing the code.

Source: https://habr.com/ru/post/135862/


All Articles