文档章节

一步步编写简单的PHP的Framework(五)

NateHuang
 NateHuang
发布于 2016/07/28 20:00
字数 1248
阅读 2
收藏 0

 上一次我讲到使用自动导入可以实现一个类的延迟加载,这一次我想讲一下配置文件。

       不知道大家注意了没有,前几篇文章我都没有涉及到配置文件,可是在一个项目中,配置文件又是比不可少的。

       现在假设将Route.php中的默认控制器和Action变为可配置的,怎么弄呢?

       我们使用最简单的方式:

 

<?php
 $defaultController = 'Index';
 $defaultAction = 'index';

 

      然后在Route.php中include这个文件:

 

<?php
include APP_PATH . '/config.php';
$controller = empty($_GET['c']) ? $defaultController : trim($_GET['c']); //设置了默认的控制器
$action = empty($_GET['a']) ? $defaultAction : trim($_GET['a']); //设置了默认的Action

当然也可以使用这种方式:

 

 

<?php
return array(
       'defaultController' => 'Index',
       'defaultAction' => 'index'
);

     还是在Route.php中include:

 

 

<?php
$config = include APP_PATH . '/config.php';
$controller = empty($_GET['c']) ? $config['defaultController'] : trim($_GET['c']); //设置了默认的控制器
$action = empty($_GET['a']) ? $config['defaultAction'] : trim($_GET['a']); //设置了默认的Action

 

      但是由于配置文件很有可能在整个框架运行过程的各个类都有用到,而前两种方式都只能在某一个类里面的某一个方法中使用,怎么让它在各个类都可以使用呢?

      我们可以可以使用一个static方法来解决,比如专门定义一个Config类来存放配置信息,Config::get来读取配置信息,Config::set来设置配置信息,具体做法读者可以自己去尝试一下。

      当然我不准备采用这种方式,可能当时我看Thinkphp源码的时候被它优雅的特殊函数C迷住了吧,后面我在写Toper的时候也使用了一些特殊的函数,而C主要是负责设置和读取配置信息,个人观点,面向对象是必要的,但是不是什么都要面向对象,所以我准备定义一个function.php来存放一些公有的函数,我把它称为公有函数库。

      由于有了公有函数库,我们可以将上一篇里面的自动导入(__autoload)也转移到这个文件中,因为在Route.php出现一段__autoload的代码还是挺诡异的!!

      好了,怎么实现刚才我们说的通过一个函数来实现配置信息的设置和读取呢?

      好了,先展示我在Toper中的实现吧:

      

function C($name = null,$val = null) {
	static $_config = array();
	if(empty($name)) {
		return $_config;
	} elseif(is_string($name)) {
		if(empty($val)) {
			if(!strpos($name,'=>')) {
				//一维
				return isset($_config[$name]) ? $_config[$name] : null;
			} else {
				//目前只支持二维
				$name = explode('=>',$name);
				return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : null;
			}
		} else {
			if(!strpos($name,'=>')) {
				//直接设置
				$_config[$name] = $val;
			} else {
				//设置二维
				$name = explode('=>',$name);
				$_config[$name[0]][$name[1]] = $val;
			}
		}
	} elseif(is_array($name)) {
		foreach($name as $key=>$value) {
			$_config[$key] = $value;
		}
		return ;
	} else {
		throw new Exception('参数类型出错');
		return ;
	}
}

 

         看着代码挺长的,实际上原理很简单,如果传递的参数只有一个,那么第二个参数就调用默认参数,即NULL,再识别是否第一个参数是否是字符串,那么这个函数就识别为读取,如果第二个参数不为空或第一个参数为数组,那么就识别为设置!!

         由于我自己现在比较懒,而且我用这个函数用的函数蛮顺手的,所以在这儿我就直接用这个函数来作为例子了,更多内容可以查看Toper的/Library/Toper/function.php。

         比如现在要读取defaultController,那么只要使用C('defaultController')即可,如果要设置,那么使用C('defaultController','Index')!!!

          现在我们只需要在入口文件中导入这个function.php即可:

 

<?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');
include FRAMEWORK_PATH . '/function.php';
include FRAMEWORK_PATH . '/Route.php';
Route::run();

         大家可能注意到了,C函数最开始的时候,里面没有存放任何元素,那么我们怎么样进行初始化,将配置文件的内容写入C函数呢?

 

          之前我们将配置文件存放在项目根目录,这样实际上是不符合之前我们的约定的规范,所以现在讲这个配置文件剪切到/UserApps/Configs目录下面,为了更方便的使用这个路径,我们定义一个CONFIGS_PATH来指向配置文件的路径。

        现在我们看看入口文件变成了什么样了:

 

