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
- Yii1.1 实现简单restful 框架
- Yii1.1框架的安装
- 使用Spring框架实现RESTful
- yii1.1 -----1
- Yii1.1 rbac实用
- debian安装yii1.1
- yii1.1随记
- 高性能tornado框架简单实现restful接口及运维开发实例
- 高性能tornado框架简单实现restful接口及运维开发实例
- RESTful Web Service框架jersey简单总结
- Java中RESTful 的实现框架
- Java中RESTful 的实现框架
- 《利用Java框架实现Restful接口》
- Jersey 极致简单的Restful WebService实现
- spring+cxf简单实现restful web serivce
- C#实现一个简单的 Restful Service
- Django 从零开始实现简单的restful应用
- 入职第一天。安装Yii1.1
- Android中canvas.drawText()无法使用\r\n换行的解决方案
- 2014-11-13
- 下拉列表的样式
- Leetcode: Max Points on a Line
- WorksheetFunction 成员 (Excel)
- Yii1.1 实现简单restful 框架
- caffe源码分析--Blob类代码研究
- 类模板声明与定义为什么不能分离
- git 命令纪要
- AWS Ubuntu下安装LAMP
- 稀疏矩阵A和B,其行数和列数对应相等,编写一个程序,计算A和B之和,假设稀疏矩阵采用三元组表示
- LeetCode: Spiral Matrix
- android项目两种构建方式的整合(Eclipse/idea和Android Studio)
- 解决了Cocoapods Undefined symbols for architecture _OBJC_CLASS_xxxx的问题,辛苦死我了,记录下之后有空在研究