router.class.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <?php
  2. use Nyholm\Psr7\Factory\Psr17Factory;
  3. use Spiral\Goridge\RPC\RPC;
  4. use Spiral\RoadRunner\Http\PSR7Worker;
  5. use Spiral\RoadRunner\Jobs\Consumer;
  6. use Spiral\RoadRunner\Jobs\Jobs;
  7. use Spiral\RoadRunner\Jobs\Task\ReceivedTaskInterface;
  8. use Spiral\RoadRunner\Worker;
  9. include "vendor/autoload.php";
  10. include 'response.class.php';
  11. /**
  12. * The zand router class file of ZenTaoPHP framework.
  13. *
  14. * The author disclaims copyright to this source code. In place of
  15. * a legal notice, here is a blessing:
  16. *
  17. * May you do good and not evil.
  18. * May you find forgiveness for yourself and forgive others.
  19. * May you share freely, never taking more than you give.
  20. */
  21. /**
  22. * router类。
  23. * The router class.
  24. *
  25. * @package framework
  26. */
  27. include dirname(__DIR__) . '/router.class.php';
  28. class zandRouter extends router
  29. {
  30. /**
  31. * 全局变量的快照
  32. * Snaps for global variables.
  33. *
  34. * @static
  35. * @var array
  36. * @access public
  37. */
  38. static $snaps = array();
  39. /**
  40. * 构造方法, 设置路径,类,超级变量等。注意:
  41. * 1.应该使用createApp()方法实例化router类;
  42. * 2.如果$appRoot为空,框架会根据$appName计算应用路径。
  43. *
  44. * The construct function.
  45. * Prepare all the paths, classes, super objects and so on.
  46. * Notice:
  47. * 1. You should use the createApp() method to get an instance of the router.
  48. * 2. If the $appRoot is empty, the framework will compute the appRoot according the $appName
  49. *
  50. * @param string $appName the name of the app
  51. * @param string $appRoot the root path of the app
  52. * @access public
  53. * @return void
  54. */
  55. public function __construct($appName = 'demo', $appRoot = '')
  56. {
  57. $_SERVER['HTTP_USER_AGENT'] = '';
  58. $_SERVER['SCRIPT_NAME'] = '/index.php';
  59. $_SERVER['SCRIPT_FILENAME'] = dirname(__DIR__, 2) . '/www/index.php';
  60. $this->worker = new zandWorker();
  61. $this->consumer = new Consumer();
  62. parent::__construct($appName, $appRoot);
  63. /* Snap. */
  64. global $filter;
  65. self::$snaps['config'] = clone $this->config;
  66. self::$snaps['lang'] = clone $this->lang;
  67. self::$snaps['filter'] = clone $filter;
  68. }
  69. /**
  70. * 初始化全局变量和客户端信息。
  71. * Init global variables and client.
  72. *
  73. * @access public
  74. * @return void
  75. */
  76. public function initRequest()
  77. {
  78. global $config, $lang, $filter, $loadedTargets;
  79. $config = clone self::$snaps['config'];
  80. $lang = clone self::$snaps['lang'];
  81. $filter = clone self::$snaps['filter'];
  82. $loadedTargets = array();
  83. $this->config = $config;
  84. $this->lang = $lang;
  85. $this->moduleName = NULL;
  86. $this->methodName = NULL;
  87. $this->rawModule = NULL;
  88. $this->rawMethod = NULL;
  89. $this->params = NULL;
  90. $this->user = NULL;
  91. self::$loadedConfigs = array();
  92. self::$loadedLangs = array();
  93. $this->setClient();
  94. }
  95. /**
  96. * 关闭请求会话
  97. * Close request.
  98. *
  99. * @access public
  100. * @return void
  101. */
  102. public function closeRequest()
  103. {
  104. $obLevel = ob_get_level();
  105. for($i = 0; $i < $obLevel; $i++) ob_end_clean();
  106. session_write_close();
  107. }
  108. /**
  109. * 开启session。
  110. * Start session.
  111. *
  112. * @access public
  113. * @return void
  114. */
  115. public function startSession()
  116. {
  117. $sessionName = $this->config->sessionVar;
  118. if(!defined('SESSION_STARTED'))
  119. {
  120. global $config;
  121. $driver = $config->db->driver;
  122. if(!class_exists($driver))
  123. {
  124. $classFile = $this->coreLibRoot . 'dao' . DS . $driver . '.class.php';
  125. include($classFile);
  126. }
  127. $dao = new $driver();
  128. $ztSessionHandler = new zandSession($dao);
  129. session_set_save_handler(
  130. \Closure::fromCallable([$ztSessionHandler, 'open']),
  131. \Closure::fromCallable([$ztSessionHandler, 'close']),
  132. \Closure::fromCallable([$ztSessionHandler, 'read']),
  133. \Closure::fromCallable([$ztSessionHandler, 'write']),
  134. \Closure::fromCallable([$ztSessionHandler, 'destroy']),
  135. \Closure::fromCallable([$ztSessionHandler, 'gc'])
  136. );
  137. session_name($sessionName);
  138. session_set_cookie_params(0, $this->config->webRoot, '', $this->config->cookieSecure, true);
  139. define('SESSION_STARTED', true);
  140. }
  141. else
  142. {
  143. $this->sessionID = isset($_COOKIE[$sessionName]) ? $_COOKIE[$sessionName] : session_create_id();
  144. session_id($this->sessionID);
  145. session_start();
  146. $this->worker->response->setCookie($sessionName, $this->sessionID, 0);
  147. }
  148. }
  149. }
  150. /**
  151. * 消息队列的消息类型。
  152. * Message in queue.
  153. *
  154. * @package zand
  155. */
  156. class zandMessage
  157. {
  158. public $id;
  159. public $type;
  160. public $command;
  161. }
  162. /**
  163. * 消息队列。
  164. * Message queue.
  165. *
  166. * @package zand
  167. */
  168. class zandQueue
  169. {
  170. private $mq;
  171. public function __construct($queueName)
  172. {
  173. $jobs = new Jobs(RPC::create('tcp://127.0.0.1:6001'));
  174. $this->mq = $jobs->connect('crons');
  175. }
  176. public function push($message)
  177. {
  178. $task = $this->mq->create(zandMessage::class, $message);
  179. $this->mq->dispatch($task);
  180. }
  181. }
  182. /**
  183. * HTTP worker.
  184. *
  185. * @package zand
  186. */
  187. class zandWorker
  188. {
  189. /**
  190. * RoadRunner PSR7 worker.
  191. *
  192. * @var object
  193. * @access private
  194. */
  195. private $psr7;
  196. /**
  197. * response.
  198. *
  199. * @var object
  200. * @access public
  201. */
  202. public $response;
  203. /**
  204. * Constructor.
  205. *
  206. * @access public
  207. * @return void
  208. */
  209. public function __construct()
  210. {
  211. $worker = Worker::create();
  212. $factory = new Psr17Factory();
  213. $this->psr7 = new PSR7Worker($worker, $factory, $factory, $factory);
  214. $this->response = new zandResponse();
  215. }
  216. /**
  217. * Wait request to run.
  218. *
  219. * @access public
  220. * @return void
  221. */
  222. public function waitRequest()
  223. {
  224. $request = $this->psr7->waitRequest();
  225. $this->initGlobal($request);
  226. $this->response = new zandResponse();
  227. }
  228. /**
  229. * Init global variables.
  230. *
  231. * @param object $request
  232. * @access public
  233. * @return void
  234. */
  235. public function initGlobal($request)
  236. {
  237. $_SERVER = $request->getServerParams();
  238. $_SERVER['REQUEST_TIME'] = time();
  239. $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true);
  240. $_SERVER['SERVER_PROTOCOL'] = $request->getUri()->getScheme();
  241. $_SERVER['REQUEST_METHOD'] = $request->getMethod();
  242. $_SERVER['SERVER_NAME'] = $request->getUri()->getHost();
  243. $_SERVER['SERVER_PORT'] = $request->getUri()->getPort();
  244. $_SERVER['REQUEST_URI'] = $request->getUri()->getPath();
  245. $_SERVER['SCRIPT_NAME'] = '/index.php';
  246. $_SERVER['PHP_SELF'] = 'index.php';
  247. $_SERVER['PATH_TRANSLATED'] = 'index.php';
  248. $_SERVER['HTTP_HOST'] = $_SERVER['SERVER_NAME'] . (in_array($_SERVER['SERVER_PORT'], array(80, 443)) ? '' : ':' . $_SERVER['SERVER_PORT']);
  249. $query = $request->getUri()->getQuery();
  250. if(!empty($query))
  251. {
  252. $_SERVER['REQUEST_URI'] .= '?' . $query;
  253. $_SERVER['QUERY_STRING'] = $query;
  254. }
  255. $_GET = $request->getQueryParams();
  256. $_POST = $request->getParsedBody();
  257. $_COOKIE = $request->getCookieParams();
  258. $_FILE = $request->getUploadedFiles();
  259. }
  260. /**
  261. * Send response.
  262. *
  263. * @param string $body
  264. * @access public
  265. * @return void
  266. */
  267. public function respond($body)
  268. {
  269. $this->response->setBody($body);
  270. $this->psr7->respond($this->response);
  271. }
  272. /**
  273. * Send error.
  274. *
  275. * @param Exception $e
  276. * @access public
  277. * @return void
  278. */
  279. public function error($e)
  280. {
  281. $this->psr7->getWorker()->error((string)$e);
  282. }
  283. }
  284. /**
  285. * MySQL实现的Session管理.
  286. * Session handler implements by MySQL.
  287. *
  288. * @package zand
  289. */
  290. class zandSession
  291. {
  292. /**
  293. * DAO for database.
  294. *
  295. * @var object
  296. * @access private
  297. */
  298. private $dao;
  299. /**
  300. * Constructor.
  301. *
  302. * @param object $dao
  303. * @access public
  304. * @return void
  305. */
  306. public function __construct($dao)
  307. {
  308. $this->dao = $dao;
  309. }
  310. /**
  311. * Open session.
  312. *
  313. * @param string $savePath
  314. * @param string $sessionName
  315. * @access public
  316. * @return bool
  317. */
  318. public function open($savePath, $sessionName)
  319. {
  320. $this->savePath = $savePath;
  321. $this->sessionName = $sessionName;
  322. return true;
  323. }
  324. /**
  325. * Close session.
  326. *
  327. * @access public
  328. * @return bool
  329. */
  330. public function close()
  331. {
  332. return true;
  333. }
  334. /**
  335. * Read session.
  336. *
  337. * @param string $id
  338. * @access public
  339. * @return string
  340. */
  341. public function read($id)
  342. {
  343. $result = $this->dao->select('data')->from(TABLE_SESSION)->where('id')->eq($id)->fetch();
  344. return $result ? $result->data : '';
  345. }
  346. /**
  347. * Write session.
  348. *
  349. * @param string $id
  350. * @param string $data
  351. * @access public
  352. * @return bool
  353. */
  354. public function write($id, $data)
  355. {
  356. $data = array('id' => $id, 'data' => $data, 'timestamp' => time());
  357. $this->dao->replace(TABLE_SESSION)->data($data)->exec();
  358. return true;
  359. }
  360. /**
  361. * Destroy session.
  362. *
  363. * @param string $id
  364. * @access public
  365. * @return bool
  366. */
  367. public function destroy($id)
  368. {
  369. $this->dao->delete()->from(TABLE_SESSION)->where('id')->eq($id)->exec();
  370. return true;
  371. }
  372. /**
  373. * GC for session.
  374. *
  375. * @param int $maxlifetime
  376. * @access public
  377. * @return bool
  378. */
  379. public function gc($maxlifetime)
  380. {
  381. $this->dao->delete()->from(TABLE_SESSION)->where('timestamp')->lt(time() - intval($maxlifetime))->exec();
  382. return true;
  383. }
  384. }