| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- <?php
- namespace Heanup\Frame;
- abstract class Controller
- {
- protected $tpl; // 模板路径, 可选
- protected $queryObj;
- protected $data_name = false;
- protected $isrestful = false;
- final public function __construct()
- {
- $this->queryObj = $this->getQuery();
- }
- /**
- * 主逻辑
- */
- final public function run()
- {
- try {
- $this->before();
- $method = strtolower($_SERVER['REQUEST_METHOD']);
- if ($method == 'options') {
- $this->optionsData();
- }
- $this->checkAuth();
- $data_name = $method . 'Data';
- if ($this->isrestful) {
- if (!method_exists(get_called_class(), $data_name)) {
- Response::sendResponse(405, ['method' => strtoupper($method)], 'Method not allowed');
- die();
- }
- $this->$data_name();
- } else {
- $this->main();
- }
- } catch (\Exception $ex) {
- $this->showError($ex->getCode(), $ex->getMessage());
- }
- }
- public function optionsData()
- {
- header("HTTP/1.1 200");
- header("Access-Control-Allow-Origin: *");
- header("Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE");
- // header("Access-Control-Max-Age: 3");
- header("Access-Control-Allow-Headers: lang,token,content-type");
- die();
- }
- /**
- * 尽快输出结果,然后执行后续逻辑
- * 本方法的的信息不会被输出
- * 即使exit之后仍旧能被执行
- */
- final public function __destruct()
- {
- if (function_exists('fastcgi_finish_request')) {
- fastcgi_finish_request();
- }
- $this->after();
- }
- /**
- * 前置方法,处理参数
- */
- protected function before()
- {
- }
- /**
- * 执行验证
- */
- protected function checkAuth()
- {
- }
- /**
- * 执行逻辑
- */
- protected function main()
- {
- }
- /**
- * 后续方法
- */
- protected function after()
- {
- }
- /**
- * @return Filter
- */
- protected function getRequest()
- {
- static $instance = null;
- parse_str(file_get_contents('php://input'), $data);
- $data = array_merge($_POST, $_GET, $_COOKIE, $data);
- if (is_null($instance)) {
- $instance = new Filter($data);
- }
- return $instance;
- }
- /**
- * @return Filter
- */
- protected function getPut()
- {
- static $instance = null;
- try {
- $putData = file_get_contents("php://input");
- $resultData = json_decode($putData, true);
- if (is_array($resultData)) {
- //解析IOS提交的PUT数据
- $data = $resultData;
- } elseif (!strstr($putData, "\r\n")) {
- //解析本地测试工具提交的PUT数据
- parse_str($putData, $putData);
- $data = $putData;
- } else {
- //解析PHP CURL提交的PUT数据
- $putData = explode("\r\n", $putData);
- $resultData = [];
- foreach ($putData as $key => $data) {
- if (substr($data, 0, 20) == 'Content-Disposition:') {
- $match = explode(";", $data);
- if (count($match) == 2) {
- preg_match('/.*\"(.*)\"/', $data, $matchName);
- $resultData[$matchName[1]] = $putData[$key + 2];
- } else {
- $info = self::parserInfo($data);
- $file = fopen($info['tmp_name'], "r+");
- fwrite($file, $putData[$key + 3]);
- fclose($file);
- $resultData[$info['field']] = $info;
- }
- }
- }
- $data = $resultData;
- }
- } catch (\Exception $e) {
- $data = [];
- }
- if (is_null($instance)) {
- $instance = new Filter($data);
- }
- return $instance;
- }
- private static function parserInfo($data, $options = ['saveFile' => true])
- {
- //获取参数名称, type
- $infoPattern = '/name="(.+?)"(; )?(filename="(.+?)")?/'; //todo: 待优化
- preg_match($infoPattern, $data, $matches);
- $info['field'] = $matches[1];
- $info['type'] = 'json';
- //如果是文件
- if (count($matches) > 4) {
- $info['type'] = 'file';
- $info['name'] = $matches[4];
- //如果设置保存文件, 保存到临时文件
- if (isset($options['saveFile']) && $options['saveFile']) {
- $tmpFile = tempnam(sys_get_temp_dir(), 'FD');
- $info['tmp_name'] = $tmpFile;
- }
- }
- return $info;
- }
- protected function getJson()
- {
- static $instance = null;
- $data = file_get_contents('php://input');
- $data = json_decode($data, true) ?: [];
- if (is_null($instance)) {
- $instance = new Filter($data);
- }
- return $instance;
- }
- /**
- * @return Filter
- */
- protected function getQuery()
- {
- static $instance = null;
- if (is_null($instance)) {
- $instance = new Filter($_GET);
- }
- return $instance;
- }
- protected function getFilter()
- {
- $str = $this->getQuery()->string("filter");
- $str = explode(";", $str);
- if ($str) {
- foreach ($str as $item) {
- $item = explode(":", $item);
- if ($item[1] == "") {
- continue;
- }
- $_Filter[$item[0]] = $item[1];
- }
- }
- $_Filter['page'] = $_GET['page'] ?: ($_Filter['page'] ?: 1);
- $_Filter['pageSize'] = $_GET['pageSize'] ?: ($_Filter['pageSize'] ?: 20);
- static $instance = null;
- if (is_null($instance)) {
- $instance = new Filter($_Filter);
- }
- return $instance;
- }
- /**
- * @return Filter
- */
- protected function getPost()
- {
- static $instance = null;
- if (is_null($instance)) {
- $instance = new Filter($_POST);
- }
- return $instance;
- }
- /**
- * 获取模板, 固定模板, 与controller名称类似
- * @return Template
- */
- protected function getTemplate()
- {
- static $template;
- if ($template) {
- return $template;
- }
- $class = get_called_class();
- $class = explode('\\', $class);
- $path = dirname(__DIR__) . '/' . implode('/', array_slice($class, 1, 2)) . '/Template/';
- if (!$this->tpl) {
- $this->tpl = implode('/', array_slice($class, 4));
- }
- $template = new Template();
- $template->setPath($path)->setTpl($this->tpl);
- $data = get_object_vars($this);
- if ($data) {
- $template->assign($data);
- }
- return $template;
- }
- /**
- * 检查CSRF攻击
- * @return bool
- */
- protected function checkCsrf()
- {
- $host = strtolower(trim($_SERVER['HTTP_HOST']));
- $referer = parse_url($_SERVER['HTTP_REFERER']);
- $referer = substr(strtolower(trim($referer['host'])), -(strlen($host)));
- if (!empty($referer) AND $referer != $host AND $referer != ('www.' . $host)) {
- return false;
- }
- return true;
- }
- }
|