牛骨文教育服务平台(让学习变的简单)
博文笔记

极其精简的PHP框架WJW

创建时间:2017-06-21 投稿人: 浏览次数:2896
最近在做一个项目,使用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 代码如下:

<?php

/*
 * 基础文件,包含配置文件、公共函数库、创建$app实例
 * 所有接口首先引入base.php,此文件中会创建实例$app,连接数据库和redis都通过此实例
 */

//配置文件往$config数组中写
$config = [];
//有些因运行环境(开发、测试、生产)不一样的配置信息写在config.php中,不跟随项目发布
$config = array_merge($config, require("config.php"));

function connectDB($options)
{
    try {
        $pdo = new PDO(
            $options["dsn"],
            $options["username"],
            $options["password"],
            $options["option"]
        );
        // 设置 PDO 错误模式为异常 ,用于抛出异常
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        if (isset($options["charset"])) {
            $pdo->exec("SET NAMES "".$options["charset"].""");
        }
        return $pdo;
    }
    catch (PDOException $e) {
        throw new Exception($e->getMessage());
    }
}

function connectRedis($options)
{
    $redis = new Redis();
    $redis->pconnect($options["host"], $options["port"]);
    return $redis;
}

class wjw
{
    public $db_list = [];
    public $redis_list = [];
    public $helpers = [];
    public function __construct()
    {
    }

    public function __destruct()
    {
        foreach ($this->db_list as $key => &$pdo) {
            $pdo = null;
            unset($this->db_list[$key]);
        }
        foreach ($this->redis_list as $key => &$redis) {
            $redis->close();
            unset($this->redis_list[$key]);
        }
    }

    public function db($db_name="default")
    {
        global $config;
        $db_name = empty($db_name)?"default":$db_name;
        if (!isset($config["db"][$db_name]) ) {
            throw new Exception("数据库配置不存在:".$db_name);
        }
        if ( !isset($this->db_list[$db_name]) && isset($config["db"][$db_name]) ) {
            $this->db_list[$db_name] = connectDB($config["db"][$db_name]);
        }
        return $this->db_list[$db_name];
    }

    public function redis($redis_name="default")
    {
        global $config;
        $redis_name = empty($redis_name)?"default":$redis_name;
        if (!isset($config["redis"][$redis_name]) ) {
            throw new Exception("Redis配置不存在:".$redis_name);
        }
        if ( !isset($this->redis_list[$redis_name]) && isset($config["redis"][$redis_name]) ) {
            $this->redis_list[$redis_name] = connectRedis($config["redis"][$redis_name]);
        }
        return $this->redis_list[$redis_name];
    }

    public function __get($name)
    {
        if (isset($this->helpers[$name])) {
            return $this->helpers[$name];
        }
        if (file_exists(dirname(__FILE__)."/helper/".$name.".php")) {
            //helper类文件的文件名、类名、app中的调用方法三者需要一致
            require_once(dirname(__FILE__)."/helper/".$name.".php");
            $this->helpers[$name] = new $name;
            return $this->helpers[$name];
        }
        else{
            throw new Exception("helper文件不存在:".$name.".php");
        }
    }
}

$app = new wjw(); 

config.php代码如下:

<?php
return [
    "db" => [
        "default" => [
            "dsn"    =>  "mysql:host=127.0.0.1;port=3306;dbname=yourDbName",
            "username"    =>  "yourUsername",
            "password"    =>  "yourPassword",
            "charset"    =>  "utf8",
            "option"    =>  [],
        ]
    ],
    "redis" => [
        "default" => [
            "host"    =>  "127.0.0.1",
            "port"    =>  "6379",
        ]
    ],
]; 

/public/demo.php 代码如下:

<?php
/*
 * 接口示例,每个接口一个文件,或者每类接口一个文件,原则上是单个文件越小越好
 * 所有接口首先引入base.php,此文件中会创建实例$app,连接数据库和redis都通过此实例
 */
require_once("../base.php");

//使用PHP中PDO的原生方法操作数据库
读取一条记录
$uuid = 763;
$sql = "SELECT * FROM `users` WHERE `uid` = :uid LIMIT 1";
$stmt = $app->db()->prepare($sql);   
$stmt->execute(array(":uid"=>$uid));
while($row = $stmt->fetch(PDO::FETCH_ASSOC)){      
    print_r($row);
}

//读取数据列表
$status = 6;
$sql = "SELECT * FROM `users` WHERE `status` < :status LIMIT 3";
$stmt = $app->db()->prepare($sql);   
$stmt->execute(array(":status"=>$status));
print_r( $stmt->fetchAll(PDO::FETCH_ASSOC));
unset($stmt);

//使用PHP中redis的原生方法操作redis
$app->redis()->set("aaa", "aaa的值");
$value = $app->redis()->get("aaa");
print_r($value);

//将helper类文件放入helper目录中,使用$app->yourClassName 调用
//helper类文件的文件名、类名、app中的调用方法三者需要一致
$app->helper_demo->test_helper("测试helper的使用");

/helper/helper_demo.php 代码如下:

<?php

class helper_demo
{
    public function __construct()
    {
    }

    public function __destruct()
    {
    }

    public function test_helper($val)
    {
        var_dump($val);
    }
} 

后期可能会增加少量常用函数和类,增加后修改原文内容,也可以在我的个人网站中查看。

http://www.weinidai.com/index.php/News/detail/id/127

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



声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。