Home > Backend Development > PHP Tutorial > Super simple PHPMVC

Super simple PHPMVC

WBOY
Release: 2016-07-25 08:47:44
Original
1715 people have browsed it
Use native PHP syntax to render pages and provide widget functions.
  1. /**
  2. * Obtaining and setting configuration parameters supports batch definition
  3. * If $key is an associative array, the configuration will be written in the form of K-V
  4. * If $key is a numeric index array, the corresponding configuration array will be returned
  5. * @param string |array $key configuration variable
  6. * @param array|null $value configuration value
  7. * @return array|null
  8. */
  9. function C($key,$value=null){
  10. static $_config = array();
  11. $args = func_num_args();
  12. if( $args == 1){
  13. if(is_string($key)){ //If the incoming key is a string
  14. return isset($_config[$key])?$_config[$key]:null;
  15. }
  16. if(is_array($key)){
  17. if(array_keys($key) !== range(0, count($key) - 1)){ //If the incoming key is an associative array
  18. $_config = array_merge ($_config, $key);
  19. }else{
  20. $ret = array();
  21. foreach ($key as $k) {
  22. $ret[$k] = isset($_config[$k])?$_config [$k]:null;
  23. }
  24. return $ret;
  25. }
  26. }
  27. }else{
  28. if(is_string($key)){
  29. $_config[$key] = $value;
  30. }else{
  31. halt( 'The parameters passed in are incorrect');
  32. }
  33. }
  34. return null;
  35. }
  36. /**
  37. * Call Widget
  38. * @param string $name widget name
  39. * @param array $data Variable list passed to widget, key is variable name, value is variable value
  40. * @return void
  41. */
  42. function W($name, $data = array()){
  43. $fullName = $name. 'Widget';
  44. if(!class_exists($fullName)){
  45. halt('Widget '.$name.' does not exist');
  46. }
  47. $widget = new $fullName();
  48. $widget->invoke ($data);
  49. }
  50. /**
  51. * Terminate program execution
  52. * @param string $str Termination reason
  53. * @param bool $display Whether to display the call stack, not displayed by default
  54. * @return void
  55. */
  56. function halt($str, $display=false){
  57. Log::fatal($str.' debug_backtrace:'.var_export(debug_backtrace(), true ));
  58. header("Content-Type:text/html; charset=utf-8");
  59. if($display){
  60. echo "
    ";
  61. debug_print_backtrace();
  62. echo "";
  63. }
  64. echo $str;
  65. exit;
  66. }
  67. /**
  68. * Get database instance
  69. * @return DB
  70. */
  71. function M(){
  72. $dbConf = C(array('DB_HOST','DB_PORT','DB_USER' ,'DB_PWD','DB_NAME','DB_CHARSET'));
  73. return DB::getInstance($dbConf);
  74. }
  75. /**
  76. * If the file exists, include it
  77. * @param string $path file path
  78. * @return void
  79. */
  80. function includeIfExist($path){
  81. if(file_exists( $path)){
  82. include $path;
  83. }
  84. }
  85. /**
  86. * General control category
  87. */
  88. class SinglePHP {
  89. /**
  90. * controller
  91. * @var string
  92. */
  93. private $c;
  94. /**
  95. * Action
  96. * @var string
  97. */
  98. private $a;
  99. /**
  100. * Singleton
  101. * @var SinglePHP
  102. */
  103. private static $_instance;
  104. /**
  105. * Constructor, initialization configuration
  106. * @param array $conf
  107. */
  108. private function __construct($conf){
  109. C($conf);
  110. }
  111. private function __clone(){}
  112. /**
  113. * Get singleton
  114. * @param array $conf
  115. * @return SinglePHP
  116. */
  117. public static function getInstance($conf){
  118. if(!(self::$_instance instanceof self)){
  119. self::$_instance = new self($ conf);
  120. }
  121. return self::$_instance;
  122. }
  123. /**
  124. * Run application instance
  125. * @access public
  126. * @return void
  127. */
  128. public function run(){
  129. if(C('USE_SESSION') == true){
  130. session_start();
  131. }
  132. C('APP_FULL_PATH', getcwd().'/'.C('APP_PATH').'/');
  133. includeIfExist( C('APP_FULL_PATH').'/common.php');
  134. $pathMod = C('PATH_MOD');
  135. $pathMod = empty($pathMod)?'NORMAL':$pathMod;
  136. spl_autoload_register(array('SinglePHP', 'autoload'));
  137. if(strcmp(strtoupper($pathMod) ,'NORMAL') === 0 || !isset($_SERVER['PATH_INFO'])){
  138. $this->c = isset($_GET['c'])?$_GET['c'] :'Index';
  139. $this->a = isset($_GET['a'])?$_GET['a']:'Index';
  140. }else{
  141. $pathInfo = isset($_SERVER[' PATH_INFO'])?$_SERVER['PATH_INFO']:'';
  142. $pathInfoArr = explode('/',trim($pathInfo,'/'));
  143. if(isset($pathInfoArr[0]) && $ pathInfoArr[0] !== ''){
  144. $this->c = $pathInfoArr[0];
  145. }else{
  146. $this->c = 'Index';
  147. }
  148. if(isset($pathInfoArr [1])){
  149. $this->a = $pathInfoArr[1];
  150. }else{
  151. $this->a = 'Index';
  152. }
  153. }
  154. if(!class_exists($this-> ;c.'Controller')){
  155. halt('Controller'.$this->c.'does not exist');
  156. }
  157. $controllerClass = $this->c.'Controller';
  158. $controller = new $controllerClass();
  159. if(!method_exists($controller, $this->a.'Action')){
  160. halt('method'.$this->a.'does not exist');
  161. }
  162. call_user_func(array($controller,$this->a.'Action'));
  163. }
  164. /**
  165. * Automatic loading function
  166. * @param string $class class name
  167. */
  168. public static function autoload($class){
  169. if(substr($class ,-10)=='Controller'){
  170. includeIfExist(C('APP_FULL_PATH').'/Controller/'.$class.'.class.php');
  171. }elseif(substr($class,-6) =='Widget'){
  172. includeIfExist(C('APP_FULL_PATH').'/Widget/'.$class.'.class.php');
  173. }else{
  174. includeIfExist(C('APP_FULL_PATH').'/Lib/'.$class.'.class.php');
  175. }
  176. }
  177. }
  178. /**
  179. * Controller class
  180. */
  181. class Controller {
  182. /**
  183. * View instance
  184. * @var View
  185. */
  186. private $_view;
  187. /**
  188. * Constructor, initialize view instance, call hook
  189. */
  190. public function __construct(){
  191. $this->_view = new View();
  192. $this->_init();
  193. }
  194. /**
  195. * Pre-hook
  196. */
  197. protected function _init(){}
  198. /**
  199. * Render the template and output
  200. * @param null|string $tpl template file path
  201. * The parameter is the relative path relative to App/View/file, does not include the suffix name, such as index/index
  202. * If the parameter is empty, then $controller/$action.php is used by default
  203. * If the parameter does not contain "/", $controller/$tpl is used by default
  204. * @return void
  205. */
  206. protected function display($tpl=''){
  207. if($tpl === ''){
  208. $trace = debug_backtrace();
  209. $controller = substr($trace[1]['class'], 0, -10);
  210. $action = substr($trace[1]['function'], 0 , -6);
  211. $tpl = $controller . '/' . $action;
  212. }elseif(strpos($tpl, '/') === false){
  213. $trace = debug_backtrace();
  214. $controller = substr($trace[1]['class'], 0, -10);
  215. $tpl = $controller . '/' . $tpl;
  216. }
  217. $this->_view->display($tpl);
  218. }
  219. /**
  220. * Set a template variable for the view engine
  221. * @param string $name The variable name to be used in the template
  222. * @param mixed $value The value corresponding to the variable name in the template
  223. * @return void
  224. */
  225. protected function assign($name,$value){
  226. $this->_view->assign($name,$value);
  227. }
  228. /**
  229. * Output the data to the browser in json format and stop executing the code
  230. * @param array $data The data to be output
  231. */
  232. protected function ajaxReturn($data){
  233. echo json_encode($data);
  234. exit;
  235. }
  236. /**
  237. * Redirect to the specified url
  238. * @param string $url The url to be redirected
  239. * @param void
  240. */
  241. protected function redirect($url){
  242. header("Location: $url");
  243. exit;
  244. }
  245. }
  246. /**
  247. * View class
  248. */
  249. class View {
  250. /**
  251. * View file directory
  252. * @var string
  253. */
  254. private $_tplDir;
  255. /**
  256. * View file path
  257. * @var string
  258. */
  259. private $_viewPath;
  260. /**
  261. * View variable list
  262. * @var array
  263. */
  264. private $_data = array();
  265. /**
  266. * Variable list for tplInclude
  267. * @var array
  268. */
  269. private static $tmpData;
  270. /**
  271. * @param string $tplDir
  272. */
  273. public function __construct($tplDir=''){
  274. if($tplDir == ''){
  275. $this->_tplDir = './'.C('APP_PATH').'/View/';
  276. }else{
  277. $this->_tplDir = $tplDir;
  278. }
  279. }
  280. /**
  281. * Set a template variable for the view engine
  282. * @param string $key The variable name to be used in the template
  283. * @param mixed $value The value corresponding to the variable name in the template
  284. * @return void
  285. */
  286. public function assign($key, $value) {
  287. $this->_data[$key] = $value;
  288. }
  289. /**
  290. * Render the template and output
  291. * @param null|string $tplFile Template file path, relative path to App/View/file, does not include suffix name, such as index/index
  292. * @return void
  293. */
  294. public function display($tplFile) {
  295. $this->_viewPath = $this->_tplDir . $tplFile . '.php';
  296. unset($tplFile);
  297. extract($this->_data);
  298. include $this->_viewPath;
  299. }
  300. /**
  301. * Used to include other templates in the template file
  302. * @param string $path The path relative to the View directory
  303. * @param array $data The variable list passed to the sub-template, key is the variable name, value is the variable value
  304. * @return void
  305. */
  306. public static function tplInclude($path, $data=array()){
  307. self::$tmpData = array(
  308. 'path' => C('APP_FULL_PATH') . '/View/' . $path . '.php',
  309. 'data' => $data,
  310. );
  311. unset($path);
  312. unset($data);
  313. extract(self::$tmpData['data']);
  314. include self::$tmpData['path'];
  315. }
  316. }
  317. /**
  318. * Widget class
  319. * When using it, you need to inherit this class, rewrite the invoke method, and call display in the invoke method
  320. */
  321. class Widget {
  322. /**
  323. * View instance
  324. * @var View
  325. */
  326. protected $_view;
  327. /**
  328. * Widget name
  329. * @var string
  330. */
  331. protected $_widgetName;
  332. /**
  333. * Constructor, initialize view instance
  334. */
  335. public function __construct(){
  336. $this->_widgetName = get_class($this);
  337. $dir = C('APP_FULL_PATH') . '/Widget/Tpl/';
  338. $this->_view = new View($dir);
  339. }
  340. /**
  341. * Processing logic
  342. * @param mixed $data parameter
  343. */
  344. public function invoke($data){}
  345. /**
  346. * Render template
  347. * @param string $tpl template path, if it is empty, use the class name as the template name
  348. */
  349. protected function display($tpl=''){
  350. if($tpl == ''){
  351. $tpl = $this->_widgetName;
  352. }
  353. $this->_view->display($tpl);
  354. }
  355. /**
  356. * Set a template variable for the view engine
  357. * @param string $name The variable name to be used in the template
  358. * @param mixed $value The value corresponding to the variable name in the template
  359. * @return void
  360. */
  361. protected function assign($name,$value){
  362. $this->_view->assign($name,$value);
  363. }
  364. }
  365. /**
  366. * Database operation class
  367. * Usage method:
  368. * DB::getInstance($conf)->query('select * from table');
  369. * where $conf is an associative array and needs to contain the following keys:
  370. * DB_HOST DB_USER DB_PWD DB_NAME
  371. * You can use DB_PORT and DB_CHARSET to specify the port and encoding. The default is 3306 and utf8
  372. */
  373. class DB {
  374. /**
  375. * Database link
  376. * @var resource
  377. */
  378. private $_db;
  379. /**
  380. * Save the last sql
  381. * @var string
  382. */
  383. private $_lastSql;
  384. /**
  385. * The number of rows affected by the last sql statement
  386. * @var int
  387. */
  388. private $_rows;
  389. /**
  390. * Error in the last sql execution
  391. * @var string
  392. */
  393. private $_error;
  394. /**
  395. * Instance array
  396. * @var array
  397. */
  398. private static $_instance = array();
  399. /**
  400. * Constructor
  401. * @param array $dbConf configuration array
  402. */
  403. private function __construct($dbConf){
  404. if(!isset($dbConf['DB_CHARSET'])){
  405. $dbConf['DB_CHARSET'] = 'utf8';
  406. }
  407. $this->_db = mysql_connect($dbConf['DB_HOST'].':'.$dbConf['DB_PORT'],$dbConf['DB_USER'],$dbConf['DB_PWD']);
  408. if($this->_db === false){
  409. halt(mysql_error());
  410. }
  411. $selectDb = mysql_select_db($dbConf['DB_NAME'],$this->_db);
  412. if($selectDb === false){
  413. halt(mysql_error());
  414. }
  415. mysql_set_charset($dbConf['DB_CHARSET']);
  416. }
  417. private function __clone(){}
  418. /**
  419. * Get DB class
  420. * @param array $dbConf configuration array
  421. * @return DB
  422. */
  423. static public function getInstance($dbConf){
  424. if(!isset($dbConf['DB_PORT'])){
  425. $dbConf['DB_PORT'] = '3306';
  426. }
  427. $key = $dbConf['DB_HOST'].':'.$dbConf['DB_PORT'];
  428. if(!isset(self::$_instance[$key]) || !(self::$_instance[$key] instanceof self)){
  429. self::$_instance[$key] = new self($dbConf);
  430. }
  431. return self::$_instance[$key];
  432. }
  433. /**
  434. * Escaped string
  435. * @param string $str The string to be escaped
  436. * @return string The escaped string
  437. */
  438. public function escape($str){
  439. return mysql_real_escape_string($str, $this->_db);
  440. }
  441. /**
  442. * Query, used for select statements
  443. * @param string $sql The sql to be queried
  444. * @return bool|array If the query succeeds, it returns the corresponding array, if it fails, it returns false
  445. */
  446. public function query($sql){
  447. $this->_rows = 0;
  448. $this->_error = '';
  449. $this->_lastSql = $sql;
  450. $this->logSql();
  451. $res = mysql_query($sql,$this->_db);
  452. if($res === false){
  453. $this->_error = mysql_error($this->_db);
  454. $this->logError();
  455. return false;
  456. }else{
  457. $this->_rows = mysql_num_rows($res);
  458. $result = array();
  459. if($this->_rows >0) {
  460. while($row = mysql_fetch_array($res, MYSQL_ASSOC)){
  461. $result[] = $row;
  462. }
  463. mysql_data_seek($res,0);
  464. }
  465. return $result;
  466. }
  467. }
  468. /**
  469. * Query, used for insert/update/delete statements
  470. * @param string $sql The sql to be queried
  471. * @return bool|int If the query succeeds, it returns the number of affected records, if it fails, it returns false
  472. */
  473. public function execute($sql) {
  474. $this->_rows = 0;
  475. $this->_error = '';
  476. $this->_lastSql = $sql;
  477. $this->logSql();
  478. $result = mysql_query($sql, $this->_db) ;
  479. if ( false === $result) {
  480. $this->_error = mysql_error($this->_db);
  481. $this->logError();
  482. return false;
  483. } else {
  484. $this->_rows = mysql_affected_rows($this->_db);
  485. return $this->_rows;
  486. }
  487. }
  488. /**
  489. * Get the number of records affected by the last query
  490. * @return int The number of records affected
  491. */
  492. public function getRows(){
  493. return $this->_rows;
  494. }
  495. /**
  496. * Get the auto-increment ID generated after the last insert
  497. * @return int Auto-increment ID
  498. */
  499. public function getInsertId() {
  500. return mysql_insert_id($this->_db);
  501. }
  502. /**
  503. * Get the sql of the last query
  504. * @return string sql
  505. */
  506. public function getLastSql(){
  507. return $this->_lastSql;
  508. }
  509. /**
  510. * Get the error information of the last query
  511. * @return string error information
  512. */
  513. public function getError(){
  514. return $this->_error;
  515. }
  516. /**
  517. * Record sql to file
  518. */
  519. private function logSql(){
  520. Log::sql($this->_lastSql);
  521. }
  522. /**
  523. * Record error log to file
  524. */
  525. private function logError(){
  526. $str = '[SQL ERR]'.$this->_error.' SQL:'.$this->_lastSql;
  527. Log::warn($str);
  528. }
  529. }
  530. /**
  531. * Log class
  532. * Usage method: Log::fatal('error msg');
  533. * The saving path is App/Log, stored by day
  534. * Fatal and warning will be recorded in the .log.wf file
  535. */
  536. class Log{
  537. /**
  538. * Logging, supports SAE environment
  539. * @param string $msg Log content
  540. * @param string $level Log level
  541. * @param bool $wf Whether it is an error log
  542. */
  543. public static function write($msg, $level='DEBUG', $wf=false){
  544. if(function_exists('sae_debug')){ //如果是SAE,则使用sae_debug函数打日志
  545. $msg = "[{$level}]".$msg;
  546. sae_set_display_errors(false);
  547. sae_debug(trim($msg));
  548. sae_set_display_errors(true);
  549. }else{
  550. $msg = date('[ Y-m-d H:i:s ]')."[{$level}]".$msg."rn";
  551. $logPath = C('APP_FULL_PATH').'/Log/'.date('Ymd').'.log';
  552. if($wf){
  553. $logPath .= '.wf';
  554. }
  555. file_put_contents($logPath, $msg, FILE_APPEND);
  556. }
  557. }
  558. /**
  559. * Print fatal log
  560. * @param string $msg Log information
  561. */
  562. public static function fatal($msg){
  563. self::write($msg, 'FATAL', true);
  564. }
  565. /**
  566. * Print warning log
  567. * @param string $msg Log information
  568. */
  569. public static function warn($msg){
  570. self::write($msg, 'WARN', true);
  571. }
  572. /**
  573. * Print notice log
  574. * @param string $msg Log information
  575. */
  576. public static function notice($msg){
  577. self::write($msg, 'NOTICE');
  578. }
  579. /**
  580. * Print debug log
  581. * @param string $msg Log information
  582. */
  583. public static function debug($msg){
  584. self::write($msg, 'DEBUG');
  585. }
  586. /**
  587. * Print sql log
  588. * @param string $msg Log information
  589. */
  590. public static function sql($msg){
  591. self::write($msg, 'SQL');
  592. }
  593. }
  594. /**
  595. * ExtException class, records additional exception information
  596. */
  597. class ExtException extends Exception{
  598. /**
  599. * @var array
  600. */
  601. protected $extra;
  602. /**
  603. * @param string $message
  604. * @param array $extra
  605. * @param int $code
  606. * @param null $previous
  607. */
  608. public function __construct($message = "", $extra = array(), $code = 0, $previous = null){
  609. $this->extra = $extra;
  610. parent::__construct($message, $code, $previous);
  611. }
  612. /**
  613. * Get additional exception information
  614. * @return array
  615. */
  616. public function getExtra(){
  617. return $this->extra;
  618. }
  619. }
复制代码


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template