位置: 编程技术 - 正文

搭建自己的PHP MVC框架详解(搭建自己的php mvc框架)

编辑:rootadmin

推荐整理分享搭建自己的PHP MVC框架详解(搭建自己的php mvc框架),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:搭建自己的ChatGPT,搭建自己的php框架,搭建自己的电子书库,搭建自己的ChatGPT,搭建自己的php框架,搭建自己的ChatGPT,搭建自己的网站,搭建自己的php框架,内容如对您有帮助,希望把文章链接给更多的朋友!

本文详细讲述了搭建自己的PHP MVC框架的方法。分享给大家供大家参考,具体如下:

前言

说到写PHP的MVC框架,大家想到的第一个词--“造轮子”,是的,一个还没有深厚功力的程序员,写出的PHP框架肯定不如那些出自大神们之手、经过时间和各种项目考验的框架。但我还是准备并且这么做了,主要是因为:

认为有关PHP的方方面面都了解了,但自己学习PHP的时间还短,基础并不扎实,很多常用函数的参数还偶尔要查手册,而且对于PHP的一些较新的特性如命名空间、反射等只是简单的看过,并没有能实际应用过。

PHP的知识多且杂,一个普通的项目往住是业务逻辑代码为主,而框架是一个能把这些知识点能融汇在一起的项目。

在自己写一个框架的时候,也会参考一些我使用过的框架如TP/CI/YII等的源码,在自己看源码时也能帮助自己理解框架,更容易接受以后要使用的框架。

所以说,这次造轮子的目的不是为了造轮子而是为了在造轮子的过程中熟悉其工艺,总结轮子特点,更好的使用轮子。

如果说写一个完整的PHP框架,那需要掌握的PHP知识点非常多,像设计模式、迭代器、事件与钩子等等,还有许多基础知识的灵活应用。我自认为这些还无法完全掌控,所以我的步骤是先自己搭建一个骨架,然后参考借鉴不同的PHP框架的特点,将其慢慢完善。因为工作原因,而且晚上还要补算法、网络等编程基础,PHP框架部分可能只有周末有时间更新,我会在进行框架功能更新之后,总结使用的知识点,更新博文。

首先放上框架的目前源码:GITHUB/zhenbianshu

或者点击此处本站下载。

框架整体

首先自己总结一下PHP的MVC框架的工作流程:

简单来说,它以一个入口文件来接受请求,选择路由,处理请求,返回结果。

当然,几句话总结完的东西实际上要做的工作很多,PHP框架会在每次接受请求时,定义常量,加载配置文件、基础类,根据访问的URL进行逻辑判断,选择对应的(模块)控制器和方法,并且自动加载对应类,处理完请求后,框架会选择并渲染对应的模板文件,以html页面的形式返回响应。在处理逻辑的时候,还要考虑到错误和异常的处理。

1、作为MVC框架,一定要有一个唯一的入口文件来统领全局,所有的访问请求都会首先进入这个入口文件,如我框架根目录的index.php,在里面,我定义了基本文件夹路径,当前环境,并根据当前环境定义错误报告的级别。

2、PHP中加载另外的文件,使用require和include,它们都是将目标文件内容加载到当前文件内,替换掉require或include语句,require是加载进来就执行,而include是加载进来在需要的时候执行,而它们的_once结构都是表示在写多次的时候只执行一次。

3、框架内的配置变量等使用专用的配置文件来保存,这里我仿照了TP里的数组返回法,用了一个compileConf()函数来解析数组,将数组的键定义为常量,值为数组的值。

命名空间和自动加载

为什么把命名空间和自动加载放到一块说呢?

在一个PHP项目中,类特别多的时候,如果类名重复的话就会造成混乱,而且相同文件夹内也不能存在同名的文件,所以这时候命名空间和文件夹就搭档出场了。文件夹就是一个一个的盒子,命名空间在我理解就像是一个标签,盒子对应标签。我们定义类时,把各种类用不同的盒子分别装好,并贴上对应的标签。而在自动加载类时,我们根据标签(命名空间)可以很轻易找到对应的盒子(文件夹)然后找到对应的类文件。

而类的自动加载,我们知道的__autoload()魔术函数,它会在你实例化一个当前路径找不到的对象时自动调用,根据传入的类名,在函数体内加载对应的类文件。

