自己写了个框架,取名为“PrimusPHP”,就3个文件夹,log中是日志文件,会自动生成。

app中就是控制器和视图,public中是入口文件和静态资源,library中既有框架的核心类,还有工具类,数据操作类等。

这个框架会用到命名空间,PHP版本如果不能用命名空间,将不能执行。

一、单一入口

“index.php”就是入口文件,“defined.php”设置一些通用常量,例如绝对目录,并且引入了初始化库。

define('ROOT', dirname(dirname(__FILE__)));
define('DS', DIRECTORY_SEPARATOR); require_once LIB_PATH . DS . 'init.php';

“index.php”就是在执行初始化方法。

require_once '../defined.php';
define('APP_NAME', 'weixin');
define('CONFIG_PATH', APP_PATH . DS . APP_NAME . DS . 'conf'); InitPrimus::getInstance();

二、初始化

private function __construct() {
$this->environment();//环境配置
$this->reporting();//错误报告
self::loadFunction(self::$config['autoload']['helper']);//加载辅助函数
$this->_autoload();//自动载入
self::openLog(); //开启log
self::loadClass('\library\core\Router');//路由
}

1)环境配置

通常会有三个配置环境,本地、测试和正式。

以前曾经把三个环境的参数写在一个文件中,然后版本控制的时候忽略文件,这样做很不方便。

尤其是在发布版本的时候,如果要变里面的参数,还得记得在哪里改。

现在直接分三个文件,各自管各自的,谁也影响不到谁。

“library”中有三个配置文件,在“app”中也放在“conf”方便自行控制。

 

如何判断当前环境是本地、测试还是正式环境呢?

这里我将这个变量埋在了“.htaccess”中,如果是nginx,也可以配置。

RewriteEngine on
SetEnv ENVIRONMENT local

2)错误报告

错误提示在调试的时候很有用,能定位到具体的行数,能提高修正效率。

在网上搜索了一下,找到了一些代码,再借鉴了CI的错误代码,嫁接到这个框架里。

set_error_handler('exception_error_handler');//追踪错误栈
register_shutdown_function('catch_fatal_error');//致命错误

“exception_error_handler”和“catch_fatal_error”是两个函数,写在了“core/Common.php”中。

在“library/view”中预留了三种错误的模版页面。

在URL中输入“index/sign”错误的样子如下:

3)加载辅助函数

框架中,经常会有一些函数或类,在一开始就被载入进来,这里的这个辅助函数就是这个道理。

在配置文件中预先写好要载入的文件名。

public static function loadFunction($name) {
if(is_array($name)) {
foreach ($name as $key) {
include_once HELPER_LIB_PATH . DS . $key . '_helper.php';
}
}else {
include_once HELPER_LIB_PATH . DS . $name . '_helper.php';
}
}

4)自动载入

当“new \library\xx()”某个类的时候,会自动进入到“spl_autoload_register”函数中。

在回调函数中将“\library\xx”修改为具体路径,在“include_once”进来,就初始化好了。

private function _autoload() {
//$className是通过命名空间获取的
spl_autoload_register(function ($className) {
$dir = false;
$classNames = explode('\\', $className);//分割为数组
$autoDirs = self::$autoDirs;
foreach ($autoDirs as $path) {
$tmpInfo = pathinfo($path);
if(in_array($tmpInfo['basename'], $classNames)) {
$dir = $tmpInfo['dirname'];
break;
}
} if($dir) {
$file = $dir . DS . dir_replace_ds($className) . '.php';
include_once($file);
}
});
}

5)日志

平时开发的时候,我喜欢将查询语句直接打印到日志中,当将代码放到线上了,也能调试各个语句的结果。

最近在做微信开发,有很多请求微信的服务器,这些请求的结果只能通过打印日志看到。

日志的类放在了“util/Log.php”中。

public function write($txt) {
if(empty($txt) || !DEVELOPMENT_ENVIRONMENT) {
return;
}
$name = date('Y-m-d') . '.log';
if(!file_exists(LOG_PATH)) {
mkdir(LOG_PATH, 0777, true);
}
$path = LOG_PATH . DS . $name;
$content = date('Y-m-d H:i:s') . ' ' . $txt . "\n";
file_put_contents($path, $content, FILE_APPEND);
}

三、路由

1)路由选择

路由支持两种,一种就是“index/index”,另外一种是“v1/index/index”。

第二种可以用于客户端接口,当客户端更新版本的时候,可能就需要新的接口,而老的接口又不能丢,就可以新开一个模块文件夹。

$params = explode('/', $uri);
if(count($params) == 2) {
$controller = $params[0];//控制器
$action = $params[1];//操作方法
}elseif(count($params) == 3) {
$module = $params[0]; //模块
$controller = $params[1];//控制器
$action = $params[2];//操作方法
}else {
$controller = 'index';
$action = 'index';
}

2)路由重定向

以前没注意到重定向,最近在做微信开发的配置文件的时候就发现这个功能。

访问“bridge.js”其实是访问了某个控制器的“action”,怪不得我在想那些微信token都是通过服务器获取的,这个js文件是怎么搞到的。