<?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/Configs');
include FRAMEWORK_PATH . '/function.php';
C(include CONFIGS_PATH . '/config.php'); //写入配置信息
include FRAMEWORK_PATH . '/Route.php';
Route::run();

      然后我们修改一下Route.php

 

 

<?php
class Route {
	public static function run() {
		$controller = empty($_GET['c']) ? C('defaultController') : trim($_GET['c']); //设置了默认的控制器
		$action = empty($_GET['a']) ? C('defaultAction') : trim($_GET['a']); //设置了默认的Action
		$controllerBasePath = APP_PATH . '/UserApps/Modules/Controllers/';
		$controllerFilePath = $controllerBasePath . $controller . 'Controller.php';
		if(is_file($controllerFilePath)) {
			include $controllerFilePath;
			$controllerName = $controller . 'Controller';
			if(class_exists($controllerName)) {
				$controllerHandler = new $controllerName();
				if(method_exists($controllerHandler,$action)) {
					$controllerHandler->$action();
				} else {
					echo 'the method does not exists';
				}
			} else {
				echo 'the class does not exists';
			}
		} else {
			echo 'controller not exists';
		}
	}
}

      今天的例子 点此下载

本文转载自:http://my.oschina.net/mingtingling/blog/90143

NateHuang
粉丝 19
博文 65
码字总数 30683
作品 0
深圳
后端工程师
私信 提问
一步步编写PHP的Framework(一)

框架这个概念可能一开始就吓坏了很多PHP的Coder,其实你只要把一个Framework想明白了,其实也没啥,只是别人功能更复杂,细节考虑的更多,代码质量更高。 框架最重要的一个文件为入口文件,基...

NateHuang
2016/07/27
23
0
一步步编写简单的PHP的Framework(六)

不好意思,由于最近事情比较多,昨天的确没有时间写,今天刚好还有接近一个小时的时间,所以就继续写一篇。 不知道大家注意到没有,之前我们导入一个配置文件是通过include CONFIGS_PATH . ...

NateHuang
2016/07/28
10
0
怎么一步步编写简单的PHP的Framework(一)

自从入职天猫之后,都没怎么时间看oschina了,趁着这段时间参加培训,忙里偷闲,写几篇日志吧。 框架这个概念可能一开始就吓坏了很多PHP的Coder,其实你只要把一个Framework想明白了,其实也...

阳光test
2012/11/15
9.2K
22
Yosemite Intellij idea php设置xdebug单步调试

PHP设置单步调试 一直看看PHP语法,最近看貌似很火的laravel,还有一个基于laravel/framework的OctoberCRM,一直没找到方式做单步调试,今天总算达成了。 IDE用的Intellij idea,Android Stu...

zmhot88
2015/04/04
2.5K
2
怎么一步步编写简单的PHP的Framework(八)

昨天我写到我们使用前端控制器来控制所有请求,今天我们继续这个话题。 既然前端控制器控制一切,那么我们可以用它来做更多的事情!! 我们知道,在windows里面默认php.ini中display_errors默...

阳光test
2012/11/25
1K
7

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins World 贡献者峰会及专家答疑展位

本文首发于:Jenkins 中文社区 原文链接 作者:Marky Jackson 译者:shunw Jenkins World 贡献者峰会及专家答疑展位 本文为 Jenkins World 贡献者峰会活动期间的记录 Jenkins 15周岁啦!Jen...

Jenkins中文社区
24分钟前
6
0
杂谈:面向微服务的体系结构评审中需要问的三个问题

面向微服务的体系结构如今风靡全球。这是因为更快的部署节奏和更低的成本是面向微服务的体系结构的基本承诺。 然而,对于大多数试水的公司来说,开发活动更多的是将现有的单块应用程序转换为...

liululee
38分钟前
6
0
OSChina 周二乱弹 —— 我等饭呢,你是不是来错食堂了?

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @ 自行车丢了:给主编推荐首歌 《クリスマスの夜》- 岡村孝子 手机党少年们想听歌,请使劲儿戳(这里) @烽火燎原 :国庆快来,我需要长假! ...

小小编辑
今天
409
9
玩转 Springboot 2 之热部署(DevTools)

Devtools 介绍 SpringBoot 提供了热部署的功能,那啥是热部署累?SpringBoot官方是这样说的:只要类路径上的文件发生更改,就会自动重新启动应用程序。在IDE中工作时,这可能是一个有用的功能...

桌前明月
今天
5
0
CSS--列表

一、列表标识项 list-style-type none:去掉标识项 disc:默认实心圆 circle:空心圆 squire:矩形 二、列表项图片 list-style-img: 取值:url(路径) 三、列表项位置 list-style-position:...

wytao1995
今天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部