Working with request
You can work with request data directly using PHP superglobals such as $_SERVER
, $_GET
, or $_POST
but the better way is to use Yii powerful CHttpRequest
class that resolves inconsistencies among different web servers, manages cookies, provides some additional security, and has a nice set of OO methods.
How to do it…
You can access the request component in your web application by using Yii::app()->getRequest()
. So, let's review the most useful methods and their usage, methods that return different parts of the current URL. In the following table, returned parts are marked with a bold font.
The methods that allow us to ensure request type are getIsPostRequest
, getIsAjaxRequest
, and getRequestType
.
- For example, we can use
getIsAjaxRequest
to serve different content based on request type:class TestController extends CController { public function actionIndex() { if(Yii::app()->request->isAjaxRequest)s $this->renderPartial('test'); else $this->render('test'); } }
In the preceding code, we are rendering a view without layout if the request is made through AJAX.
- While PHP provides superglobals for both
POST
andGET
, Yii way allows us to omit some additional checks:class TestController extends CController { public function actionIndex() { $request = Yii::app()->request; $param = $request->getParam('id', 1); // equals to $param = isset($_REQUEST['id']) ? $_REQUEST['id'] : 1; $param = $request->getQuery('id'); // equals to $param = isset($_GET['id']) ? $_GET['id'] : null; $param = $request->getPost('id', 1); // equals to $param = isset($_POST['id']) ? $_POST['id'] : 1; } }
getPreferredLanguage
tries to determine the user's preferred language. It can't be completely accurate, but it is good to use it as a fallback in case the user has not specified a preferred language manually.class TestController extends CController { public function actionIndex() { $request = Yii::app()->request; $lang = $request->preferredLanguage; // trying to get language setting from DB $criteria = new CDbCriteria(); $criteria->compare('user_id', $request->getQuery('userid')); $criteria->compare('key', 'language'); $setting = Settings::model()->find($criteria); if($setting) $lang = $setting->value; Yii::app()->setLanguage($lang); echo Yii::t('app', 'Language is: ').$lang; } }
sendFile
allows to initiate file download as follows:class TestController extends CController { public function actionIndex() { $request = Yii::app()->getRequest(); $request->sendFile('test.txt', 'File content goes here.'); } }
This action will trigger a file download and send all necessary headers, including content type (mimetype) and content length. Mimetype, if not set manually as a third parameter, will be guessed based on the filename's extension.
- The last thing we are going to show in this chapter is the
getCookies
method. It returns aCCookieCollection
class instance that allows us to work with cookies. AsCCookieCollection
extendsCMap
, we can use some native PHP methods as follows:class TestController extends CController { public function actionIndex() { $request = Yii::app()->request; // getting a cookie $cookie = $request->cookies['test']; if($cookie) // printing cookie value echo $cookie->value; else { // creating new cookie $cookie=new CHttpCookie('test','I am a cookie!'); $request->cookies['test'] = $cookie; } }
There's more...
If you are working with a lot of cookie values and want to shorten the code provided, then you can use a helper as follows:
class Cookie { public static function get($name) { $cookie=Yii::app()->request->cookies[$name]; if(!$cookie) return null; return $cookie->value; } public static function set($name, $value, $expiration=0) { $cookie=new CHttpCookie($name,$value); $cookie->expire = $expiration; Yii::app()->request->cookies[$name]=$cookie; } }
After you drop this code into protected/components/Cookie.php
, you will be able to perform the following:
class TestController extends CController { public function actionIndex() { $cookie = Cookie::get('test'); if($cookie) echo $cookie; else Cookie::set('test','I am a cookie!!'); } }