重定向规则可以用正则表达式。

$init_conf['rewrite'] = array(
'/new_bridge.js/' => 'index/config',
'/new_bridge2.js/' => 'index/config2',
'/p\/(\d+)/' => 'index/ticket?p=$1'
);

下面是正则匹配:

public function rewrite() {
$config = \InitPrimus::getConfig('rewrite');
foreach ($config as $src => $redirect) {
//$pattern = '@^\/?' . $src . '\/?$@';
if (\preg_match($src, $this->uri)) {
$this->uri = \preg_replace($src, $redirect, $this->uri);
break;
}
}
}

框架地址:

https://github.com/pwstrick/PrimusPHP

制作自己的MVC框架(二)——启动的更多相关文章

  1. 制作自己的MVC框架(一)——简单粗暴的实现

    现在市面上有很多成熟的MVC框架,可以拿来直接用,但自己造一下轮子其实也挺有意思的. 下面先来看个最简单粗暴的MVC实现. 5个文件就能实现最简单的MVC,在Apache中设置一个虚拟目录,配置个简单 ...

  2. dya49:django:wsgrief&模板渲染Jinjia2&django的MTV/MVC框架&创建/启动一个django项目

    目录 1.自定义web框架wsgiref版 2.自定义web框架wsgiref版-优化版 3.模板渲染JinJa2 4.MTV和MVC框架 5.django:下载安装&创建启动 自定义web框 ...

  3. 制作自己的MVC框架(三)——应用

    一.数据库操作 目前封装了两种数据库,“MongoDB”和“MySQL”,用到了一次接口“IDatabase.php”. namespace library\db; interface IDataba ...

  4. IceMx.Mvc 我的js MVC 框架 二、视图的数据绑定

    介绍 本人菜鸟,一些自己的浅薄见解,望各位大神指正. 本框架有以下优点 1.简单(调用简单.实现简单.不过度设计) 2.视图.控制器.模型分离(分离对于维护十分有必要) 3.组件化(每一个mvc模块儿 ...

  5. 自定义MVC框架(二) -基于XML文件

    1.oracle的脚本 create table STUDENT ( sid NUMBER primary key, sname ), age NUMBER, pwd ) ) create seque ...

  6. 封装:简要介绍自定义开发基于WPF的MVC框架

    原文:封装:简要介绍自定义开发基于WPF的MVC框架 一.目的:在使用Asp.net Core时,深感MVC框架作为页面跳转数据处理的方便,但WPF中似乎没有现成的MVC框架,由此自定义开发一套MVC ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  8. 手写MVC框架(二)-代码实现和使用示例

    --------上一篇:手写MVC框架(一)-再出发----- 背景 书接上文,之前整理了实现MVC框架需要写哪些东西.这周粗看了一下,感觉也没多少工作量,所以就计划一天时间来完成.周末的时间,哪会那 ...

  9. 手写Spring MVC框架(二) 实现访问拦截功能

    前言 在上一篇文章中,我们手写了一个简单的mvc框架,今天我们要实现的功能点是:在Spring MVC框架基础上实现访问拦截功能. 先梳理一下需要实现的功能点: 搭建好Spring MVC基本框架: ...

随机推荐

  1. 使用Monit监控本地进程

    目前用它监控某些服务,失败自动重启,同时监控特定的日志文件,如果有变化,就发邮件报警 安装不细写了,网上好多 我先用cat /proc/version看了下我的系统是el6的,于是wget http: ...

  2. 理解CSS边框border

    前面的话   边框是CSS盒模型属性中默默无闻的一个普通属性,CSS3的到来,但得边框属性重新焕发了光彩.本文将详细介绍CSS边框 基础样式   边框是一条以空格分隔的集合样式,包括边框粗细(边框宽度 ...

  3. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  4. 为.NET Core项目定义Item Template

    作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Template和Item Template就是一个非常 ...

  5. C#多线程之线程池篇2

    在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我 ...

  6. .Net 大型分布式基础服务架构横向演变概述

    一. 业务背景 构建具备高可用,高扩展性,高性能,能承载高并发,大流量的分布式电子商务平台,支持用户,订单,采购,物流,配送,财务等多个项目的协作,便于后续运营报表,分析,便于运维及监控. 二. 基础 ...

  7. [C#] C# 知识回顾 - 异常介绍

    异常介绍 我们平时在写程序时,无意中(或技术不够),而导致程序运行时出现意外(或异常),对于这个问题, C# 有专门的异常处理程序. 异常处理所涉及到的关键字有 try.catch 和 finally ...

  8. CSS 3学习——文本效果和@font-face

    文本效果 关于文本效果,这里仅仅记录得到大多数浏览器支持的几个属性,分别是: text-overflow text-shadow word-break word-wrap text-overflow ...

  9. System.Guid ToString五中格式

    参考:https://msdn.microsoft.com/en-us/library/97af8hh4.aspx 测试代码: using System; using System.Collectio ...

  10. ASP.NET中常用的优化性能的方法

    1. 数据库访问性能优化 数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源.ASP.NET中提供了连接池( ...