搜索
首页后端开发php教程b2Core : 300 行的php MVC 架构

b2Core 是一个轻量 php MVC 框架, 300 行代码封装了常用 CRUD 等实用功能。
最新版代码请见 http://b2core.b24.cn ,欢迎批评和建议。

本页中对对于代码的各个部分做了详尽的注释.
前台请求的格式为

http://domain/index.php/controller/method/param1/param2/

http://domain/controller/method/param1/param2/
  1. /**
  2. * B2Core 是由 Brant (brantx@gmail.com)发起的基于PHP的MVC架构
  3. * 核心思想是在采用MVC框架的基础上最大限度的保留php的灵活性
  4. * Vison 2.0 (20120515)
  5. * */
  6. define('VERSION','2.0');
  7. // 载入配置文件:数据库、url路由等等
  8. require(APP.'config.php');
  9. // 如果配置了数据库则载入
  10. if(isset($db_config)) $db = new db($db_config);
  11. // 获取请求的地址兼容 SAE
  12. $uri = '';
  13. if(isset($_SERVER['PATH_INFO'])) $uri = $_SERVER['PATH_INFO'];
  14. if(isset($_SERVER['ORIG_PATH_INFO'])) $uri = $_SERVER['ORIG_PATH_INFO'];
  15. if(isset($_SERVER['SCRIPT_URL'])) $uri = $_SERVER['SCRIPT_URL'];
  16. // 去除Magic_Quotes
  17. if(get_magic_quotes_gpc()) // Maybe would be removed in php6
  18. {
  19. function stripslashes_deep($value)
  20. {
  21. $value = is_array($value) ? array_map('stripslashes_deep', $value) : (isset($value) ? stripslashes($value) : null);
  22. return $value;
  23. }
  24. $_POST = stripslashes_deep($_POST);
  25. $_GET = stripslashes_deep($_GET);
  26. $_COOKIE = stripslashes_deep($_COOKIE);
  27. }
  28. // 执行 config.php 中配置的url路由
  29. foreach ($route_config as $key => $val)
  30. {
  31. $key = str_replace(':any', '([^\/.]+)', str_replace(':num', '([0-9]+)', $key));
  32. if (preg_match('#^'.$key.'#', $uri))$uri = preg_replace('#^'.$key.'#', $val, $uri);
  33. }
  34. // 获取URL中每一段的参数
  35. $uri = rtrim($uri,'/');
  36. $seg = explode('/',$uri);
  37. $des_dir = $dir = '';
  38. /* 依次载入控制器上级所有目录的架构文件 __construct.php
  39. * 架构文件可以包含当前目录下的所有控制器的父类,和需要调用的函数
  40. */
  41. foreach($seg as $cur_dir)
  42. {
  43. $des_dir.=$cur_dir."/";
  44. if(is_file(APP.'c'.$des_dir.'__construct.php')) {
  45. require(APP.'c'.$des_dir.'__construct.php');
  46. $dir .=array_shift($seg).'/';
  47. }
  48. else {
  49. break;
  50. }
  51. }
  52. /* 根据 url 调用控制器中的方法,如果不存在返回 404 错误
  53. * 默认请求 class home->index()
  54. */
  55. $dir = $dir ? $dir:'/';
  56. array_unshift($seg,NULL);
  57. $class = isset($seg[1])?$seg[1]:'home';
  58. $method = isset($seg[2])?$seg[2]:'index';
  59. if(!is_file(APP.'c'.$dir.$class.'.php'))show_404();
  60. require(APP.'c'.$dir.$class.'.php');
  61. if(!class_exists($class))show_404();
  62. if(!method_exists($class,$method))show_404();
  63. $B2 = new $class();
  64. call_user_func_array(array(&$B2, $method), array_slice($seg, 3));
  65. /* B2 系统函数
  66. * load($path,$instantiate) 可以动态载入对象,如:控制器、Model、库类等
  67. * $path 是类文件相对 app 的地址
  68. * $instantiate 为 False 时,仅引用文件,不实例化对象
  69. * $instantiate 为数组时,数组内容会作为参数传递给对象
  70. */
  71. function &load($path, $instantiate = TRUE )
  72. {
  73. $param = FALSE;
  74. if(is_array($instantiate)) {
  75. $param = $instantiate;
  76. $instantiate = TRUE;
  77. }
  78. $file = explode('/',$path);
  79. $class_name = array_pop($file);
  80. $object_name = md5($path);
  81. static $objects = array();
  82. if (isset($objects[$object_name])) return $objects[$object_name];
  83. require(APP.$path.'.php');
  84. if ($instantiate == FALSE) $objects[$object_name] = TRUE;
  85. if($param)$objects[$object_name] = new $class_name($param);
  86. else $objects[$object_name] = new $class_name();
  87. return $objects[$object_name];
  88. }
  89. /* 调用 view 文件
  90. * function view($view,$param = array(),$cache = FALSE)
  91. * $view 是模板文件相对 app/v/ 目录的地址,地址应去除 .php 文件后缀
  92. * $param 数组中的变量会传递给模板文件
  93. * $cache = TRUE 时,不像浏览器输出结果,而是以 string 的形式 return
  94. */
  95. function view($view,$param = array(),$cache = FALSE)
  96. {
  97. if(!empty($param))extract($param);
  98. ob_start();
  99. if(is_file(APP.$view.'.php')) {
  100. require APP.$view.'.php';
  101. }
  102. else {
  103. echo 'view '.$view.' desn\'t exsit';
  104. return false;
  105. }
  106. // Return the file data if requested
  107. if ($cache === TRUE)
  108. {
  109. $buffer = ob_get_contents();
  110. @ob_end_clean();
  111. return $buffer;
  112. }
  113. }
  114. // 取得 url 的片段,如 url 是 /abc/def/g/ seg(1) = abc
  115. function seg($i)
  116. {
  117. global $seg;
  118. return isset($seg[$i])?$seg[$i]:false;
  119. }
  120. // 写入日志
  121. function write_log($level = 0 ,$content = 'none')
  122. {
  123. file_put_contents(APP.'log/'.$level.'-'.date('Y-m-d').'.log', $content , FILE_APPEND );
  124. }
  125. // 显示404错误
  126. function show_404() //显示 404 错误
  127. {
  128. header("HTTP/1.1 404 Not Found");
  129. // 调用 模板 v/404.php
  130. view('v/404');
  131. exit(1);
  132. }
  133. /* B2Core 系统类 */
  134. // 抽象的控制器类,建议所有的控制器均基层此类或者此类的子类
  135. class c {
  136. function index()
  137. {
  138. echo "基于 B2 v".VERSION." 创建";
  139. }
  140. }
  141. // 数据库操作类
  142. class db {
  143. var $link;
  144. var $last_query;
  145. function __construct($conf)
  146. {
  147. $this->link = mysql_connect($conf['host'],$conf['user'], $conf['password']);
  148. if (!$this->link) {
  149. die('无法连接: ' . mysql_error());
  150. return FALSE;
  151. }
  152. $db_selected = mysql_select_db($conf['default_db']);
  153. if (!$db_selected) {
  154. die('无法使用 : ' . mysql_error());
  155. }
  156. mysql_query('set names utf8',$this->link);
  157. }
  158. //执行 query 查询,如果结果为数组,则返回数组数据
  159. function query($query)
  160. {
  161. $ret = array();
  162. $this->last_query = $query;
  163. $result = mysql_query($query,$this->link);
  164. if (!$result) {
  165. echo "DB Error, could not query the database\n";
  166. echo 'MySQL Error: ' . mysql_error();
  167. echo 'Error Query: ' . $query;
  168. exit;
  169. }
  170. if($result == 1 )return TRUE;
  171. while($record = mysql_fetch_assoc($result))
  172. {
  173. $ret[] = $record;
  174. }
  175. return $ret;
  176. }
  177. function insert_id() {return mysql_insert_id();}
  178. // 执行多条 SQL 语句
  179. function muti_query($query)
  180. {
  181. $sq = explode(";\n",$query);
  182. foreach($sq as $s){
  183. if(trim($s)!= '')$this->query($s);
  184. }
  185. }
  186. }
  187. // 模块类,封装了通用CURD模块操作,建议所有模块都继承此类。
  188. class m {
  189. var $db;
  190. var $table;
  191. var $fields;
  192. var $key;
  193. function __construct()
  194. {
  195. global $db;
  196. $this->db = $db;
  197. $this->key = 'id';
  198. }
  199. public function __call($name, $arg) {
  200. return call_user_func_array(array($this, $name), $arg);
  201. }
  202. // 向数据库插入数组格式数据
  203. function add($elem = FALSE)
  204. {
  205. $query_list = array();
  206. if(!$elem)$elem = $_POST;
  207. foreach($this->fields as $f) {
  208. if(isset($elem[$f])){
  209. $elem[$f] = addslashes($elem[$f]);
  210. $query_list[] = "`$f` = '$elem[$f]'";
  211. }
  212. }
  213. $this->db->query("insert into `$this->table` set ".implode(',',$query_list));
  214. return $this->db->insert_id();
  215. }
  216. // 删除某一条数据
  217. function del($id)
  218. {
  219. $this->db->query("delete from `$this->table` where ".$this->key."='$id'");
  220. }
  221. // 更新数据
  222. function update($id , $elem = FALSE)
  223. {
  224. $query_list = array();
  225. if(!$elem)$elem = $_POST;
  226. foreach($this->fields as $f) {
  227. if(isset($elem[$f])){
  228. $elem[$f] = addslashes($elem[$f]);
  229. $query_list[] = "`$f` = '$elem[$f]'";
  230. }
  231. }
  232. $this->db->query("update `$this->table` set ".implode(',',$query_list)." where ".$this->key." ='$id'" );
  233. }
  234. // 统计数量
  235. function count($where='')
  236. {
  237. $res = $this->db->query("select count(*) as a from `$this->table` where 1 $where");
  238. return $res[0]['a'];
  239. }
  240. /* get($id) 取得一条数据 或
  241. * get($postquery = '',$cur = 1,$psize = 30) 取得多条数据
  242. */
  243. function get()
  244. {
  245. $args = func_get_args();
  246. if(is_numeric($args[0])) return $this->__call('get_one', $args);
  247. return $this->__call('get_many', $args);
  248. }
  249. function get_one($id)
  250. {
  251. $id = is_numeric($id)?$id:0;
  252. $res = $this->db->query("select * from `$this->table` where ".$this->key."='$id'");
  253. if(isset($res[0]))return $res[0];
  254. return false;
  255. }
  256. function get_many($postquery = '',$cur = 1,$psize = 30)
  257. {
  258. $cur = $cur > 0 ?$cur:1;
  259. $start = ($cur - 1) * $psize;
  260. $query = "select * from `$this->table` where 1 $postquery limit $start , $psize";
  261. return $this->db->query($query);
  262. }
  263. }
