YiluPHP
这家伙很懒,什么都没有留下...

经验 极其精简的PHP框架WJW

浏览数 195398
最近在做一个项目,使用PHP做后端服务,为了提升代码执行效率,自己写了这个极其精简的PHP框架,我把它命令为WJW,我的姓名的缩写 
框架中包含连接多个数据库的实现、连接多个redis的实现,和自动加载调用到的类文件。目标是做到尽量少得执行代码、尽量少得加载文件。
  1. 框架仅支持PDO连接数据库,不做多种数据库的支持,也不做多种连接方式的支持;
  2. 框架中操作数据库的方式和操作redis的方式都使用原生的方法,没有封装更多层代码,用于减少代码的执行路径;
  3. WJW框架建议把所有可能的自定义类都放到helper目录中,包括类库、Model类、service类等等,用于减少使用类文件时的目录判断和框架的代码量,开发者可以通过使用类文件的命令规则区分不同种类的文件;
  4. WJW框架建议在每一次请求中都尽量少得加载文件、尽量短的代码执行路径,因为开发者在组织代码结构时也需要往这个方向靠拢,才能开发出更加极速高效的系统。

目录和文件结构:

helper/  Model类、service类等等类库的存放目录,类文件的文件名和类名需要一致,

      在项目中无需手工实例化类,可以直接使用$app->your_class_name->your_method_name(); 访问。

------helper_demo.PHP  这是一个类库的示例文件,可以删除

public/  服务器中配置虚拟主机时,根目录指向此目录,此目录是对外访问的入口

------demo.php  这是一个请求接口的示例,可以删除

base.php  基础文件,包含配置文件、公共函数库、创建$app实例。

      所有接口首先引入base.php,此文件中会创建实例$app,

      连接数据库Redis都通过此实例。

config.php 有些因运行环境(开发、测试、生产)不一样的配置信息写在

      这个文件中,这个文件在发布时不需要发布。


base.php 代码如下:

  1. <?php  
  2.   
  3. /* 
  4.  * 基础文件,包含配置文件、公共函数库、创建$app实例 
  5.  * 所有接口首先引入base.php,此文件中会创建实例$app,连接数据库和redis都通过此实例 
  6.  */  
  7.   
  8. //配置文件往$config数组中写  
  9. $config = [];  
  10. //有些因运行环境(开发、测试、生产)不一样的配置信息写在config.php中,不跟随项目发布  
  11. $config = array_merge($configrequire('config.php'));  
  12.   
  13. function connectDB($options)  
  14. {  
  15.     try {  
  16.         $pdo = new PDO(  
  17.             $options['dsn'],  
  18.             $options['username'],  
  19.             $options['password'],  
  20.             $options['option']  
  21.         );  
  22.         // 设置 PDO 错误模式为异常 ,用于抛出异常  
  23.         $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);  
  24.         if (isset($options['charset'])) {  
  25.             $pdo->exec('SET NAMES "'.$options['charset'].'"');  
  26.         }  
  27.         return $pdo;  
  28.     }  
  29.     catch (PDOException $e) {  
  30.         throw new Exception($e->getMessage());  
  31.     }  
  32. }  
  33.   
  34. function connectRedis($options)  
  35. {  
  36.     $redis = new Redis();  
  37.     $redis->pconnect($options['host'], $options['port']);  
  38.     return $redis;  
  39. }  
  40.   
  41. class wjw  
  42. {  
  43.     public $db_list = [];  
  44.     public $redis_list = [];  
  45.     public $helpers = [];  
  46.     public function __construct()  
  47.     {  
  48.     }  
  49.   
  50.     public function __destruct()  
  51.     {  
  52.         foreach ($this->db_list as $key => &$pdo) {  
  53.             $pdo = null;  
  54.             unset($this->db_list[$key]);  
  55.         }  
  56.         foreach ($this->redis_list as $key => &$redis) {  
  57.             $redis->close();  
  58.             unset($this->redis_list[$key]);  
  59.         }  
  60.     }  
  61.   
  62.     public function db($db_name='default')  
  63.     {  
  64.         global $config;  
  65.         $db_name = empty($db_name)?'default':$db_name;  
  66.         if (!isset($config['db'][$db_name]) ) {  
  67.             throw new Exception('数据库配置不存在:'.$db_name);  
  68.         }  
  69.         if ( !isset($this->db_list[$db_name]) && isset($config['db'][$db_name]) ) {  
  70.             $this->db_list[$db_name] = connectDB($config['db'][$db_name]);  
  71.         }  
  72.         return $this->db_list[$db_name];  
  73.     }  
  74.   
  75.     public function redis($redis_name='default')  
  76.     {  
  77.         global $config;  
  78.         $redis_name = empty($redis_name)?'default':$redis_name;  
  79.         if (!isset($config['redis'][$redis_name]) ) {  
  80.             throw new Exception('Redis配置不存在:'.$redis_name);  
  81.         }  
  82.         if ( !isset($this->redis_list[$redis_name]) && isset($config['redis'][$redis_name]) ) {  
  83.             $this->redis_list[$redis_name] = connectRedis($config['redis'][$redis_name]);  
  84.         }  
  85.         return $this->redis_list[$redis_name];  
  86.     }  
  87.   
  88.     public function __get($name)  
  89.     {  
  90.         if (isset($this->helpers[$name])) {  
  91.             return $this->helpers[$name];  
  92.         }  
  93.         if (file_exists(dirname(__FILE__).'/helper/'.$name.'.php')) {  
  94.             //helper类文件的文件名、类名、app中的调用方法三者需要一致  
  95.             require_once(dirname(__FILE__).'/helper/'.$name.'.php');  
  96.             $this->helpers[$name] = new $name;  
  97.             return $this->helpers[$name];  
  98.         }  
  99.         else{  
  100.             throw new Exception('helper文件不存在:'.$name.'.php');  
  101.         }  
  102.     }  
  103. }  
  104.   
  105. $app = new wjw();   

