Yii 1.1 Application Development Cookbook
上QQ阅读APP看书,第一时间看更新

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 and GET, 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 a CCookieCollection class instance that allows us to work with cookies. As CCookieCollection extends CMap, 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!!');
   }
}