从ThinkPHP框架核心讨论C、E、G、L、T、I、N…等函数

为什么要用 yaml

如果只是从了解怎么用这几函数的角度看,直接看官方发布的文档即可!但是要了解这些函数是怎么被ThinkPHP框架定义调用的,那需要另外一番讨
论了。还好,ThinkPHP官方在源码力做了很好的注释,通过一步步探索我发现只要你找到代码的定义位置,你就能更精确的把握其应用,甚至不用读代码,
官方的代码注释就能帮你很好的理解。废话不多说,来看我找的框架执行代码的几个位置:

因为 Yaml 简单,而且对人类友好;

   首先,从入口文件index.php里面看到框架的执行通过“require
‘./ThinkPHP/ThinkPHP.php’;”执行,打开这个文件,看里面的start() 方法:

Yaml:

   …………………………..

在哪里会用到?

      static public function start() {
     // 注册AUTOLOAD方法
     spl_autoload_register(‘ThinkThink::autoload’);      
     // 设定错误和异常处理
     register_shutdown_function(‘ThinkThink::fatalError’);
     set_error_handler(‘ThinkThink::appError’);
     set_exception_handler(‘ThinkThink::appException’);

最基本的,在 ThinkPHP 的配置文件里面就可以选择 Yaml 的格式,你是愿意写
Yaml 的简洁格式配置呢?还是愿意写又长又臭又难写的 PHP array 呢?

     // 初始化文件存储方式
     Storage::connect(STORAGE_TYPE);

     $runtimefile  = RUNTIME_PATH.APP_MODE.’~runtime.php’;
     if(!APP_DEBUG && Storage::has($runtimefile)){
         Storage::load($runtimefile);
     }else{
         if(Storage::has($runtimefile))
             Storage::unlink($runtimefile);
         $content =  ”;
         // 读取应用模式
         $mode   =   include
is_file(CONF_PATH.’core.php’)?CONF_PATH.’core.php’:MODE_PATH.APP_MODE.’.php’;
         // 加载核心文件
         /*Array
(
   [0] => C:wampwwwonthinkThinkPHP/Common/functions.php
   [1] => ./Application/Common/Common/function.php
   [2] =>
C:wampwwwonthinkThinkPHPLibrary/Think/Hook.class.php
   [3] =>
C:wampwwwonthinkThinkPHPLibrary/Think/App.class.php
   [4] =>
C:wampwwwonthinkThinkPHPLibrary/Think/Dispatcher.class.php
   [5] =>
C:wampwwwonthinkThinkPHPLibrary/Think/Route.class.php
   [6] =>
C:wampwwwonthinkThinkPHPLibrary/Think/Controller.class.php
   [7] =>
C:wampwwwonthinkThinkPHPLibrary/Think/View.class.php
   [8] =>
C:wampwwwonthinkThinkPHPLibrary/Behavior/ParseTemplateBehavior.class.php
   [9] =>
C:wampwwwonthinkThinkPHPLibrary/Behavior/ContentReplaceBehavior.class.php
)
          */
         foreach ($mode[‘core’] as $file){
             if(is_file($file)) {
               include $file;
               if(!APP_DEBUG) $content   .= compile($file);
             }
         }

问题来了

         // 加载应用模式配置文件
         foreach ($mode[‘config’] as $key=>$file){
             is_numeric($key)?C(include $file):C($key,include $file);
         }

于是,我把配置格式改为 Yaml:
复制代码 代码如下:
// /index.php

         // 读取当前应用模式对应的配置文件
         if(‘common’ != APP_MODE &&
is_file(CONF_PATH.’config_’.APP_MODE.’.php’))
             C(include CONF_PATH.’config_’.APP_MODE.’.php’);  

// 定义配置文件的格式为 yaml
define(‘CONF_EXT’, ‘.yaml’);

         // 加载模式别名定义
         if(isset($mode[‘alias’])){
           
 self::addMap(is_array($mode[‘alias’])?$mode[‘alias’]:include
$mode[‘alias’]);
         }

然后把 Application 目录下面的 config.php 全部改为 config.yaml。

         // 加载应用别名定义文件
         if(is_file(CONF_PATH.’alias.php’))
             self::addMap(include CONF_PATH.’alias.php’);

这个时候,报错:
复制代码 代码如下:
Class ‘Spyc’ not found 错误位置 FILE:
D:appthinkThinkPHPCommonfunctions.php  LINE: 90

         // 加载模式行为定义
         if(isset($mode[‘tags’])) {
           
 Hook::import(is_array($mode[‘tags’])?$mode[‘tags’]:include
$mode[‘tags’]);
         }

然后找,发现这一段:
复制代码 代码如下:
/**
 * 解析yaml文件返回一个数组
 * @param string $file 配置文件名
 * @return array
 */
if (!function_exists(‘yaml_parse_file’)) {
    function yaml_parse_file($file) {
        vendor(‘spyc.Spyc’);
        return Spyc::YAMLLoad($file);
    }
}

         // 加载应用行为定义
         if(is_file(CONF_PATH.’tags.php’))
             // 允许应用增加开发模式配置定义
             Hook::import(include CONF_PATH.’tags.php’);  

貌似引入 Spyc 这个库没找到。

         // 加载框架底层语言包
         L(include
THINK_PATH.’Lang/’.strtolower(C(‘DEFAULT_LANG’)).’.php’);

找了一下,Spyc 在这里:

         if(!APP_DEBUG){
             $content  .=  “nnamespace {
ThinkThink::addMap(“.var_export(self::$_map,true).”);”;
             $content  .=
 “nL(“.var_export(L(),true).”);nC(“.var_export(C(),true).’);ThinkHook::import(‘.var_export(Hook::get(),true).’);}’;
             Storage::put($runtimefile,strip_whitespace(‘<?php
‘.$content));
         }else{
           // 调试模式加载系统默认的配置文件
           C(include THINK_PATH.’Conf/debug.php’);
           // 读取应用调试配置文件
           if(is_file(CONF_PATH.’debug.php’))
               C(include CONF_PATH.’debug.php’);          
         }
     }

然后,这个 vendor 是什么东东?


面那个打印出来的数组是我加上去的,可以看出来,这个数组就是ThinkPHP加载的核心文件,其中包括
 “ThinkPHP/Common/functions.php”和“
./Application/Common/Common/function.php”;在前面的functions.php文件里面会发现各种函数库:

看这里:

/**
* 获取和设置配置参数 支持批量定义
* @param string|array $name 配置变量
* @param mixed $value 配置值
* @param mixed $default 默认值
* @return mixed
*/
function C($name=null, $value=null,$default=null) {
   static $_config = array();
   // 无参数时获取所有
   if (empty($name)) {
       return $_config;
   }
   // 优先执行设置获取或赋值
   if (is_string($name)) {
       if (!strpos($name, ‘.’)) {
           $name = strtolower($name);
           if (is_null($value))
               return isset($_config[$name]) ? $_config[$name] :
$default;
           $_config[$name] = $value;
           return;
       }
       // 二维数组设置和获取支持
       $name = explode(‘.’, $name);
       $name[0]   =  strtolower($name[0]);
       if (is_null($value))
           return isset($_config[$name[0]][$name[1]]) ?
$_config[$name[0]][$name[1]] : $default;
       $_config[$name[0]][$name[1]] = $value;
       return;
   }
   // 批量设置
   if (is_array($name)){
       $_config = array_merge($_config,
array_change_key_case($name));
       return;
   }
   return null; // 避免非法参数
}

结论:

/**
* 抛出异常处理
* @param string $msg 异常消息
* @param integer $code 异常代码 默认为0
* @return void
*/
function E($msg, $code=0) {
   throw new ThinkException($msg, $code);
}

在上面的 Git 里面下载 Spyc.php 放进 /ThinkPHP/Library/Vendor/spyc/
目录下,就一切正常!Done with the right way!

/**
* 记录和统计时间(微秒)和内存使用情况
* 使用方法:
* <code>
* G(‘begin’); // 记录开始标记位
* // … 区间运行代码
* G(‘end’); // 记录结束标签位
* echo G(‘begin’,’end’,6); // 统计区间运行时间 精确到小数后6位
* echo G(‘begin’,’end’,’m’); // 统计区间内存使用情况
* 如果end标记位没有定义,则会自动以当前作为标记位
* 其中统计内存使用需要 MEMORY_LIMIT_ON 常量为true才有效
* </code>
* @param string $start 开始标签
* @param string $end 结束标签
* @param integer|string $dec 小数位或者m
* @return mixed
*/
function G($start,$end=”,$dec=4) {
   static $_info       =   array();
   static $_mem        =   array();
   if(is_float($end)) { // 记录时间
       $_info[$start]  =   $end;
   }elseif(!empty($end)){ // 统计时间和内存使用
       if(!isset($_info[$end])) $_info[$end]       =
 microtime(TRUE);
       if(MEMORY_LIMIT_ON && $dec==’m’){
           if(!isset($_mem[$end])) $_mem[$end]     =
 memory_get_usage();
           return
number_format(($_mem[$end]-$_mem[$start])/1024);
       }else{
           return
number_format(($_info[$end]-$_info[$start]),$dec);
       }

   }else{ // 记录时间和内存使用
       $_info[$start]  =  microtime(TRUE);
       if(MEMORY_LIMIT_ON) $_mem[$start]           =
 memory_get_usage();
   }
}

 

当然,C、E、G、L、T、I、N…等函数也在其中,呵呵
是不是发现不止这些函数的定义,这里的资源只要了解就能精确把握应用;至于每个函数的用法不在多说……

 

 

**制作人:飞虎                                          

无兄弟不编程!

欢迎加QQ群进行更多交流:305397511    
专注于php、mysql、jquery以及开源框架**

 

 

 


发表评论

电子邮件地址不会被公开。 必填项已用*标注