复制代码
  1. // 所有配置内容都可以在这个文件维护
  2. error_reporting(E_ERROR);
  3. if(file_exists(APP.'config_user.php')) require(APP.'config_user.php');
  4. // 配置url路由
  5. $route_config = array(
  6. '/reg/'=>'/user/reg/',
  7. '/logout/'=>'/user/logout/',
  8. );
  9. define('BASE','/');
  10. /* 数据库默认按照 SAE 进行配置 */
  11. $db_config = array(
  12. 'host'=>SAE_MYSQL_HOST_M.':'.SAE_MYSQL_PORT,
  13. 'user'=>SAE_MYSQL_USER,
  14. 'password'=>SAE_MYSQL_PASS,
  15. 'default_db'=>SAE_MYSQL_DB
  16. );
复制代码


声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
高流量网站的PHP性能调整高流量网站的PHP性能调整May 14, 2025 am 12:13 AM

TheSecretTokeEpingAphp-PowerEdwebSiterUnningSmoothlyShyunderHeavyLoadInVolvOLVOLVOLDEVERSALKEYSTRATICES:1)emplactopCodeCachingWithOpcachingWithOpCacheToreCescriptexecution Time,2)使用atabasequercachingCachingCachingWithRedataBasEndataBaseLeSendataBaseLoad,3)

PHP中的依赖注入:初学者的代码示例PHP中的依赖注入:初学者的代码示例May 14, 2025 am 12:08 AM

你应该关心DependencyInjection(DI),因为它能让你的代码更清晰、更易维护。1)DI通过解耦类,使其更模块化,2)提高了测试的便捷性和代码的灵活性,3)使用DI容器可以管理复杂的依赖关系,但要注意性能影响和循环依赖问题,4)最佳实践是依赖于抽象接口,实现松散耦合。

PHP性能:是否可以优化应用程序?PHP性能:是否可以优化应用程序?May 14, 2025 am 12:04 AM

是的,优化papplicationispossibleandessential.1)empartcachingingcachingusedapcutorediucedsatabaseload.2)优化的atabaseswithexing,高效Quereteries,and ConconnectionPooling.3)EnhanceCodeWithBuilt-unctions,避免使用,避免使用ingglobalalairaiables,并避免使用

PHP性能优化:最终指南PHP性能优化:最终指南May 14, 2025 am 12:02 AM

theKeyStrategiestosiminificallyBoostphpapplicationPermenCeare:1)useOpCodeCachingLikeLikeLikeLikeLikeCacheToreDuceExecutiontime,2)优化AtabaseInteractionswithPreparedStateTemtStatementStatementSandProperIndexing,3)配置

PHP依赖注入容器:快速启动PHP依赖注入容器:快速启动May 13, 2025 am 12:11 AM

aphpdepentioncontiveContainerIsatoolThatManagesClassDeptions,增强codemodocultion,可验证性和Maintainability.itactsasaceCentralHubForeatingingIndections,因此reducingTightCightTightCoupOulplingIndeSingantInting。

PHP中的依赖注入与服务定位器PHP中的依赖注入与服务定位器May 13, 2025 am 12:10 AM

选择DependencyInjection(DI)用于大型应用,ServiceLocator适合小型项目或原型。1)DI通过构造函数注入依赖,提高代码的测试性和模块化。2)ServiceLocator通过中心注册获取服务,方便但可能导致代码耦合度增加。

PHP性能优化策略。PHP性能优化策略。May 13, 2025 am 12:06 AM

phpapplicationscanbeoptimizedForsPeedAndeffificeby:1)启用cacheInphp.ini,2)使用preparedStatatementSwithPdoforDatabasequesies,3)3)替换loopswitharray_filtaray_filteraray_maparray_mapfordataprocrocessing,4)conformentnginxasaseproxy,5)

PHP电子邮件验证:确保正确发送电子邮件PHP电子邮件验证:确保正确发送电子邮件May 13, 2025 am 12:06 AM

phpemailvalidation invoLvesthreesteps:1)格式化进行regulareXpressecthemailFormat; 2)dnsvalidationtoshethedomainhasavalidmxrecord; 3)

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)