Toper

怎么一步步编写简单的PHP的Framework(十六)

霸气de小男生 提交于 2020-04-24 14:14:08
今天回来的比较晚,本来准备用UML画一下模型这一块儿的关系,但是没有时间搞了,只有用PS搞了一个简单的事例。 我把模型分成了几块儿,A,B,C,D,E,F,这几块儿分别代表了什么呢? 首先A,这个Base代表的就是整个框架的基类,所有的模型文件都必须继承自这个基类; 由于B的内容需要依赖D,所以先说一下D,D首先有一个ConnectionManager,它负责管理数据库的连接和关闭还有数据库驱动的选择,这个命名自己感觉不太好,先就将就吧,既然它负责数据库的连接和关闭,肯定它就有以下方法: <?php public class ConnectionManager { public static function getConnection(){} public static function releaseConnection() {} } 由于数据库的连接对于所有模型来说都是共享的,所以我们把ConnnectionManager设置为单例。 D中右边有PDO,MYSQL_*,这代表什么意思呢,实际上就是代表各种驱动,有可能你使用的是比较先进的PDO,也有可能你使用的是比较老的MYSQL_*这种,也有可能你使用的是mysqli,ADO等等,正是由于PHP数据库这一块儿的混乱情况,我们需要在框架中定义一个契约,所有的驱动类按照这个契约编写实现,这样,不管驱动类的底层实现怎样

怎么一步步编写简单的PHP的Framework(七)

