首頁  >  文章  >  後端開發  >  超簡潔PHPMVC

超簡潔PHPMVC

WBOY
WBOY原創
2016-07-25 08:47:441703瀏覽
原生PHP語法來渲染頁面,同時提供了widget功能
  1. /**
  2. * 取得和設定組態參數支援批次定義
  3. * 如果$key是關聯型數組,則會以K-V的形式寫入配置
  4. * 如果$key是數字索引數組,則傳回對應的配置陣列
  5. * @param string|array $key 設定變數
  6. * @param array|null $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)){ //如果傳入的key是字串
  14. return isset($_config[$key])?$_config[$key]:null;
  15. }
  16. if(is_array($key)){
  17. if(array_keys($key) !== range( 0, count($key) - 1)){ //如果傳入的key是關聯數組
  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('傳入參數不正確');
  32. }
  33. }
  34. return null;
  35. }
  36. /**
  37. * 呼叫Widget
  38. * @param string $name widget名
  39. * @param array $data 傳遞給widget的變數列表,key為變數名,value為變數值
  40. * @return void
  41. */
  42. function W($ name, $data = array()){
  43. $fullName = $name.'Widget';
  44. if(!class_exists($fullName)){
  45. halt('Widget '.$name.'不存在');
  46. }
  47. $widget = new $fullName();
  48. $widget->invoke($data);
  49. }
  50. /**
  51. * 終止程式執行
  52. * @param string $str 終止原因
  53. * @param bool $display 是否顯示呼叫堆疊,預設不顯示
  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. * 取得資料庫執行個體
  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. * 如果檔案存在就include進來
  77. * @param string $path 檔案路徑
  78. * @return void
  79. * /
  80. function includeIfExist($path){
  81. if(file_exists($path)){
  82. include $path;
  83. }
  84. }
  85. /**
  86. * 總控類
  87. */
  88. class SinglePHP {
  89. /**
  90. * 控制器
  91. * @var string
  92. */
  93. private $c;
  94. /**
  95. * 操作
  96. * @var string
  97. */
  98. private $a;
  99. /**
  100. * 單例
  101. * @var SinglePHP
  102. */
  103. private static $_instance;
  104. /**
  105. * 建構函數,初始化配置
  106. * @param array $conf
  107. */
  108. private function __construct($conf){
  109. C($conf);
  110. }
  111. private function>private function>private function>private function>private function> __clone(){}
  112. /**
  113. * 取得單例
  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. * 執行應用程式實例
  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('控制器'.$this->c.'不存在');
  156. }
  157. $controllerClass = $this->c.'Controller';
  158. $controller = new $controllerClass();
  159. if(!method_exists($controller, $this->a.'Action')){
  160. halt('方法'.$this->a.'不存在');
  161. }
  162. call_user_func(array($controller,$this->a.'Action'));
  163. }
  164. /**
  165. * 自動載入函數
  166. * @param string $class 類別名稱
  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. * 컨트롤러 클래스
  180. */
  181. 클래스 컨트롤러 {
  182. /**
  183. * 인스턴스 보기
  184. * @var 보기
  185. */
  186. private $_view;
  187. /**
  188. * 생성자, 뷰 인스턴스 초기화, 후크 호출
  189. */
  190. public 함수 __construct(){
  191. $this->_view = new View();
  192. $this->_init();
  193. }
  194. /**
  195. * 프리훅
  196. */
  197. 보호된 함수 _init(){}
  198. /**
  199. * 템플릿 렌더링 및 출력
  200. * @param null|string $tpl 템플릿 파일 경로
  201. * 매개변수는 앱/뷰/파일에 대한 상대 경로이며 다음과 같은 접미사 이름을 포함하지 않습니다. index/index
  202. * 매개변수가 비어 있는 경우 기본값은 $controller/$action.php
  203. * 매개변수에 "/"가 포함되어 있지 않으면 기본값은 $controller/$tpl
  204. * @ 무효 반환
  205. */
  206. 보호된 함수 표시($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 = $컨트롤러 . '/' . $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. * 뷰 엔진에 대한 템플릿 변수 설정
  221. * @param string $name 템플릿에서 사용할 변수 이름
  222. * @param mix $value 템플릿의 변수 이름에 해당하는 값
  223. * @ 반환 무효
  224. */
  225. 보호된 함수 할당($name, $value){
  226. $this->_view->할당($name,$value);
  227. }
  228. /**
  229. * 데이터를 json 형식으로 브라우저에 출력하고 코드 실행을 중지합니다
  230. * @param array $data 출력할 데이터
  231. */
  232. 보호된 함수 ajaxReturn($data) {
  233. echo json_encode($data);
  234. exit;
  235. }
  236. /**
  237. * 지정된 URL로 리디렉션
  238. * @param string $url 리디렉션할 URL
  239. * @param void
  240. */
  241. 보호된 함수 리디렉션($url){
  242. header("위치: $url");
  243. exit;
  244. }
  245. }
  246. /**
  247. * 수업 보기
  248. */
  249. 클래스 보기 {
  250. /**
  251. * 파일 디렉터리 보기
  252. * @var string
  253. */
  254. 비공개 $_tplDir;
  255. /**
  256. * 파일 경로 보기
  257. * @var string
  258. */
  259. 비공개 $_viewPath;
  260. /**
  261. * 변수 목록 보기
  262. * @var array
  263. */
  264. 비공개 $_data = array();
  265. /**
  266. * tplInclude용 변수 목록
  267. * @var array
  268. */
  269. 비공개 정적 $tmpData;
  270. /**
  271. * @param 문자열 $tplDir
  272. */
  273. 공용 함수 __construct($tplDir=''){
  274. if($tplDir == ''){
  275. $this->_tplDir = './'.C('APP_PATH').'/View/';
  276. }else{
  277. $this->_tplDir = $tplDir;
  278. }
  279. }
  280. /**
  281. * 뷰 엔진에 대한 템플릿 변수 설정
  282. * @param string $key 템플릿에서 사용할 변수 이름
  283. * @param mix $value 템플릿의 변수 이름에 해당하는 값
  284. * @ 반환 무효
  285. */
  286. 공용 함수 할당($key, $value) {
  287. $this->_data[$key] = $value;
  288. }
  289. /**
  290. * 템플릿 렌더링 및 출력
  291. * @param null|string $tplFile 앱/뷰/파일을 기준으로 한 템플릿 파일 경로에는 인덱스/인덱스와 같은 접미사 이름이 포함되지 않습니다.
  292. * @return void
  293. */
  294. 공용 함수 표시($tplFile) {
  295. $this->_viewPath = $this->_tplDir . $tpl파일 . '.php';
  296. unset($tplFile);
  297. extract($this->_data);
  298. include $this->_viewPath;
  299. }
  300. /**
  301. * 템플릿 파일에 다른 템플릿을 포함하는 데 사용됩니다.
  302. * @param string $path View 디렉터리에 대한 상대 경로
  303. * @param array $data 하위 템플릿에 전달되는 변수 목록, 키 은 변수 이름이고, value는 변수 값입니다
  304. * @return void
  305. */
  306. 공용 정적 함수 tplInclude($path, $data=array()){
  307. self::$tmpData = array(
  308. 'path' => C('APP_FULL_PATH') .' /보기/' . $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. * 위젯 클래스
  319. * 사용 시 이 클래스를 상속받아서 Invoke 메소드를 오버라이드하고, Invoke 메소드에서 display
  320. 를 호출해야 합니다.*/
  321. 클래스 위젯 {
  322. /**
  323. * 인스턴스 보기
  324. * @var 보기
  325. */
  326. protected $_view;
  327. /**
  328. * 위젯명
  329. * @var string
  330. */
  331. protected $_widgetName;
  332. /**
  333. * 생성자, 뷰 인스턴스 초기화
  334. */
  335. 공용 함수 __construct(){
  336. $this->_widgetName = get_class($this);
  337. $dir = C('APP_FULL_PATH') . '/Widget/Tpl/';
  338. $this->_view = new View($dir);
  339. }
  340. /**
  341. * 처리 로직
  342. * @param 혼합 $data 매개변수
  343. */
  344. 공용 함수 호출($data) {}
  345. /**
  346. * 렌더 템플릿
  347. * @param string $tpl 템플릿 경로, 비어 있으면 클래스 이름을 템플릿 이름으로 사용
  348. */
  349. 보호된 함수 표시($tpl=''){
  350. if($tpl == ''){
  351. $tpl = $this-> ;_widgetName;
  352. }
  353. $this->_view->display($tpl);
  354. }
  355. /**
  356. * 뷰 엔진에 대한 템플릿 변수 설정
  357. * @param string $name 템플릿에서 사용할 변수 이름
  358. * @param mix $value 템플릿의 변수 이름에 해당하는 값
  359. * @ 반환 무효
  360. */
  361. 보호된 함수 할당($name, $value){
  362. $this->_view->할당($name,$value);
  363. }
  364. }
  365. /**
  366. * 데이터베이스 작업 클래스
  367. * 사용 방법:
  368. * DB::getInstance($conf)->query('select * from table');
  369. * 여기서 $conf는 연관 배열입니다. , 다음 키를 포함해야 합니다:
  370. * DB_HOST DB_USER DB_PWD DB_NAME
  371. * DB_PORT 및 DB_CHARSET을 사용하여 포트와 인코딩을 지정할 수 있으며 기본값은 3306 및 utf8입니다
  372. */
  373. 클래스 DB {
  374. /**
  375. * 데이터베이스 링크
  376. * @var 리소스
  377. */
  378. 비공개 $_db;
  379. /**
  380. * 마지막 sql 저장
  381. * @var string
  382. */
  383. 비공개 $_lastSql;
  384. /**
  385. * 마지막 SQL 문의 영향을 받은 행 수
  386. * @var int
  387. */
  388. 비공개 $_rows;
  389. /**
  390. * 마지막 SQL 실행 오류
  391. * @var string
  392. */
  393. 비공개 $_error;
  394. /**
  395. * 인스턴스 배열
  396. * @var 배열
  397. */
  398. 비공개 정적 $_instance = array();
  399. /**
  400. * 생성자
  401. * @param array $dbConf 구성 배열
  402. */
  403. 비공개 함수 __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. 비공개 함수 __clone(){}
  418. /**
  419. * DB 클래스 가져오기
  420. * @param array $dbConf 구성 배열
  421. * @return DB
  422. */
  423. 정적 공개 함수 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] self) ){
  429. self::$_instance[$key] = new self($dbConf);
  430. }
  431. return self::$_instance[$key];
  432. }
  433. /**
  434. * 이스케이프된 문자열
  435. * @param string $str 이스케이프할 문자열
  436. * @return string 이스케이프된 문자열
  437. */
  438. 공용 함수 escape($str){
  439. return mysql_real_escape_string($str, $this->_db);
  440. }
  441. /**
  442. * select 문에 사용되는 쿼리
  443. * @param string $sql 쿼리할 sql
  444. * @return bool|array 쿼리가 성공하면 해당 배열을 반환하고, 실패하면 해당 배열을 반환하고, 거짓
  445. */
  446. 공용 함수 쿼리($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. 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. * 삽입/업데이트/삭제 문에 사용되는 쿼리
  470. * @param string $sql 쿼리할 SQL
  471. * @return bool|int 쿼리가 성공하면 영향을 받은 레코드 수를 반환하고, 실패하면 false를 반환합니다
  472. */
  473. 공용 함수 실행($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. false 반환;
  483. } else {
  484. $this->_rows = mysql_affected_rows($ this->_db);
  485. return $this->_rows;
  486. }
  487. }
  488. /**
  489. * 마지막 쿼리의 영향을 받은 레코드 수 가져오기
  490. * @return int 영향을 받은 레코드 수
  491. */
  492. 공용 함수 getRows(){
  493. return $this->_rows;
  494. }
  495. /**
  496. * 마지막 삽입 이후 생성된 자동 증가 ID 가져오기
  497. * @return int 자동 증가 ID
  498. */
  499. 공개 함수 getInsertId() {
  500. return mysql_insert_id($this->_db);
  501. }
  502. /**
  503. * 마지막 쿼리의 sql 가져오기
  504. * @return string sql
  505. */
  506. 공용 함수 getLastSql(){
  507. return $this->_lastSql;
  508. }
  509. /**
  510. * 마지막 쿼리의 오류 정보 가져오기
  511. * @return 문자열 오류 정보
  512. */
  513. 공용 함수 getError(){
  514. return $this->_error;
  515. }
  516. /**
  517. * SQL을 파일에 기록
  518. */
  519. 비공개 함수 logSql(){
  520. Log::sql($this- >_lastSql);
  521. }
  522. /**
  523. * 오류 로그를 파일에 기록
  524. */
  525. 비공개 함수 logError(){
  526. $str = '[SQL ERR]'.$this->_error.' SQL:'.$this->_lastSql;
  527. 로그::warn($str);
  528. }
  529. }
  530. /**
  531. * 로그 클래스
  532. * 사용 방법: Log::fatal('error msg');
  533. * 저장 경로는 App/Log, 날짜별로 저장됩니다.
  534. * Fatal 및 warning은 에 기록됩니다. .wf 파일의 .log
  535. */
  536. 클래스 로그{
  537. /**
  538. * 로그, SAE 환경 지원
  539. * @param string $msg 로그 내용
  540. * @param string $level 로그 수준
  541. * @param bool $wf 오류 로그 여부
  542. */
  543. 공용 정적 함수 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 (참);
  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. * 列印fatal日誌
  560. * @param string $msg 日誌資訊
  561. */
  562. 公用靜態函數fatal($msg){
  563. self::write($msg, 'FATAL', true);
  564. }
  565. /**
  566. * 列印warning日誌
  567. * @param string $msg 日誌資訊
  568. */
  569. 公用靜態函數warn($msg){
  570. self::write($msg, 'WARN', true);
  571. }
  572. /**
  573. * 列印notice日誌
  574. * @param string $msg 日誌資訊
  575. */
  576. 公共靜態函數通知($msg) {
  577. self::write($msg, '注意');
  578. }
  579. /**
  580. * 列印debug日誌
  581. * @param string $msg 日誌資訊
  582. */
  583. 公用靜態函式debug($msg){
  584. self:: write($msg, 'DEBUG');
  585. }
  586. /**
  587. * 列印sql日誌
  588. * @param string $msg 日誌資訊
  589. */
  590. 公用靜態函數sql($msg){
  591. self::write($msg, 'SQL ');
  592. }
  593. }
  594. /**
  595. * ExtException類,記錄額外的異常資訊
  596. */
  597. class ExtException extends Exception{
  598. /**
  599. * @var 陣列
  600. */
  601. protected $extra;/**
  602. * @param string $message
  603. * @param array $extra
  604. * @param int $code
  605. * @param null $previous
  606. */
  607. public function __construct($message = "", $extra = array(), $code = 0, $previous = null){
  608. $this->extra = $ extra;
  609. parent::__construct($message, $code, $previous);
  610. }
  611. /**
  612. * 取得額外的異常資訊
  613. * @return array
  614. */
  615. public function getExtra(){
  616. return $this this this ->extra;
  617. }
  618. }
複製程式碼


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn