用 Composer构建自己的 PHP 框架之设计 MVC


Posted in PHP onOctober 30, 2014

回顾

在上一篇教程中,我们使用 codingbean/macaw 这个 Composer 包构建了两条简单路由,第一条是响应 GET ‘/fuck' 的,另一条会 hold 住所有请求。其实对 PHP 框架来说,有了路由就有了一切。所以接下来我们要做的事情就是让 MFFC 框架更加规范,更加丰满。

这就牵扯到了 PHP 框架另外的价值:确立开发规范以便于`多人协作`,使用 ORM`、`模板引擎 等工具以`提高开发效率`。

正式开始规划文件夹

新建 MFFC/app 文件夹,在 app 中创建 controllers、models、views 三个文件夹,开始正式开始踏上 MVC 的征程。

(谁说我抄 Laravel 了,我抄的明明是 Rails :-D)

使用命名空间

新建 controllers/BaseController.php 文件:

<?php
/**
* BaseController
*/
class BaseController
{
  
  public function __construct()
  {
  }
}

新建 controllers/HomeController.php 文件:

<?php
/**
* \HomeController
*/
class HomeController extends BaseController
{
  
  public function home()
  {
    echo "<h1>控制器成功!</h1>";
  }
}

增加一条路由: Macaw::get('', 'HomeController@home');`,打开浏览器直接访问 http://127.0.0.1:81/`,出现以下提示:

Fatal error: Class 'HomeController' not found in /Library/WebServer/Documents/wwwroot/MFFC/vendor/codingbean/macaw/Macaw.php on line 93

为什么没找到 HomeController 类?因为我们没有让他自动加载,修改 composer.json 为:

{
  "require": {
    "codingbean/macaw": "dev-master"
  },
  "autoload": {
    "classmap": [
      "app/controllers",
      "app/models"
    ]
  }
}

运行 composer dump-autoload`,稍等片刻,刷新,你将看到以下内容(别忘了调节编码哦~):

用 Composer构建自己的 PHP 框架之设计 MVC

恭喜你,命名空间使用成功!

连接数据库

新建 models/Article.php 文件,内容为(数据库密码请自行更改):

<?php
/**
* Article Model
*/
class Article
{
  public static function first()
  {
    $connection = mysql_connect("localhost","root","password");
    if (!$connection) {
      die('Could not connect: ' . mysql_error());
    }
    mysql_set_charset("UTF8", $connection);
    mysql_select_db("mffc", $connection);
    $result = mysql_query("SELECT * FROM articles limit 0,1");
    if ($row = mysql_fetch_array($result)) {
      echo '<h1>'.$row["title"].'</h1>';
      echo '<p>'.$row["content"].'</p>';
    }
    mysql_close($connection);
  }
}

修改 controllers/HomeController.php 文件:

<?php/*** \HomeController*/class HomeController extends BaseController{  public function home() {  Article::first(); }}

刷新,这时候会得到 Article 类未找到的信息,因为我们没有更新自动加载配置:

composer dump-autoload

在等待的时间里,我们去建立数据库 mffc`,在里面建立表 articles`,设计两个字段 title`、`content 用于记录信息,并填充进至少一条数据。你也可以在建立完成 mffc 数据库以后运行以下 SQL 语句:

DROP TABLE IF EXISTS `articles`;
CREATE TABLE `articles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `content` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `articles` WRITE;
/*!40000 ALTER TABLE `articles` DISABLE KEYS */;
INSERT INTO `articles` (`id`, `title`, `content`)
VALUES
 (1,'我是标题','<h3>我是内容呀~~</h3><p>我真的是内容,不信算了,哼~ O(∩_∩)O</p>'),
 (2,'我是标题','<h3>我是内容呀~~</h3><p>我真的是内容,不信算了,哼~ O(∩_∩)O</p>');
/*!40000 ALTER TABLE `articles` ENABLE KEYS */;
UNLOCK TABLES;

然后,刷新!你将看到以下页面:

用 Composer构建自己的 PHP 框架之设计 MVC

恭喜你!MVC 中的 M 和 C 都已经实现!接下来我们开始调用 V (视图)。

调用视图

修改 models/Article.php 为:

<?php
/**
* Article Model
*/
class Article
{
  public static function first()
  {
    $connection = mysql_connect("localhost","root","C4F075C4");
    if (!$connection) {
      die('Could not connect: ' . mysql_error());
    }
    mysql_set_charset("UTF8", $connection);
    mysql_select_db("mffc", $connection);
    $result = mysql_query("SELECT * FROM articles limit 0,1");
    if ($row = mysql_fetch_array($result)) {
      return $row;
    }
    mysql_close($connection);
  }
}

将包含查询结果的数组返回。修改 HomeController:

<?php
/**
* \HomeController
*/
class HomeController extends BaseController
{
  public function home()
  {
    $article = Article::first();
    require dirname(__FILE__).'/../views/home.php';
  }
}

