CI框架libraries目录下引入命名空间、自动加载类文件好处和应用场景

项目中使用到了predis库,现在项目有需求需要使用多个LUA脚本,那么这些文件(.php)改放在什么地方合适呢?

放在third_party/predis111/scr/MyScript目录下是最方便的,但是不合适!

原因:predis111是库sdk ,放在他下面就是改变了sdk, sdk变得不干净了,后期sdk升级自己的脚本就被覆盖了,很危险!

放在libraries 目录下相对合适,像PHPEXCEL 如果大量使用,为了更好组织文件(也许自己写了子类,父类,抽象类)这样的话更需要引入命名空间,自动加载。

组织结构如下:

 要使调用时能找到对应的类文件就要使用类自动加载和命名空间了。

Predis.php代码如下:

注意,两个autoload.php 的require包含,第一个目的是为了能自动找到sdk中的类, 第二个目的是为了能自动找到MyscriptLiang下的类文件。

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH.'third_party/predis111/autoload.php';
require APPPATH."libraries/predis/autoload.php";

class Predis{

  private $_redis = null;
  public function __construct(){
    $CI = &get_instance();
    $CI ->config->load('predis',TRUE);
    $predis_config = $CI ->config->item('predis','predis');
    
    $host = isset($predis_config['default']['host']) ? $predis_config['default']['host'] : null;
    $port = isset($predis_config['default']['port']) ? $predis_config['default']['port'] : null;
    if(empty($host) || empty($port)){
      exit('predis config error');
    }
    
    
    $this->_redis = new Predis\Client(array(
      'host'=> $host,
      'port' => $port
    ));

    try{
      $this->_redis->connect();
    }catch(Predis\Connection\ConnectionException $e){
      echo 'Predis connect redis-server has exception! Message:'.$e->getMessage();
      exit();
    }
    
  }
  
  public function __call($name,$args){
    $callback = array($this->_redis,$name);
    return call_user_func_array($callback,$args);
  }
}

自定的autoload.php 代码如下:

注意:定义命名空间

<?php
/**
 * Created by PhpStorm.
 * User: liang
 * Date: 2018/3/23
 * Time: 下午11:19
 */
namespace lib\Predis;


spl_autoload_register(function($className){
//    echo __NAMESPACE__;
    echo 'CLASS:',$className, "<br/>";
    //className : 如:lib\Predis\MyscriptLiang\Sumscores
    if(0 === strpos($className, __NAMESPACE__)) {
        //echo substr($className, strlen(__NAMESPACE__)),"<br/>";   //  \MyscriptLiang\Sumscores

        $parts = explode('\\', substr($className, strlen(__NAMESPACE__.'\\')));
        echo "<pre>";
        var_dump($parts);   //PATH:/mnt/hgfs/work_www/blog/application/libraries/predis/MyscriptLiang/Sumscores.php
        echo "</pre>";
//        array(2) {
//            [0]=>
//  string(13) "MyscriptLiang"
//            [1]=>
//  string(9) "Sumscores"
//}
        $filepath = __DIR__.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $parts).'.php';
        echo "PATH:";
        echo $filepath;
        echo "<br/>";

        if (is_file($filepath)) {
            require $filepath;
        }
    }
},true,false);


脚本Sumscores.php 中注意定义自己的命名空间;想使用sdk 中类,就要use引用sdk中的命名空间,代码如下:

<?php
/**
 * Created by PhpStorm.
 * User: liang
 * Date: 2018/3/19
 * Time: 上午11:15
 */
namespace lib\Predis\MyscriptLiang;
use Predis\Command\ScriptCommand;

class Sumscores extends ScriptCommand {
    public function getKeysCount()
    {
        // Tell Predis to use all the arguments but the last one as arguments
        // for KEYS. The last one will be used to populate ARGV.
        return -1;  
    }

    /**
     * @return string
     *  注意ipairs  和pairs区别!
     */
    public function getScript()
    {
        return <<<LUA
local sum = 0
local users = redis.call('mget',unpack(KEYS))
for _, user in ipairs(users) do
    local courses = cjson.decode(user).courses
    for c, score in pairs(courses) do 
       sum = sum + score +3
    end
end
return sum
LUA;
    }
}

libraries中自己类组织好了,下面看看控制器中怎么使用这些类?Script.php 代码如下:


    public function test_sum(){
	    $this->load->library('predis');

        $this->predis->getProfile()->defineCommand('sumscores','lib\Predis\MyscriptLiang\\'.'Sumscores');  // \挨着' 所以需要转译
        $bob = new stdClass();
        $bob->name = 'bob';
        $bob->courses = new stdClass();
        $bob->courses->数学 = 90;
        $bob->courses->语文 = 70;

        $jeff = new stdClass();
        $jeff->name = 'jeff';
        $jeff->courses = new stdClass();
        $jeff->courses->数学 = 80;
        $jeff->courses->语文 = 60;

        $bob = array(
            'name'=>'bob',
            'courses'=>array(
                'math'=> 90,
                'yuwen'=> 100
            )
        );

        $jeff = array(
            'name'=>'jeff',
            'courses'=>array(
                'math'=> 80,
                'yuwen'=> 60
            )
        );

        $this->predis->set('script:user:1',json_encode($bob));
        $this->predis->set('script:user:2',json_encode($jeff));


        $sum = $this->predis->sumscores('script:user:1','script:user:2','argv');
        echo 'sum:';
        var_dump($sum);
    }

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值