现在我们多用spl_autoload_register()函数,它可以注册多个函数来代替__autoload函数的功能,我们传入一个函数名为参数,spl_autoload_register会将这个函数压入栈中,在实例化一个当前路径内找不到的类时,系统将会将函数出栈依次调用,直到实例化成功。

现在Loader类还是一个简单的类,待以后慢慢完善。

路由选择

接下来就是路由选择了,其本质是根据当前定义的全局URL模式选择合适的方法来分析传入的URI,加载对应的类,并实现对应的方法。

这样,我在地址栏输入 zbs.com/index.php&#;r=index/login 后,系统会自动调用/app/Controller/Index.php下的login方法。完成了这么一个简单的路由。

阶段总结:

接下来我会优化现有的工具类,添加显示层,添加数据库类,还会将一些别的框架里非常cool的功能移植进来~

接上文(代码有所更新),继续完善框架(二):

对于本次更新,我想说:

① 本框架由本人挑时间完善,而我还不是PHP大神级的人物,所以框架漏洞难免,求大神们指出。② 本框架的知识点应用都会写在博客里,大家有什么异议的可以一起讨论,也希望看博客的也能学习到它们。③ 本次更新,更新了函数规范上的一些问题,如将函数尽量的独立化,每一个函数尽量只单独做好一件事情,尽量减少函数依赖。还对框架的整体优化了一下,添加了SQ全局类,用以处理全局函数,变量。

回调函数

替换了很low的类名拼装实例化,然后拼装方法名的用法,使用PHP的回调函数方式:

原代码:

修改后代码

这里介绍一下PHP的函数回调应用方式:call_user_func和call_user_func_array:

调用第一个参数所提供的用户自定义的函数。

返回值:返回调用函数的结果,或FALSE。

call_user_func_array()的用法跟call_user_func类似,只不过传入的参数params整体为一个数组。

另外,call_user_func系列函数还可以传入在第一个参数里传入匿名参数,可以很方便的回调某些事件,这些特性在复杂的框架里应用也十分广泛,如yii2的事件机制里回调函数的使用就是基于此。

VIEW层和ob函数

框架在controller的基类中定义了render方法来渲染页面,它会调用类VIEW的静态函数来分析加载对应页面的模板。

这里重点说一下ob(output buffering)系列函数,其作用引用简明代魔法的ob作用介绍:

① 防止在浏览器有输出之后再使用setcookie,或者header,session_start函数造成的错误。其实这样的用法少用为好,养成良好的代码习惯。② 捕捉对一些不可获取的函数的输出,比如phpinfo会输出一大堆的HTML,但是我们无法用一个变量例如$info=phpinfo();来捕捉,这时候ob就管用了。③ 对输出的内容进行处理,例如进行gzip压缩,例如进行简繁转换,例如进行一些字符串替换。④ 生成静态文件,其实就是捕捉整页的输出,然后存成文件,经常在生成HTML,或者整页缓存中使用。

它在ob_start()函数执行后,打开缓冲区,将后面的输出内容装进系统的缓冲区,ob_implicit_flush(0)函数来关闭绝对刷送(echo等),最后使用ob_get_clean()函数将缓冲区的内容取出来。

搭建自己的PHP MVC框架详解(搭建自己的php mvc框架)

类/index/key常量和全局类

TP里的/index/key等全局常量用着很方便,可以很简单的实现跳转等操作,而定义它的函数createUrl函数我又想重用,于是借鉴YII的全局类定义方法:

定义基类及详细方法(以后的全局方法会写在这里)

在启动文件中定义类并继承基类;

在全局内都可以直接使用SQ::createUrl()方法来创建URL了。这样,定义/index/key常量就很轻松了。

用单例模式定义数据库连接基类

使用单例模式的核心是:

① 私有化构造函数,使无法用new来创建对象,也防止子类继承它并改写其构造函数;② 用静态变量存放当前对象,定义静态方法来返回对象,如对象还未实例化,实例化一个,存入静态变量并返回。③ 构造其__clone魔术方法,防止clone出一个新的对象;

DB类的sql查询函数

DB查询函数是一个很复杂的部分,它是一个自成体系的东西,像TP和YII的查询方法都有其独特的地方。我这里暂时先借用TP的MODEL基类,有时间再慢慢补这个。

嗯,介绍一下像TP的查询里的方法联查的实现,其诀窍在于,在每个联查方法的最后都用 return this 来返回已处理过的查询对象。

阶段总结:

