PageRenderTime 42ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/Core/Extend/Action/RestAction.class.php

http://school15.codeplex.com
PHP | 364 lines | 197 code | 18 blank | 149 comment | 29 complexity | b140197d91935c820276e1bf991b3459 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // $Id: RestAction.class.php 2706 2012-02-04 03:39:48Z liu21st $
  12. /**
  13. +------------------------------------------------------------------------------
  14. * ThinkPHP RESTFul ??????
  15. +------------------------------------------------------------------------------
  16. */
  17. abstract class RestAction {
  18. // ??Action??
  19. private $name = '';
  20. // ????
  21. protected $view = null;
  22. protected $_method = ''; // ??????
  23. protected $_type = ''; // ??????
  24. // ????
  25. protected $_types = array();
  26. /**
  27. +----------------------------------------------------------
  28. * ???? ????????
  29. +----------------------------------------------------------
  30. * @access public
  31. +----------------------------------------------------------
  32. */
  33. public function __construct() {
  34. //??????
  35. $this->view = Think::instance('View');
  36. if(!defined('__EXT__')) define('__EXT__','');
  37. // ??????
  38. if(''==__EXT__) { // ????????
  39. $this->_type = $this->getAcceptType();
  40. }elseif(false === stripos(C('REST_CONTENT_TYPE_LIST'),__EXT__)) {
  41. // ?????? ??????????
  42. $this->_type = C('REST_DEFAULT_TYPE');
  43. }else{
  44. // ????????
  45. if($this->getAcceptType() == __EXT__) {
  46. $this->_type = __EXT__;
  47. }else{
  48. $this->_type = C('REST_DEFAULT_TYPE');
  49. }
  50. }
  51. // ??????
  52. $method = strtolower($_SERVER['REQUEST_METHOD']);
  53. if(false === stripos(C('REST_METHOD_LIST'),$method)) {
  54. // ?????? ????????
  55. $method = C('REST_DEFAULT_METHOD');
  56. }
  57. $this->_method = $method;
  58. // ?????????
  59. $this->_types = C('REST_OUTPUT_TYPE');
  60. //??????
  61. if(method_exists($this,'_initialize'))
  62. $this->_initialize();
  63. }
  64. /**
  65. +----------------------------------------------------------
  66. * ????Action??
  67. +----------------------------------------------------------
  68. * @access protected
  69. +----------------------------------------------------------
  70. */
  71. protected function getActionName() {
  72. if(empty($this->name)) {
  73. // ??Action??
  74. $this->name = substr(get_class($this),0,-6);
  75. }
  76. return $this->name;
  77. }
  78. /**
  79. +----------------------------------------------------------
  80. * ??AJAX??
  81. +----------------------------------------------------------
  82. * @access protected
  83. +----------------------------------------------------------
  84. * @return bool
  85. +----------------------------------------------------------
  86. */
  87. protected function isAjax() {
  88. if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) ) {
  89. if('xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH']))
  90. return true;
  91. }
  92. if(!empty($_POST[C('VAR_AJAX_SUBMIT')]) || !empty($_GET[C('VAR_AJAX_SUBMIT')]))
  93. // ??Ajax????
  94. return true;
  95. return false;
  96. }
  97. /**
  98. +----------------------------------------------------------
  99. * ???? ????????????
  100. +----------------------------------------------------------
  101. * @access public
  102. +----------------------------------------------------------
  103. * @param string $method ???
  104. * @param array $args ??
  105. +----------------------------------------------------------
  106. * @return mixed
  107. +----------------------------------------------------------
  108. */
  109. public function __call($method,$args) {
  110. if( 0 === strcasecmp($method,ACTION_NAME)) {
  111. if(method_exists($this,$method.'_'.$this->_method.'_'.$this->_type)) { // RESTFul????
  112. $fun = $method.'_'.$this->_method.'_'.$this->_type;
  113. $this->$fun();
  114. }elseif($this->_method == C('REST_DEFAULT_METHOD') && method_exists($this,$method.'_'.$this->_type) ){
  115. $fun = $method.'_'.$this->_type;
  116. $this->$fun();
  117. }elseif($this->_type == C('REST_DEFAULT_TYPE') && method_exists($this,$method.'_'.$this->_method) ){
  118. $fun = $method.'_'.$this->_method;
  119. $this->$fun();
  120. }elseif(method_exists($this,'_empty')) {
  121. // ?????_empty?? ???
  122. $this->_empty($method,$args);
  123. }elseif(file_exists_case(C('TMPL_FILE_NAME'))){
  124. // ?????????? ?????????
  125. $this->display();
  126. }else{
  127. // ????
  128. throw_exception(L('_ERROR_ACTION_').ACTION_NAME);
  129. }
  130. }else{
  131. switch(strtolower($method)) {
  132. // ???? ???????? ???? $this->_post($key,$filter,$default);
  133. case '_get': $input =& $_GET;break;
  134. case '_post':$input =& $_POST;break;
  135. case '_put':
  136. case '_delete':parse_str(file_get_contents('php://input'), $input);break;
  137. case '_request': $input =& $_REQUEST;break;
  138. case '_session': $input =& $_SESSION;break;
  139. case '_cookie': $input =& $_COOKIE;break;
  140. case '_server': $input =& $_SERVER;break;
  141. default:
  142. throw_exception(__CLASS__.':'.$method.L('_METHOD_NOT_EXIST_'));
  143. }
  144. if(isset($input[$args[0]])) { // ????
  145. $data = $input[$args[0]];
  146. $fun = $args[1]?$args[1]:C('DEFAULT_FILTER');
  147. $data = $fun($data); // ????
  148. }else{ // ?????
  149. $data = isset($args[2])?$args[2]:NULL;
  150. }
  151. return $data;
  152. }
  153. }
  154. /**
  155. +----------------------------------------------------------
  156. * ????
  157. * ??????????????
  158. +----------------------------------------------------------
  159. * @access protected
  160. +----------------------------------------------------------
  161. * @param string $templateFile ??????????
  162. * ???? ???????????
  163. * @param string $charset ????
  164. * @param string $contentType ????
  165. +----------------------------------------------------------
  166. * @return void
  167. +----------------------------------------------------------
  168. */
  169. protected function display($templateFile='',$charset='',$contentType='') {
  170. $this->view->display($templateFile,$charset,$contentType);
  171. }
  172. /**
  173. +----------------------------------------------------------
  174. * ??????
  175. +----------------------------------------------------------
  176. * @access protected
  177. +----------------------------------------------------------
  178. * @param mixed $name ????????
  179. * @param mixed $value ????
  180. +----------------------------------------------------------
  181. * @return void
  182. +----------------------------------------------------------
  183. */
  184. protected function assign($name,$value='') {
  185. $this->view->assign($name,$value);
  186. }
  187. public function __set($name,$value) {
  188. $this->view->assign($name,$value);
  189. }
  190. /**
  191. +----------------------------------------------------------
  192. * ???????CONTENT_TYPE???
  193. +----------------------------------------------------------
  194. * @access public
  195. +----------------------------------------------------------
  196. * @param string $type content_type ????????
  197. * @param string $charset ??????
  198. +----------------------------------------------------------
  199. * @return void
  200. +----------------------------------------------------------
  201. */
  202. public function setContentType($type, $charset=''){
  203. if(headers_sent()) return;
  204. if(empty($charset)) $charset = C('DEFAULT_CHARSET');
  205. $type = strtolower($type);
  206. if(isset($this->_types[$type])) //??content_type
  207. header('Content-Type: '.$this->_types[$type].'; charset='.$charset);
  208. }
  209. /**
  210. +----------------------------------------------------------
  211. * ??????
  212. +----------------------------------------------------------
  213. * @access protected
  214. +----------------------------------------------------------
  215. * @param mixed $data ??????
  216. * @param String $type ???? JSON XML
  217. * @param integer $code HTTP??
  218. +----------------------------------------------------------
  219. * @return void
  220. +----------------------------------------------------------
  221. */
  222. protected function response($data,$type='',$code=200) {
  223. // ????
  224. if(C('LOG_RECORD')) Log::save();
  225. $this->sendHttpStatus($code);
  226. exit($this->encodeData($data,strtolower($type)));
  227. }
  228. /**
  229. +----------------------------------------------------------
  230. * ????
  231. +----------------------------------------------------------
  232. * @access protected
  233. +----------------------------------------------------------
  234. * @param mixed $data ??????
  235. * @param String $type ???? JSON XML
  236. +----------------------------------------------------------
  237. * @return void
  238. +----------------------------------------------------------
  239. */
  240. protected function encodeData($data,$type='') {
  241. if(empty($data)) return '';
  242. if('json' == $type) {
  243. // ??JSON???????? ??????
  244. $data = json_encode($data);
  245. }elseif('xml' == $type){
  246. // ??xml????
  247. $data = xml_encode($data);
  248. }elseif('php'==$type){
  249. $data = serialize($data);
  250. }// ??????
  251. $this->setContentType($type);
  252. header('Content-Length: ' . strlen($data));
  253. return $data;
  254. }
  255. // ??Http????
  256. protected function sendHttpStatus($status) {
  257. static $_status = array(
  258. // Informational 1xx
  259. 100 => 'Continue',
  260. 101 => 'Switching Protocols',
  261. // Success 2xx
  262. 200 => 'OK',
  263. 201 => 'Created',
  264. 202 => 'Accepted',
  265. 203 => 'Non-Authoritative Information',
  266. 204 => 'No Content',
  267. 205 => 'Reset Content',
  268. 206 => 'Partial Content',
  269. // Redirection 3xx
  270. 300 => 'Multiple Choices',
  271. 301 => 'Moved Permanently',
  272. 302 => 'Moved Temporarily ', // 1.1
  273. 303 => 'See Other',
  274. 304 => 'Not Modified',
  275. 305 => 'Use Proxy',
  276. // 306 is deprecated but reserved
  277. 307 => 'Temporary Redirect',
  278. // Client Error 4xx
  279. 400 => 'Bad Request',
  280. 401 => 'Unauthorized',
  281. 402 => 'Payment Required',
  282. 403 => 'Forbidden',
  283. 404 => 'Not Found',
  284. 405 => 'Method Not Allowed',
  285. 406 => 'Not Acceptable',
  286. 407 => 'Proxy Authentication Required',
  287. 408 => 'Request Timeout',
  288. 409 => 'Conflict',
  289. 410 => 'Gone',
  290. 411 => 'Length Required',
  291. 412 => 'Precondition Failed',
  292. 413 => 'Request Entity Too Large',
  293. 414 => 'Request-URI Too Long',
  294. 415 => 'Unsupported Media Type',
  295. 416 => 'Requested Range Not Satisfiable',
  296. 417 => 'Expectation Failed',
  297. // Server Error 5xx
  298. 500 => 'Internal Server Error',
  299. 501 => 'Not Implemented',
  300. 502 => 'Bad Gateway',
  301. 503 => 'Service Unavailable',
  302. 504 => 'Gateway Timeout',
  303. 505 => 'HTTP Version Not Supported',
  304. 509 => 'Bandwidth Limit Exceeded'
  305. );
  306. if(isset($_status[$code])) {
  307. header('HTTP/1.1 '.$code.' '.$_status[$code]);
  308. // ??FastCGI?????
  309. header('Status:'.$code.' '.$_status[$code]);
  310. }
  311. }
  312. /**
  313. +----------------------------------------------------------
  314. * ???????Accept???
  315. +----------------------------------------------------------
  316. * @return string
  317. +----------------------------------------------------------
  318. */
  319. protected function getAcceptType(){
  320. $type = array(
  321. 'html'=>'text/html,application/xhtml+xml,*/*',
  322. 'xml'=>'application/xml,text/xml,application/x-xml',
  323. 'json'=>'application/json,text/x-json,application/jsonrequest,text/json',
  324. 'js'=>'text/javascript,application/javascript,application/x-javascript',
  325. 'css'=>'text/css',
  326. 'rss'=>'application/rss+xml',
  327. 'yaml'=>'application/x-yaml,text/yaml',
  328. 'atom'=>'application/atom+xml',
  329. 'pdf'=>'application/pdf',
  330. 'text'=>'text/plain',
  331. 'png'=>'image/png',
  332. 'jpg'=>'image/jpg,image/jpeg,image/pjpeg',
  333. 'gif'=>'image/gif',
  334. 'csv'=>'text/csv'
  335. );
  336. foreach($type as $key=>$val){
  337. $array = explode(',',$val);
  338. foreach($array as $k=>$v){
  339. if(stristr($_SERVER["HTTP_ACCEPT"], $v)) {
  340. return $key;
  341. }
  342. }
  343. }
  344. return false;
  345. }
  346. }