Yii1.1 实现简单restful 框架

来源:互联网 发布:阅读题软件 编辑:程序博客网 时间:2024/04/30 23:40

学习了下php的rest服务,将总结记录如下。采用Yii1.1版本,Yii2已经专门有restful专题(ps:暂时没有学习)


1.先用Yii创建项目

2.创建数据库(rest)和表(rest_user)及对应模型(user)[脚手架创建]

CREATE TABLE `rest_user` (  `id` int AUTO_INCREMENT COMMENT '用户账号',  `name` char(32) NOT NULL COMMENT '用户姓名',  PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;INSERT INTO `rest_user` VALUES ('1','考勤'),('2','hu'),('3','wang'),('4','fan'),('5','yuan');


3.在protected/config/main.php中配置路由

'urlManager'=>array(    'urlFormat'=>'path',    'showScriptName'=>false,//为优化URL去掉index.php入口文件名字准备    'rules'=>array(        'user/<id:\d+>/<title:.*?>'=>'user/view',        'users/<tag:.*?>'=>'users/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>',    ),),

4.建立相关控制器处理rest请求(ApiController.php)

<?phpclass ApiController extends Controller{    // {{{ *** Members ***    /**     * Key which has to be in HTTP USERNAME and PASSWORD headers      */    Const APPLICATION_ID = 'ASCCPE';    private $format = 'json';    // }}}     // {{{ filters    /**     * @return array action filters     */    public function filters()    {            return array();    } // }}}     // {{{ *** Actions ***    // {{{ actionIndex    public function actionIndex()    {        echo CJSON::encode(array(1, 2, 3));    } // }}}     // {{{ actionList    public function actionList()    {        $this->_checkAuth();        switch($_GET['model'])        {            case 'users': // {{{                 $models = User::model()->findAll();                break; // }}}             default: // {{{                 $this->_sendResponse(501, sprintf('Error: Mode <b>list</b> is not implemented for model <b>%s</b>',$_GET['model']) );                exit; // }}}         }        if(is_null($models)) {            $this->_sendResponse(200, sprintf('No items where found for model <b>%s</b>', $_GET['model']) );        } else {            $rows = array();            foreach($models as $model)                $rows[] = $model->attributes;            $this->_sendResponse(200, CJSON::encode($rows));        }    } // }}}     // {{{ actionView    /* Shows a single item     *      * @access public     * @return void     */    public function actionView()    {        //$this->_checkAuth();        // Check if id was submitted via GET        if(!isset($_GET['id']))            $this->_sendResponse(500, 'Error: Parameter <b>id</b> is missing' );        var_dump($_GET['id']);        var_dump($_GET['model']);        switch($_GET['model'])        {            // Find respective model                case 'users': // {{{                 $model = User::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; // }}}         }        if(is_null($model)) {            $this->_sendResponse(404, 'No Item found with id '.$_GET['id']);        } else {            $this->_sendResponse(200, $this->_getObjectEncoded($_GET['model'], $model->attributes));        }    } // }}}     // {{{ actionCreate    /**     * Creates a new item     *      * @access public     * @return void     */    public function actionCreate()    {        //$this->_checkAuth();        switch($_GET['model'])        {            // Get an instance of the respective model            case 'users': // {{{                 $model = new User;                                    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 );        }        var_dump($_REQUEST);    } // }}}         // {{{ actionUpdate    /**     * Update a single iten     *      * @access public     * @return void     */    public function actionUpdate()    {       // $this->_checkAuth();        // Get PUT parameters        parse_str(file_get_contents('php://input'), $put_vars);        switch($_GET['model'])        {            // Find respective model            case 'users': // {{{                 $model = User::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; // }}}         }        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($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 {            $msg = "<h1>Error</h1>";            $msg .= sprintf("Couldn't update 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 );        }    } // }}}     // {{{ actionDelete    /**     * Deletes a single item     *      * @access public     * @return void     */    public function actionDelete()    {      //  $this->_checkAuth();        switch($_GET['model'])        {            // Load the respective model            case 'users': // {{{                 $model = User::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']) );    } // }}}     // }}} End Actions    // {{{ Other Methods    // {{{ _sendResponse    /**     * Sends the API response      *      * @param int $status      * @param string $body      * @param string $content_type      * @access private     * @return void     */    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 templatized 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;        }    } // }}}                // {{{ _getStatusCodeMessage    /**     * Gets the message for a status code     *      * @param mixed $status      * @access private     * @return string     */    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(            100 => 'Continue',            101 => 'Switching Protocols',            200 => 'OK',            201 => 'Created',            202 => 'Accepted',            203 => 'Non-Authoritative Information',            204 => 'No Content',            205 => 'Reset Content',            206 => 'Partial Content',            300 => 'Multiple Choices',            301 => 'Moved Permanently',            302 => 'Found',            303 => 'See Other',            304 => 'Not Modified',            305 => 'Use Proxy',            306 => '(Unused)',            307 => 'Temporary Redirect',            400 => 'Bad Request',            401 => 'Unauthorized',            402 => 'Payment Required',            403 => 'Forbidden',            404 => 'Not Found',            405 => 'Method Not Allowed',            406 => 'Not Acceptable',            407 => 'Proxy Authentication Required',            408 => 'Request Timeout',            409 => 'Conflict',            410 => 'Gone',            411 => 'Length Required',            412 => 'Precondition Failed',            413 => 'Request Entity Too Large',            414 => 'Request-URI Too Long',            415 => 'Unsupported Media Type',            416 => 'Requested Range Not Satisfiable',            417 => 'Expectation Failed',            500 => 'Internal Server Error',            501 => 'Not Implemented',            502 => 'Bad Gateway',            503 => 'Service Unavailable',            504 => 'Gateway Timeout',            505 => 'HTTP Version Not Supported'        );        return (isset($codes[$status])) ? $codes[$status] : '';    } // }}}     // {{{ _checkAuth    /**     * Checks if a request is authorized     *      * @access private     * @return void     */    private function _checkAuth()    {        // Check if we have the USERNAME and PASSWORD HTTP headers set?        if(!(isset($_SERVER['HTTP_X_'.self::APPLICATION_ID.'_USERNAME']) and isset($_SERVER['HTTP_X_'.self::APPLICATION_ID.'_PASSWORD']))) {            // Error: Unauthorized            $this->_sendResponse(401);        }        $username = $_SERVER['HTTP_X_'.self::APPLICATION_ID.'_USERNAME'];        $password = $_SERVER['HTTP_X_'.self::APPLICATION_ID.'_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');        }    } // }}}     // {{{ _getObjectEncoded    /**     * Returns the json or xml encoded array     *      * @param mixed $model      * @param mixed $array Data to be encoded     * @access private     * @return void     */    private function _getObjectEncoded($model, $array)    {        if(isset($_GET['format']))            $this->format = $_GET['format'];        if($this->format=='json')        {            return CJSON::encode($array);        }        elseif($this->format=='xml')        {            $result = '<?xml version="1.0">';            $result .= "\n<$model>\n";            foreach($array as $key=>$value)                $result .= "    <$key>".utf8_encode($value)."</$key>\n";             $result .= '</'.$model.'>';            return $result;        }        else        {            return;        }    } // }}}     // }}} End Other Methods}/* vim:set ai sw=4 sts=4 et fdm=marker fdc=4: */?>

到此即生成简单的rest框架

下面的get请求id的效果




0 0
原创粉丝点击