yii2里的数据表和model类属性之间的映射很酷(虽然被深坑过), 前面一直避开的模块(module,我可以想像得到把它也添加到URI时解析的麻烦)有时间考虑一下。

接上文,继续完善框架(三)

本次更新的主要内容有:

① 介绍了异常处理机制② 完善了异常和错误处理③ 数据表跟Model类的映射

异常处理

异常处理:异常处理是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)

异常处理用于处理程序中的异常状况,虽说是“异常状态”,但仍然还是在程序编写人员的预料之中,其实程序的异常处理完全可以用‘if else'语句来代替,但异常处理自然有其优势之处。

个人总结其优点如下:

① 可以快速终止流程,重置系统状态,清理变量和内存占用,在普通WEB应用中,一次请求结束后,FAST CGI会自动清理变量和上下文,但如果在PHP的命令行模式执行守护脚本时,它的效果就会很方便了。

② 大量的if else语句会使代码变得繁杂难懂,使用异常处理可以使程序逻辑更清晰易懂,毕竟处理异常的入口只有catch语句一处。

③ 一量程序中的函数出现异常结果或状况,如果使用函数的return方式返回异常信息,层层向上,每一次都要进行return判断。使用异常处理我们可以假设所有的返回信息都是正常的,避免了大量的代码重复。

虽然将代码放在try catch块中会有微微的效率差,但是跟这些优点一比,这点消耗就不算什么了。那么PHP的异常处理怎么使用呢?

PHP内置有Exception类,使得我们可以通过实例化异常类来抛出异常。我们将代码放在try语句中执行,并在其后用catch试图捕捉到在try代码块中抛出的异常,并对异常进行处理。我们还可以在catch代码段后使用finally语句块,无论是否有异常都会执行finally代码块的代码,try catch语句形如下面代码:

使用try catch语句,需要注意:

① 当我们抛出异常时,会实例化一个异常类,此异常类可以自己定义,但在catch语句中,我们需要规定要捕获的异常对象的类名,并且只能捕获到特定类的异常对象,当然我们可以在最后捕获一个异常基类(PHP内置异常类)来确保异常一定能被捕获。

② 在抛出异常时,程序会被终止,并回溯代码找到第一个能捕获到它的catch语句,try catch语句是可以嵌套的,并且如上面代码所示 cacth语句是可以多次定义的。

③ finally块会在try catch块结束后执行,即使在try catch块中使用return返回,程序没有执行到最后。

框架里的异常处理

说了那么多异常相关(当然解释这些也是为了能理解和使用框架),那么框架里要怎么实现呢?

重写异常类

我们可以重写异常类,完善其内部方法:

如上,final方法是不可以重写的,除此之外,我们可以定义自己的方法,如记录异常日志,像我自定义的log方法,在catch代码块中,就可以直接使用$e->log来记录一个异常日志了。

注册全局异常方法

我们可以使用set_exception_handler('exceptionHandler')来全局捕获没有被catch块捕获到的异常,此异常处理函数需要传入一个异常处理对象,这样可以分析此异常处理信息,避免系统出现不人性化的提示,增强框架的健壮性。

其他全局函数

顺便再说一下其他的全局处理函数:

① set_shutdown_function('shutDownHandler')来执行脚本结束时的函数,此函数即使是在ERROR结束后,也会自动调用。

② set_error_handler('errorHandler')在PHP发生错误时自动调用,注意,必须在已注册错误函数后才发出的错误才会调用。函数参数形式应为($errno, $errstr, $errfile, $errline);

但是要注意这些全局函数需要在代码段的前面已经定义过再注册。

数据表和Model类的ActiveRecord映射

初次使用yii2的ActivceRecord类觉得好方便,只需要定义其字段同名属性再调用save方法就OK了(好神奇啊),它是怎么实现的呢,看了下源码,明白了其大致实现过程(基类)。

1. 使用‘describe table_name' 查询语句;2. 分析查询结果:对每一个字段,有Field(字段名)、Type(数据类型)、Null(是否为空)、Key(索引信息,‘PRI'表示为主键)、Default(默认值)、Extra(附加信息,如auto_increment)3. 通过判断其主键($row['KEY'] == 'PRI')信息,保存时看是否有主键信息,若存在,则为更新;不存在,则插入。4. 另外,解析出来的字段信息还有更多妙用~~

更多关于php框架相关内容感兴趣的读者可查看本站专题:《php优秀开发框架总结》、《codeigniter入门教程》、《ThinkPHP入门教程》、《Zend FrameWork框架入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

