Difference between #11 and #12 of
How-To: Create a REST API

Revision #12 has been created by Maurizio Domba Cerin on Apr 16, 2011, 7:18:34 AM with the memo:

formated code indent
« previous (#11) next (#13) »

Changes

Title unchanged

How-To: Create a REST API

Category unchanged

How-tos

Yii version unchanged

Tags unchanged

REST, API, Tutorial

Content changed

[...]
In order to parse these URL's, set up the URL manager in _config/main.php_ like this:


```php
...
        'urlManager'=>array(
 
         'urlFormat'=>'path',
 
         'rules'=>array(
 
                        'post/<id:\d+>/<title:.*?>'=>'post/view',
 
                        'posts/<tag:.*?>'=>'post/index',
 
                        // REST patterns
 
                        array('api/list', 'pattern'=>'api/<model:\w+>', 'verb'=>'GET'),
 
                        array('api/view', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'GET'),
 
                        array('api/update', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'PUT'),  // Update
 
                        array('api/delete', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'DELETE'),
 
                        array('api/create', 'pattern'=>'api/<model:\w+>', 'verb'=>'POST'), // Create
 
                        // Other controllers
 
                        '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
 
         ),
 
        ),
 
        ...
 
```
 
 
Note that for _all_ requests, we will get the requested _model_ (e.g. _posts_) via the _GET model_ parameter.
 
 
For the _Get Single Item_ and _Update Item_ method, we will receive the model's primary key via the _GET id_ parameter.
 
 
 
## Create an API controller
 
 
In this tutorial, we will implement all REST methods in a new controller. Put this file in the _controllers_ directory:
 
 
 
```php 
class
 
class ApiController extends Controller
 
{
 
    // Members
 
    /**
 
     * Key which has to be in HTTP USERNAME and PASSWORD headers 
 
     */
 
    Const APPLICATION_ID = 'ASCCPE';
 
 
    /**
 
     * Default response format
 
     * either 'json' or 'xml'
 
     */
 
    private $format = 'json';
 
    /**
 
     * @return array action filters
 
     */
 
    public function filters()
 
    {
 
            return array();
 
    }
 
    // Actions
 
 
    public function actionList()
 
    {
 
    }
 
 
    public function actionView()
 
    {
 
    }
 
 
    public function actionCreate()
 
    {
 
    }
 
 
    public function actionUpdate()
 
    {
 
    }
 
 
    public function actionDelete()
 
    {
 
    }
 
}
 
```
 
 
## Implementing the Actions
 
 
### Get all Models List Action
 
 
 
```php 
public function actionList()
 
    {
 
        // Get the respective model instance
 
        switch($_GET['model'])
 
        {
 
            case 'posts':
 
                $models = Post::model()->findAll();
 
                break;
 
            default:
 
                // Model not implemented error
 
                $this->_sendResponse(501, sprintf('Error: Mode <b>list</b> is not implemented for model <b>%s</b>',$_GET['model']) );
 
                exit;
 
        }
 
        // Did we get some results?
 
        if(is_null($models)) {
 
            // No
 
            $this->_sendResponse(200, sprintf('No items where found for model <b>%s</b>', $_GET['model']) );
 
        } else {
 
            // Prepare response
 
            $rows = array();
 
            foreach($models as $model)
 
                $rows[] = $model->attributes;
 
            // Send the response
 
            $this->_sendResponse(200, CJSON::encode($rows));
 
        }
 
    } // }}} 
 
```
 
 
 
### Get a Single Model Action
 
 
 
```php 
public function actionView()
 
    {
 
        // Check if id was submitted via GET
 
        if(!isset($_GET['id']))
 
            $this->_sendResponse(500, 'Error: Parameter <b>id</b> is missing' );
 
 
        switch($_GET['model'])
 
        {
 
            // Find respective model    
 
            case 'posts':
 
                $model = Post::model()->findByPk($_GET['id']);
 
                break;
 
            default:
 
                $this->_sendResponse(501, sprintf('Mode <b>view</b> is not implemented for model <b>%s</b>',$_GET['model']) );
 
                exit; // }}} 
 
        }
 
        // Did we find the requested model?
 
        if(is_null($model)) {
 
            // No, raise an error 
 
            $this->_sendResponse(404, 'No Item found with id '.$_GET['id']);
 
        } else {
 
            
 
            $this->_sendResponse(200, CJSON::encode($_GET['model']));
 
        }
 
    } // }}} 
 
```
 
 
 
### Create a new Model Action
 
 
 
```php 
public function actionCreate()
 
    {
 
        switch($_GET['model'])
 
        {
 
            // Get an instance of the respective model
 
            case 'posts':
 
                $model = new Post;                    
 
                break;
 
            default:
 
                $this->_sendResponse(501, sprintf('Mode <b>create</b> is not implemented for model <b>%s</b>',$_GET['model']) );
 
                exit;
 
        }
 
        // Try to assign POST values to attributes
 
        foreach($_POST as $var=>$value) {
 
            // Does the model have this attribute?
 
            if($model->hasAttribute($var)) {
 
                $model->$var = $value;
 
            } else {
 
                // No, raise an error
 
                $this->_sendResponse(500, sprintf('Parameter <b>%s</b> is not allowed for model <b>%s</b>', $var, $_GET['model']) );
 
            }
 
        }
 
        // Try to save the model
 
        if($model->save()) {
 
            // Saving was OK
 
            $this->_sendResponse(200, $this->_getObjectEncoded($_GET['model'], $model->attributes) );
 
        } else {
 
            // Errors occurred
 
            $msg = "<h1>Error</h1>";
 
            $msg .= sprintf("Couldn't create model <b>%s</b>", $_GET['model']);
 
            $msg .= "<ul>";
 
            foreach($model->errors as $attribute=>$attr_errors) {
 
                $msg .= "<li>Attribute: $attribute</li>";
 
                $msg .= "<ul>";
 
                foreach($attr_errors as $attr_error) {
 
                    $msg .= "<li>$attr_error</li>";
 
                }        
 
                $msg .= "</ul>";
 
            }
 
            $msg .= "</ul>";
 
            $this->_sendResponse(500, $msg );
 
        }
 
    } // }}}
 
```
 
 
 
### Update a Model Action
 
 
 
```php 
public function actionUpdate()
 
    {
 
 
        // Parse the PUT parameters
 
        parse_str(file_get_contents('php://input'), $put_vars);
 
 
        switch($_GET['model'])
 
        {
 
            // Find respective model
 
            case 'posts':
 
                $model = Post::model()->findByPk($_GET['id']);                    
 
                break;
 
            default:
 
                $this->_sendResponse(501, sprintf('Error: Mode <b>update</b> is not implemented for model <b>%s</b>',$_GET['model']) );
 
                exit;
 
        }
 
        // Did we find the requested model?
 
        if(is_null($model)) {
 
            // No, raise an error
 
            $this->_sendResponse(400, sprintf("Error: Didn't find any model <b>%s</b> with ID <b>%s</b>.",$_GET['model'], $_GET['id']) );
 
        }
 
        
 
        // Try to assign PUT parameters to attributes
 
        foreach($put_vars as $var=>$value) {
 
            // Does model have this attribute?
 
            if($model->hasAttribute($var)) {
 
                $model->$var = $value;
 
            } else {
 
                // No, raise error
 
                $this->_sendResponse(500, sprintf('Parameter <b>%s</b> is not allowed for model <b>%s</b>', $var, $_GET['model']) );
 
            }
 
        }
 
        // Try to save the model
 
        if($model->save()) {
 
            $this->_sendResponse(200, sprintf('The model <b>%s</b> with id <b>%s</b> has been updated.', $_GET['model'], $_GET['id']) );
 
        } else {
 
            // prepare the error $msg
 
            // see actionCreate
 
            // ...
 
            $this->_sendResponse(500, $msg );
 
        }
 
    }
 
```
 
 
 
### Delete a Model Action
 
 
 
```php 
public function actionDelete()
 
    {
 
        switch($_GET['model'])
 
        {
 
            // Load the respective model
 
            case 'posts':
 
                $model = Post::model()->findByPk($_GET['id']);                    
 
                break;
 
            default:
 
                $this->_sendResponse(501, sprintf('Error: Mode <b>delete</b> is not implemented for model <b>%s</b>',$_GET['model']) );
 
                exit;
 
        }
 
        // Was a model found?
 
        if(is_null($model)) {
 
            // No, raise an error
 
            $this->_sendResponse(400, sprintf("Error: Didn't find any model <b>%s</b> with ID <b>%s</b>.",$_GET['model'], $_GET['id']) );
 
        }
 
 
        // Delete the model
 
        $num = $model->delete();
 
        if($num>0)
 
            $this->_sendResponse(200, sprintf("Model <b>%s</b> with ID <b>%s</b> has been deleted.",$_GET['model'], $_GET['id']) );
 
        else
 
            $this->_sendResponse(500, sprintf("Error: Couldn't delete model <b>%s</b> with ID <b>%s</b>.",$_GET['model'], $_GET['id']) );
 
    }
 
```
 
 
 
## Additional Methods Needed
 
 
### Sending the Response
 
 
How are the API responses actually sent? Right, we need to implement the _sendResponse method.
 
 
This code is borrowed from [http://www.gen-x-design.com/archives/create-a-rest-api-with-php](http://www.gen-x-design.com/archives/create-a-rest-api-with-php).
 
 
 
```php 
private function _sendResponse($status = 200, $body = '', $content_type = 'text/html')
 
    {
 
        $status_header = 'HTTP/1.1 ' . $status . ' ' . $this->_getStatusCodeMessage($status);
 
        // set the status
 
        header($status_header);
 
        // set the content type
 
        header('Content-type: ' . $content_type);
 
 
        // pages with body are easy
 
        if($body != '')
 
        {
 
            // send the body
 
            echo $body;
 
            exit;
 
        }
 
        // we need to create the body if none is passed
 
        else
 
        {
 
            // create some body messages
 
            $message = '';
 
 
            // this is purely optional, but makes the pages a little nicer to read
 
            // for your users.  Since you won't likely send a lot of different status codes,
 
            // this also shouldn't be too ponderous to maintain
 
            switch($status)
 
            {
 
                case 401:
 
                    $message = 'You must be authorized to view this page.';
 
                    break;
 
                case 404:
 
                    $message = 'The requested URL ' . $_SERVER['REQUEST_URI'] . ' was not found.';
 
                    break;
 
                case 500:
 
                    $message = 'The server encountered an error processing your request.';
 
                    break;
 
                case 501:
 
                    $message = 'The requested method is not implemented.';
 
                    break;
 
            }
 
 
            // servers don't always have a signature turned on (this is an apache directive "ServerSignature On")
 
            $signature = ($_SERVER['SERVER_SIGNATURE'] == '') ? $_SERVER['SERVER_SOFTWARE'] . ' Server at ' . $_SERVER['SERVER_NAME'] . ' Port ' . $_SERVER['SERVER_PORT'] : $_SERVER['SERVER_SIGNATURE'];
 
 
            // this should be templated in a real-world solution
 
            $body = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 
                        <html>
 
                            <head>
 
                                <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
                                <title>' . $status . ' ' . $this->_getStatusCodeMessage($status) . '</title>
 
                            </head>
 
                            <body>
 
                                <h1>' . $this->_getStatusCodeMessage($status) . '</h1>
 
                                <p>' . $message . '</p>
 
                                <hr />
 
                                <address>' . $signature . '</address>
 
                            </body>
 
                        </html>';
 
 
            echo $body;
 
            exit;
 
        }
 
    } // }}}            
 
```
 
 
 
### Getting the Status Codes
 
 
Also, we need to implement the _getStatusCodeMessage method. This is pretty straight forward:
 
 
 
```php 
private function _getStatusCodeMessage($status)
 
    {
 
        // these could be stored in a .ini file and loaded
 
        // via parse_ini_file()... however, this will suffice
 
        // for an example
 
        $codes = Array(
 
            200 => 'OK',
 
            400 => 'Bad Request',
 
            401 => 'Unauthorized',
 
            402 => 'Payment Required',
 
            403 => 'Forbidden',
 
            404 => 'Not Found',
 
            500 => 'Internal Server Error',
 
            501 => 'Not Implemented',
 
        );
 
        return (isset($codes[$status])) ? $codes[$status] : '';
 
    } // }}} 
 
 
```
 
 
 
### Authentication
 
 
If we want to have the API user authorize himself, we could write something like this:
 
 
 
```php 
private function _checkAuth()
 
    {
 
        // Check if we have the USERNAME and PASSWORD HTTP headers set?
 
        if(!(isset($_SERVER['HTTP_X_USERNAME']) and isset($_SERVER['HTTP_X_PASSWORD']))) {
 
            // Error: Unauthorized
 
            $this->_sendResponse(401);
 
        }
 
        $username = $_SERVER['HTTP_X_USERNAME'];
 
        $password = $_SERVER['HTTP_X_PASSWORD'];
 
        // Find the user
 
        $user=User::model()->find('LOWER(username)=?',array(strtolower($username)));
 
        if($user===null) {
 
            // Error: Unauthorized
 
            $this->_sendResponse(401, 'Error: User Name is invalid');
 
        } else if(!$user->validatePassword($password)) {
 
            // Error: Unauthorized
 
            $this->_sendResponse(401, 'Error: User Password is invalid');
 
        }
 
    } // }}} 
'urlManager'=>array(
 
    'urlFormat'=>'path',
 
    'rules'=>array(
 
        'post/<id:\d+>/<title:.*?>'=>'post/view',
 
        'posts/<tag:.*?>'=>'post/index',
 
        // REST patterns
 
        array('api/list', 'pattern'=>'api/<model:\w+>', 'verb'=>'GET'),
 
        array('api/view', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'GET'),
 
        array('api/update', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'PUT'),
 
        array('api/delete', 'pattern'=>'api/<model:\w+>/<id:\d+>', 'verb'=>'DELETE'),
 
        array('api/create', 'pattern'=>'api/<model:\w+>', 'verb'=>'POST'),
 
        // Other controllers
 
        '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
 
    ),
 
),
 
...
 
```
 
 
Note that for _all_ requests, we will get the requested _model_ (e.g. _posts_) via the _GET model_ parameter.
 
 
For the _Get Single Item_ and _Update Item_ method, we will receive the model's primary key via the _GET id_ parameter.
 
 
 
## Create an API controller
 
 
In this tutorial, we will implement all REST methods in a new controller. Put this file in the _controllers_ directory:
 
 
 
```php 
class ApiController extends Controller
 
{
 
    // Members
 
    /**
 
     * Key which has to be in HTTP USERNAME and PASSWORD headers 
 
     */
 
    Const APPLICATION_ID = 'ASCCPE';
 
 
    /**
 
     * Default response format
 
     * either 'json' or 'xml'
 
     */
 
    private $format = 'json';
 
    /**
 
     * @return array action filters
 
     */
 
    public function filters()
 
    {
 
            return array();
 
    }
 
 
    // Actions
 
    public function actionList()
 
    {
 
    }
 
    public function actionView()
 
    {
 
    }
 
    public function actionCreate()
 
    {
 
    }
 
    public function actionUpdate()
 
    {
 
    }
 
    public function actionDelete()
 
    {
 
    }
 
}
 
```
 
 
## Implementing the Actions
 
 
### Get all Models List Action
 
 
 
```php 
public function actionList()
 
{
 
    // Get the respective model instance
 
    switch($_GET['model'])
 
    {
 
        case 'posts':
 
            $models = Post::model()->findAll();
 
            break;
 
        default:
 
            // Model not implemented error
 
            $this->_sendResponse(501, sprintf(
 
                'Error: Mode <b>list</b> is not implemented for model <b>%s</b>',
 
                $_GET['model']) );
 
            exit;
 
    }
 
    // Did we get some results?
 
    if(is_null($models)) {
 
        // No
 
        $this->_sendResponse(200, 
 
                sprintf('No items where found for model <b>%s</b>', $_GET['model']) );
 
    } else {
 
        // Prepare response
 
        $rows = array();
 
        foreach($models as $model)
 
            $rows[] = $model->attributes;
 
        // Send the response
 
        $this->_sendResponse(200, CJSON::encode($rows));
 
    }
 
}
 
```
 
 
 
### Get a Single Model Action
 
 
 
```php 
public function actionView()
 
{
 
    // Check if id was submitted via GET
 
    if(!isset($_GET['id']))
 
        $this->_sendResponse(500, 'Error: Parameter <b>id</b> is missing' );
 
 
    switch($_GET['model'])
 
    {
 
        // Find respective model    
 
        case 'posts':
 
            $model = Post::model()->findByPk($_GET['id']);
 
            break;
 
        default:
 
            $this->_sendResponse(501, sprintf(
 
                'Mode <b>view</b> is not implemented for model <b>%s</b>',
 
                $_GET['model']) );
 
            exit;
 
    }
 
    // Did we find the requested model? If not, raise an error
 
    if(is_null($model))
 
        $this->_sendResponse(404, 'No Item found with id '.$_GET['id']);
 
    else
 
        $this->_sendResponse(200, CJSON::encode($_GET['model']));
 
}
 
```
 
 
 
### Create a new Model Action
 
 
 
```php 
public function actionCreate()
 
{
 
    switch($_GET['model'])
 
    {
 
        // Get an instance of the respective model
 
        case 'posts':
 
            $model = new Post;                    
 
            break;
 
        default:
 
            $this->_sendResponse(501, 
 
                sprintf('Mode <b>create</b> is not implemented for model <b>%s</b>',
 
                $_GET['model']) );
 
                exit;
 
    }
 
    // Try to assign POST values to attributes
 
    foreach($_POST as $var=>$value) {
 
        // Does the model have this attribute? If not raise an error
 
        if($model->hasAttribute($var))
 
            $model->$var = $value;
 
        else
 
            $this->_sendResponse(500, 
 
                sprintf('Parameter <b>%s</b> is not allowed for model <b>%s</b>', $var,
 
                $_GET['model']) );
 
    }
 
    // Try to save the model
 
    if($model->save())
 
        $this->_sendResponse(200, 
 
                $this->_getObjectEncoded($_GET['model'], $model->attributes) );
 
    else {
 
        // Errors occurred
 
        $msg = "<h1>Error</h1>";
 
        $msg .= sprintf("Couldn't create model <b>%s</b>", $_GET['model']);
 
        $msg .= "<ul>";
 
        foreach($model->errors as $attribute=>$attr_errors) {
 
            $msg .= "<li>Attribute: $attribute</li>";
 
            $msg .= "<ul>";
 
            foreach($attr_errors as $attr_error)
 
                $msg .= "<li>$attr_error</li>";
 
            $msg .= "</ul>";
 
        }
 
        $msg .= "</ul>";
 
        $this->_sendResponse(500, $msg );
 
    }
 
}
 
```
 
 
 
### Update a Model Action
 
 
 
```php 
public function actionUpdate()
 
{
 
    // Parse the PUT parameters
 
    parse_str(file_get_contents('php://input'), $put_vars);
 
 
    switch($_GET['model'])
 
    {
 
        // Find respective model
 
        case 'posts':
 
            $model = Post::model()->findByPk($_GET['id']);                    
 
            break;
 
        default:
 
            $this->_sendResponse(501, 
 
                sprintf( 'Error: Mode <b>update</b> is not implemented for model <b>%s</b>',
 
                $_GET['model']) );
 
            exit;
 
    }
 
    // Did we find the requested model? If not, raise an error
 
    if(is_null($model))
 
        $this->_sendResponse(400, 
 
                sprintf("Error: Didn't find any model <b>%s</b> with ID <b>%s</b>.",
 
                $_GET['model'], $_GET['id']) );
 
        
 
    // Try to assign PUT parameters to attributes
 
    foreach($put_vars as $var=>$value) {
 
        // Does model have this attribute? If not, raise an error
 
        if($model->hasAttribute($var))
 
            $model->$var = $value;
 
        else {
 
            $this->_sendResponse(500, 
 
                sprintf('Parameter <b>%s</b> is not allowed for model <b>%s</b>',
 
                $var, $_GET['model']) );
 
        }
 
    }
 
    // Try to save the model
 
    if($model->save())
 
        $this->_sendResponse(200, 
 
                sprintf('The model <b>%s</b> with id <b>%s</b> has been updated.',
 
                $_GET['model'], $_GET['id']) );
 
    else
 
        // prepare the error $msg
 
        // see actionCreate
 
        // ...
 
        $this->_sendResponse(500, $msg );
 
}
 
```
 
 
 
### Delete a Model Action
 
 
 
```php 
public function actionDelete()
 
{
 
    switch($_GET['model'])
 
    {
 
        // Load the respective model
 
        case 'posts':
 
            $model = Post::model()->findByPk($_GET['id']);                    
 
            break;
 
        default:
 
            $this->_sendResponse(501, 
 
                sprintf('Error: Mode <b>delete</b> is not implemented for model <b>%s</b>',
 
                $_GET['model']) );
 
            exit;
 
    }
 
    // Was a model found? If not, raise an error
 
    if(is_null($model))
 
        $this->_sendResponse(400, 
 
                sprintf("Error: Didn't find any model <b>%s</b> with ID <b>%s</b>.",
 
                $_GET['model'], $_GET['id']) );
 
 
    // Delete the model
 
    $num = $model->delete();
 
    if($num>0)
 
        $this->_sendResponse(200, 
 
                sprintf("Model <b>%s</b> with ID <b>%s</b> has been deleted.",
 
                $_GET['model'], $_GET['id']) );
 
    else
 
        $this->_sendResponse(500, 
 
                sprintf("Error: Couldn't delete model <b>%s</b> with ID <b>%s</b>.",
 
                $_GET['model'], $_GET['id']) );
 
}
 
```
 
 
 
## Additional Methods Needed
 
 
### Sending the Response
 
 
How are the API responses actually sent? Right, we need to implement the _sendResponse method.
 
 
This code is borrowed from [http://www.gen-x-design.com/archives/create-a-rest-api-with-php](http://www.gen-x-design.com/archives/create-a-rest-api-with-php).
 
 
 
```php 
private function _sendResponse($status = 200, $body = '', $content_type = 'text/html')
 
{
 
    // set the status
 
    $status_header = 'HTTP/1.1 ' . $status . ' ' . $this->_getStatusCodeMessage($status);
 
    header($status_header);
 
    // and the content type
 
    header('Content-type: ' . $content_type);
 
 
    // pages with body are easy
 
    if($body != '')
 
    {
 
        // send the body
 
        echo $body;
 
        exit;
 
    }
 
    // we need to create the body if none is passed
 
    else
 
    {
 
        // create some body messages
 
        $message = '';
 
 
        // this is purely optional, but makes the pages a little nicer to read
 
        // for your users.  Since you won't likely send a lot of different status codes,
 
        // this also shouldn't be too ponderous to maintain
 
        switch($status)
 
        {
 
            case 401:
 
                $message = 'You must be authorized to view this page.';
 
                break;
 
            case 404:
 
                $message = 'The requested URL ' . $_SERVER['REQUEST_URI'] . ' was not found.';
 
                break;
 
            case 500:
 
                $message = 'The server encountered an error processing your request.';
 
                break;
 
            case 501:
 
                $message = 'The requested method is not implemented.';
 
                break;
 
        }
 
 
        // servers don't always have a signature turned on 
 
        // (this is an apache directive "ServerSignature On")
 
        $signature = ($_SERVER['SERVER_SIGNATURE'] == '') ? $_SERVER['SERVER_SOFTWARE'] . ' Server at ' . $_SERVER['SERVER_NAME'] . ' Port ' . $_SERVER['SERVER_PORT'] : $_SERVER['SERVER_SIGNATURE'];
 
 
        // this should be templated in a real-world solution
 
        $body = '
 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 
<html>
 
<head>
 
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
 
    <title>' . $status . ' ' . $this->_getStatusCodeMessage($status) . '</title>
 
</head>
 
<body>
 
    <h1>' . $this->_getStatusCodeMessage($status) . '</h1>
 
    <p>' . $message . '</p>
 
    <hr />
 
    <address>' . $signature . '</address>
 
</body>
 
</html>';
 
 
        echo $body;
 
        exit;
 
    }
 
}
 
```
 
 
 
### Getting the Status Codes
 
 
Also, we need to implement the _getStatusCodeMessage method. This is pretty straight forward:
 
 
 
```php 
private function _getStatusCodeMessage($status)
 
{
 
    // these could be stored in a .ini file and loaded
 
    // via parse_ini_file()... however, this will suffice
 
    // for an example
 
    $codes = Array(
 
        200 => 'OK',
 
        400 => 'Bad Request',
 
        401 => 'Unauthorized',
 
        402 => 'Payment Required',
 
        403 => 'Forbidden',
 
        404 => 'Not Found',
 
        500 => 'Internal Server Error',
 
        501 => 'Not Implemented',
 
    );
 
    return (isset($codes[$status])) ? $codes[$status] : '';
 
}
 
```
 
 
 
### Authentication
 
 
If we want to have the API user authorize himself, we could write something like this:
 
 
 
```php 
private function _checkAuth()
 
{
 
    // Check if we have the USERNAME and PASSWORD HTTP headers set?
 
    if(!(isset($_SERVER['HTTP_X_USERNAME']) and isset($_SERVER['HTTP_X_PASSWORD']))) {
 
        // Error: Unauthorized
 
        $this->_sendResponse(401);
 
    }
 
    $username = $_SERVER['HTTP_X_USERNAME'];
 
    $password = $_SERVER['HTTP_X_PASSWORD'];
 
    // Find the user
 
    $user=User::model()->find('LOWER(username)=?',array(strtolower($username)));
 
    if($user===null) {
 
        // Error: Unauthorized
 
        $this->_sendResponse(401, 'Error: User Name is invalid');
 
    } else if(!$user->validatePassword($password)) {
 
        // Error: Unauthorized
 
        $this->_sendResponse(401, 'Error: User Password is invalid');
 
    }
 
}

```

Also, in all REST methods where an authentication is required, we need to put
[...]
96 1
125 followers
Viewed: 376 659 times
Version: 1.1
Category: How-tos
Written by: jwerner
Last updated by: Rohit Suthar
Created on: Apr 15, 2011
Last updated: 3 years ago
Update Article

Revisions

View all history