╄→гoц情女王★ 提交于 2020-04-15 19:37:50
【推荐阅读】微服务还能火多久?>>> 不好意思,最近几天事情有点多,所以更新比较慢。 之前我们在入口文件就直接调用了Route::run(),这样做有不有什么问题呢? 答案是有!! 有时候在进行路由之前和之后需要进行一些额外的处理,如果按照之前在入口文件直接调用Route::run()的话,那么这些处理过程只能写在入口文件中,但是入口文件本不应该做这样的事情,那么我们该怎么样来解决这个问题呢? 我们引入一个前端控制器的概念,它相当于一个总控,所有外部的请求都在它的控制范围内,那么这些额外的处理是不是就可以放在这个控制器中了呢!! 好,我们现在先修改一下入口文件: <?php defined('APP_PATH') || define('APP_PATH',dirname(__FILE__) . '/..'); defined('FRAMEWORK_PATH') || define('FRAMEWORK_PATH',APP_PATH . '/Library/Test'); defined('MODULES_PATH') || define('MODULES_PATH',APP_PATH . '/UserApps/Modules'); defined('CONFIGS_PATH') || define('CONFIGS_PATH',APP_PATH . '/UserApps

怎么一步步编写简单的PHP的Framework(二十)

最后都变了- 提交于 2020-03-15 21:06:12
上一次我把SqlParser这个类的主要结构讲了一下,这次我就将这个类的函数编写了。 按照上节课的内容,主要的函数有下面几个: private function _where($where){} private function _field($field) {} private function _distinct($distinct) {} private function _table($table) {} private function _order($order) {} private function _group($group) {} 首先我们说一下distinct函数,这个函数最终会返回字符串DISTINCT或者空串,我们可以想一下,这个函数传递的形参实际上是非常简单的,它只需要告诉框架我是否需要DISTINCT即可,所以在框架中只需做一个简单判定就好。 现假设用户传递的参数为true或字符串'distinct'的时候代表用户想使用'DISTINCT',那么这个函数的实现就变成了这样: private function _distinct($distinct) { return ((true === $distinct) || ('distinct' === $distinct)) ? 'DISTANCT' : ''; } 这里直接使用'distinct' ===

怎么一步步编写简单的PHP的Framework(三)

前提是你 提交于 2019-12-10 16:25:12
睡不着,继续写一篇吧!! 按照上一次我讲的内容,一个基本的MVC构架是已经搭建起来了的,但是本身还存在很多问题,如:模型这一块儿每次连接DB,关闭DB的代码冗余,视图这一块儿还是PHP代码,每个文件要使用很多include代码等等。 要编写一个框架,那么首先就要规定一个标准的目录结构,我们暂时把这个目录结构定死,不允许用户修改,这样可以减少代码量,方便大家看的更明白。 由于之前编写了Toper,所以我准备沿用Toper的目录结构来做演示: Library(框架存放目录) Test(假设这个框架名就叫test) UserApps (用户的APP存放目录) Configs(配置文件存放目录) Modules(模块存放目录) Controllers (所有控制器存放目录) Models (模型存放目录) Views (视图存放目录) Helpers (辅助文件目录) Plugins(插件存放目录,暂时用不上) Public (网站根目录) index.php (最重要的入口文件) 这个地方有点需要解释一下,Public目录才是网站的根目录,Library目录和UserApps目录是存放在网站根目录之外的,这样用户通过浏览器访问时就不能直接访问这个PHP文件,这样可以提高网站的安全性。   之前我们把路由的功能全部放在入口文件这一块儿,实际上这是不合适的,入口文件不应该做这些逻辑的处理

怎么一步步编写简单的PHP的Framework(八)

天涯浪子 提交于 2019-12-10 16:08:42
昨天我写到我们使用前端控制器来控制所有请求,今天我们继续这个话题。 既然前端控制器控制一切,那么我们可以用它来做更多的事情!! 我们知道,在windows里面默认php.ini中display_errors默认开启,而在linux中默认是关闭的,那么这样对于程序的调试时很麻烦的,所以我们可以在配置文件中设置一个debug属性,它代表是否调试打开,如果打开调试,程序出现任何异常,那么会输出很多调试信息。在这儿,我只是很简单的设置一下,真正的框架调试功能肯定不是这样简单的。 先我们实现如果debug开启,那么显示调试信息debug mode:这样一个字符串,并且如果程序有语法或其他错误,显示错误信息,如果调试关闭,那么任何错误信息都不显示。 现在修改FrontController的__construct函数: private function __construct() { C(Config::factory(Config::PHP)); //写入配置信息 session_start(); if(true === C('debug')) { echo 'debug mode:'; ini_set('display_errors','On'); error_reporting(C('errorReporting')); } else { error_reporting(0); ini

怎么一步步编写简单的PHP的Framework(六)

假装没事ソ 提交于 2019-12-10 16:08:32
不好意思,由于最近事情比较多,昨天的确没有时间写,今天刚好还有接近一个小时的时间,所以就继续写一篇。 不知道大家注意到没有,之前我们导入一个配置文件是通过include CONFIGS_PATH . '/config.php'来做的,这样做好吗? 不忙回答,我可以提两个问题: 1. 如果这个路径下面的config.php不存在会发生什么现象? 2.如果我将PHP这种配置文件修改成为xml这种配置文件之后会发生什么现象? 首先,如果文件不存在,那么PHP会抛出一个警告,但是程序继续执行;配置文件变成xml之后,入口文件处需要编写相应的读取xml的代码,而且需要把之前的include CONFIGS_PATH . '/config.php'这句代码修改掉。 那么有没有方法能够实现配置文件的无缝切换呢? 在具体讲解这些之前,我首先说一下工厂模式,现假设:A需要购买一辆红色汽车,他直接向B (一个生产汽车的工厂 )提出需求,B按照A的需求,从仓库中选取一辆合适的汽车,然后交给A。整个过程,A只是提出需求,具体汽车的选取是由B工厂来确定的,这种方式就是工厂模式。 举个例子: <?php public class Factory { public static function factory($whichOneToChoose) { $returnVal = 'Red'; switch(

怎么一步步编写简单的PHP的Framework(十三)

假装没事ソ 提交于 2019-12-07 17:08:58
上次讲到控制器怎么样将数据传递到视图,今天我就主要说一下在程序中怎么让代码更“安全”,之后就转到讲模型,再讲怎么做视图,最后再讲控制器的功能强化。 我再声明一下,我写这个文章只是让大家对PHP的框架编写有一个基本的了解,由于本人技术有限,这个文章是给PHP初学者学习的,所以高手勿喷,还有就是我现在时间也有限,所以每次可能需要两三天才能写一篇,每篇我写的时间也要控制在一个小时以内,由于边写这个文章边编代码,所以代码中可能会存在很多BUG,见谅!! 如果你是一个PHP爱好者,请在文章后面积极回复一下,这种交流不仅可以使我的PHP技术提高,也鼓励了我继续写下去的勇气,谢谢!! 很多人编写PHP代码什么都不注意,遇到很多警告,就直接通过error_reporting屏蔽掉,这样做我觉得问题是非常大的,比如: <?php $a = $_GET['a']; echo $a; 如果通过GET方式传递的参数有a,那么程序非常正常,但是如果没有传递呢,那就会抛出一个警告!! 我的作法是首先将error_reporting设置为E_STRICT,不允许程序出现警告!! 刚才这段代码可能就需要修改成: <?php $a = isset($_GET['a']) ? $_GET['a'] : ''; echo $a; 除了这种问题,还有就是PHP特有的 @符号 ,很多人都喜欢用这个来屏蔽错误

怎么一步步编写简单的PHP的Framework(十四)

喜你入骨 提交于 2019-12-07 03:40:35
今天我说一下怎么在框架中over掉这些安全问题。 首先是SQL注入,这个如果你使用的是PDO,我觉得应该没什么问题,如果你使用的还是mysql_*等API,那么你可以在框架中实现bindParameter或者在插入数据库之前进行字符串转义。 前两天把上一篇文章写完之后,Vian在后面留言说到过SQL注入的一个解决方案,就是在在插入DB之前进行 '''.addslashes($id).''',它的意思就是首先进行addslashes操作,之后再强制单引号包裹,这样它就是一个不折不扣的字符串了,所以就注入不了,我觉得这个方法不错,赞一个!! 由于SQL注入需要联系到模型,XSS需要联系到视图,这两块儿我都没有开始讲,所以我再后面再讲怎么在框架中解决,当然,如果我写到后面忘记了,你也可以提醒我一下。 上一次我讲CSRF的时候,并没有给出一个解决方案,今天我就给出这个解决方案。实际上解决的方法很简单,就是给它产生一个随机数,然后后端判定传递过来的数和正确的数是否吻合, 如果不吻合,就不执行相应的代码了,这个随机数我们称为token。 为了简单,我们就将产生token和得到token的函数都写在控制器中,即Controller.php。 首先是生成随机数,最简单的方式是使用mt_rand()直接产生一个整数,但在这儿我使用之前我在initphp这个框架中看到的解决csrf的方法,在这儿