config.php代码如下:
  1. <?php  
  2. return [  
  3.     'db' => [  
  4.         'default' => [  
  5.             'dsn'    =>  'mysql:host=127.0.0.1;port=3306;dbname=yourDbName',  
  6.             'username'    =>  'yourUsername',  
  7.             'password'    =>  'yourPassword',  
  8.             'charset'    =>  'utf8',  
  9.             'option'    =>  [],  
  10.         ]  
  11.     ],  
  12.     'redis' => [  
  13.         'default' => [  
  14.             'host'    =>  '127.0.0.1',  
  15.             'port'    =>  '6379',  
  16.         ]  
  17.     ],  
  18. ];   

/public/demo.php 代码如下:
  1. <?php  
  2. /* 
  3.  * 接口示例,每个接口一个文件,或者每类接口一个文件,原则上是单个文件越小越好 
  4.  * 所有接口首先引入base.php,此文件中会创建实例$app,连接数据库和redis都通过此实例 
  5.  */  
  6. require_once('../base.php');  
  7.   
  8. //使用PHP中PDO的原生方法操作数据库  
  9. 读取一条记录  
  10. $uuid = 763;  
  11. $sql = 'SELECT * FROM `users` WHERE `uid` = :uid LIMIT 1';  
  12. $stmt = $app->db()->prepare($sql);     
  13. $stmt->execute(array(':uid'=>$uid));  
  14. while($row = $stmt->fetch(PDO::FETCH_ASSOC)){        
  15.     print_r($row);  
  16. }  
  17.   
  18. //读取数据列表  
  19. $status = 6;  
  20. $sql = 'SELECT * FROM `users` WHERE `status` < :status LIMIT 3';  
  21. $stmt = $app->db()->prepare($sql);     
  22. $stmt->execute(array(':status'=>$status));  
  23. print_r( $stmt->fetchAll(PDO::FETCH_ASSOC));  
  24. unset($stmt);  
  25.   
  26. //使用PHP中redis的原生方法操作redis  
  27. $app->redis()->set('aaa''aaa的值');  
  28. $value = $app->redis()->get('aaa');  
  29. print_r($value);  
  30.   
  31. //将helper类文件放入helper目录中,使用$app->yourClassName 调用  
  32. //helper类文件的文件名、类名、app中的调用方法三者需要一致  
  33. $app->helper_demo->test_helper('测试helper的使用');  

/helper/helper_demo.php 代码如下:
  1. <?php  
  2.   
  3. class helper_demo  
  4. {  
  5.     public function __construct()  
  6.     {  
  7.     }  
  8.   
  9.     public function __destruct()  
  10.     {  
  11.     }  
  12.   
  13.     public function test_helper($val)  
  14.     {  
  15.         var_dump($val);  
  16.     }  
  17. }   

后期可能会增加少量常用函数和类,增加后修改原文内容,敬请关注。

欢迎 phper 们留言评论,指出不足和提出宝贵建议。

我来说说