PHP回调函数与匿名函数实例详解 本文实例讲述了PHP回调函数与匿名函数。分享给大家供大家参考,具体如下:回调函数和匿名函数回调函数、闭包在JS中并不陌生,JS使用它可以完成事

PHP数据库编程之MySQL优化策略概述 本文简单讲述了PHP数据库编程之MySQL优化策略。分享给大家供大家参考,具体如下:前些天看到一篇文章说到PHP的瓶颈很多情况下不在PHP自身,而在于数

PHP数据库操作二:memcache用法分析 本文实例讲述了PHP数据库操作之memcache用法。分享给大家供大家参考,具体如下:在一个高并发的web应用中,数据库存取瓶颈一直是个大问题,一旦达到

标签: 搭建自己的php mvc框架

本文链接地址:https://www.jiuchutong.com/biancheng/287502.html 转载请保留说明!

上一篇:PHP高精确度运算BC函数库实例详解(php精度丢失)

下一篇:PHP回调函数与匿名函数实例详解(php 函数返回值)

  • 增值税普通发票怎么开
  • 个税手续费返还交增值税,但是6%的那行是灰色的
  • 实收资本增加印花税怎么算
  • 税金及附加怎么来的
  • 车辆保险费印花税目
  • 金税四期有什么优势
  • 累计折旧影响所得税费用吗
  • 小规模纳税人生活服务业免征增值税
  • 一般纳税人加计抵减申报表怎么填
  • 退回以前年度工资怎么做账
  • 研究开发费用的加计扣除100%
  • 银行汇票使用流程举例
  • 工资一直挂账未发可以吗
  • 公司缴纳个人所得税会计分录
  • 领用包装物会计处理
  • 物业公司收取的电费怎么确认收入
  • 分公司的人员构成
  • 员工基本养老保险缴纳比例
  • 金税盘与税控盘及报税盘怎么区分
  • 美国边境管理体制
  • 关于税前扣除的规定
  • 变相处理问题什么意思
  • 管理费用研发费用科目设置
  • 开票金额开多了,对公司有影响吗
  • 购买债券发生的交易费用计入哪个科目
  • 外籍人士离职补偿
  • 集团公司收取管理费是否可以税前列支
  • 什么叫资金预算
  • php7 数组
  • php数组函数输出《咏雪》里有多少"片"字
  • 贸易公司出口退税政策最新
  • 玩游戏的显示器要高刷还是高分辨率
  • 电脑刷新率怎么调低
  • 商铺转让权是什么意思
  • 凯恩kane
  • 后端怎么把图片传给前端的
  • php traits
  • javascript动画教程
  • 印花税不足一元需要缴纳吗
  • opencv图像处理入门与实践pdf
  • 详解Yii2 rules 的验证规则
  • 长期待摊费用为负数怎么调整
  • 企业所得税的计算公式三种
  • 小企业会计准则和企业会计准则的区别
  • 发票抵扣联和发票联区别
  • 农产品核定进项
  • mysql性能提升
  • 小规模纳税人起征点变化历程
  • 公司不交工会经费有什么后果?工会经费交费时自愿的么?
  • 怎么修改申报数据
  • 员工食堂买菜账务流程
  • 提供加工修理修配劳务包含哪些
  • 企业将重组债务转为资本的会计处理
  • sql server存储过程写法
  • 在建工程账务怎么会转到预收账款
  • 支付宝和微信的财务统计
  • 固定资产报废怎么开票
  • 每个月房租
  • 购买汽车后,需要缴纳的税种有哪些
  • 应付账款是已经付了还是没付
  • mysql 元组
  • 苹果电脑安全性
  • 无人值守安装操作系统
  • linux中的ls命令的功能是变换工作目录到目标指定目录
  • ghost过的硬盘能恢复吗
  • macbookpro中的文本编辑
  • 进程rundll32文件很多
  • yum update upgrade
  • windows7准备配置windows
  • linux将文本写入文件
  • win7筛选键
  • linux怎么配置raid
  • perl 计算
  • npm安装插件失败
  • js闭包作用问题解决应用
  • 安卓 存储权限 访问的地方是哪里
  • 广东省深圳市税占27%,高新技术占15%,各市分别占多少?
  • 软件即征即退软件是什么
  • 一季度土地市场
  • 缴纳了车辆购置税能退吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设