保存,刷新,你将得到跟上面一模一样的页面,视图调用成功!

几乎所有人都是通过学习某个框架来了解 MVC 的,这样可能框架用的很熟,一旦离了框架一个简单的页面都写不了,更不要说自己设计 MVC 架构了,其实这里面也没有那么多门道,原理非常清晰,我说说我的感悟:

1. PHP 框架再牛逼,他也是 PHP,也要遵循 PHP 的运行原理和基本哲学。抓住这一点我们就能很容易地理解很多事情。

2. PHP 做的网站从逻辑上说,跟 php test.php 没有任何区别,都只是一段字符串作为参数传递给 PHP 解释器而已。无非就是复杂的网站会根据 URL 来调用需要运行的文件和代码,然后返回相应的结果。

3. 无论我们看到的是 CodeIgniter 这样 180 个文件`组成的“小框架”,还是 Laravel 这样`加上 vendor 一共 3700 多个文件`的 “大框架”,他们都会在每一个 URL 的驱动下,组装一段可以运行的字符串,传给 PHP 解释器,再把从 PHP 解释器返回的字符串传给访客的浏览器。

4. MVC 是一种逻辑架构,本质上是为了让人脑这样的超低 RAM 的计算机能够制造出远超人脑 RAM 的大型软件,其实 MVC 架构在 GUI 软件出现以前就已经成形,命令行输出也是视图嘛。

5. 在 MFFC 里,一个 URL 驱动框架做的事情基本是这样的:入口文件 require 控制器,控制器 require 模型,模型和数据库交互得到数据返回给控制器,控制器再 require 视图,把数据填充进视图,返回给访客,流程结束。

PHP 相关文章推荐
一个分页的论坛
Oct 09 PHP
php中json_encode处理gbk与gb2312中文乱码问题的解决方法
Jul 10 PHP
PHP查找与搜索数组元素方法总结
Jun 12 PHP
标准版Eclipse搭建PHP环境的详细步骤
Nov 18 PHP
yii2中添加验证码的实现方法
Jan 09 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
Apr 26 PHP
理解php依赖注入和控制反转
May 11 PHP
再谈PHP中单双引号的区别详解
Jun 12 PHP
php添加数据到xml文件的简单例子
Sep 08 PHP
Laravel重写用户登录简单示例
Oct 08 PHP
PHP 芝麻信用接入的注意事项
Dec 01 PHP
PHP cURL获取微信公众号access_token的实例
Apr 28 PHP
用 Composer构建自己的 PHP 框架之构建路由
Oct 30 #PHP
ThinkPHP做文字水印时提示call an undefined function exif_imagetype()解决方法
Oct 30 #PHP
用 Composer构建自己的 PHP 框架之基础准备
Oct 30 #PHP
thinkphp视图模型查询提示ERR: 1146:Table 'db.pr_order_view' doesn't exist的解决方法
Oct 30 #PHP
仿dedecms下拉分页样式修改的thinkphp分页类实例
Oct 30 #PHP
thinkphp中html:list标签传递多个参数实例
Oct 30 #PHP
如何让CI框架支持service层
Oct 29 #PHP
You might like
深入解析phpCB批量转换的代码示例
2013/06/27 PHP
thinkphp使用phpmailer发送邮件的方法
2014/11/24 PHP
Yii2框架dropDownList下拉菜单用法实例分析
2016/07/18 PHP
Laravel5权限管理方法详解
2016/07/26 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
2017/08/30 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
javascript高亮效果的二种实现方法
2008/09/14 Javascript
JS函数实现动态添加CSS样式表文件
2012/12/15 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
jQuery列表拖动排列具体实现
2013/11/04 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
jQuery函数的第二个参数获取指定上下文中的DOM元素
2014/05/19 Javascript
js获取当前日期时间及其它操作汇总
2015/04/17 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
深入理解jquery中的事件与动画
2016/05/24 Javascript
纯前端JavaScript实现Excel IO案例分享
2016/08/26 Javascript
解决微信内置浏览器返回上一页强制刷新问题方法
2017/02/05 Javascript
bootstrap栅格系统示例代码分享
2017/05/22 Javascript
JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍
2018/03/01 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
2018/04/14 Javascript
vue打包相关细节整理(小结)
2018/09/28 Javascript
Vue 自定义指令实现一键 Copy功能
2019/09/16 Javascript
Auto.JS实现抖音刷宝等刷视频app,自动点赞,自动滑屏,自动切换视频功能
2020/05/08 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
Python使用百度API上传文件到百度网盘代码分享
2014/11/08 Python
python通过索引遍历列表的方法
2015/05/04 Python
Python读取网页内容的方法
2015/07/30 Python
TensorFlow搭建神经网络最佳实践
2018/03/09 Python
Python反转序列的方法实例分析
2018/03/21 Python
程序设计HTML5 Canvas API
2013/04/08 HTML / CSS
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
2016年国陪研修感言
2015/11/18 职场文书