zoukankan      html  css  js  c++  java
  • 巧妙的重载魔术方法__call()

    工作半年了,感觉这半年学到的东西比大学四年学到的还要多,主要原因是心静下来了,目标也明确了,不会去整天的和游戏纠缠在一起了。大学时候其实也意识到了玩游戏会影响自己的正常学习和工作的,但是一直控制不了自己,还是忍不住经常去玩,没日没夜的玩(本来就是闷骚男,还宅着玩游戏,这也是大学四年只有游戏、左右手,没有女朋友的一个原因了)。现在工作了,每天都有任务,看到旁边的牛人们在项目中如鱼得水,就有了赶超他们的想法,于是每天都会给自己一个额外的小任务去学习新的知识,到现在工作有半年了,对以前不熟悉的linux现在也可应熟悉的使用了,对不熟悉的js也有了新的认识,可以说现在我对工作可以胜任(如果分为新手、高级新手、胜任者、精通者、专家)了,开发过活动、接口、后台,也优化完善过系统的框架,只要是产品运营提出的合理需求都可以快速的支持到位。当然还确确实实的感受到一点:程序员真是一个奇怪的群体,大多时候总是会觉得自己的点子是最好的。当然这个算是自信但有时候讨论的时候你的咄咄逼人不一定是好事,所以还要多听听其他人的想法,不但可以发现自己的不足,还会建立良好的:”友谊“。跟大家瞎扯了这么多这半年的一点点感受,谢谢你可以坚持看完^_^。

    下面步入真题,说说如何巧妙的运用php的魔术方法,我相信这个在大多数项目中会用到。

    先说明一下,这个小技巧我在项目中已经有很好的应用了,给我们项目带来了很大的方便,在这里先卖卖关子,您不妨继续往下看。

    在项目中,可配的配置信息一定大量存在,比如说一个游戏的机器人开放时间段、支付方式的开启与否、商城显示title的配置等等,这些配置信息一般有一个特点就是没有特定的规则,而且产品运营可以随时的给据实际情况去修改,这些信息怎么保存呢,肯定不会每种类型都去建一张表,这样做简直就是费力不讨好,你想下,也许一张表中就保存了一条信息,所以得想想其他的方法,虽然这些信息没有规则,但是他们却有一个特点就是不会有太多,而且一般情况下数组就可以保存所有需要配置的信息,因此用json字符串存储信息是个不错的选择,当需要使用的时候直接取出json_decode这样就可以直接使用了,下面看看具体怎么巧妙的利用php的魔术方法实现的。

    这里你先要了解下php的一个魔术方法__call(),查下php官方的文档,是这样解释这个函数的

    public mixed __call ( string $name , array $arguments )
    
    __call() is triggered when invoking inaccessible methods in an object context.

    意思就是说当在一个对象中调用一个不可访问的方法(没有权限、不存在)时会触发这个函数,函数的参数$name是调用的函名,$arguments是调用的函数参数数组。看看下面这个例子:

    class Test
    {
        public function __call($name, $arguments)
        {
            echo "你调用了一个不存在的方法:
    ";
            echo "函数名:{$name}
    ";
            echo "参数: 
    ";
            print_r($arguments);
        }
    }
    
    $T = new Test();
    $T->setrobottime("12", "18");

    这个函数会输出下面的结果

    你调用了一个不存在的方法:
    函数名:setrobottime
    参数: 
    Array
    (
        [0] => 12
        [1] => 18
    )

    这样,我们就可以不去直接定义函数,而是用这个特性去做一些事情了。下面看看代码的实现思路,主要是思路,其中有些我是假设的,就像数据库连接,这里不主要讲这个。

    class Config
    {
        /**
         * 这里假定下数据库表名为
         * config.config,
         * 字段为:
         * config_key varchar(50),
         * config_value text,
         * primary key(config_key)
         *
         * 数据库连接为$link
         * 插入方法封装为query
         * 获取一条信息方法封装为getOne
         */
        /**
         * 要进行的操作
         */
        private static $keys = array(
            //'调用方法' => 'key',
            'roboottime'    => 'ROBOOTTIME',
            'dailysignin'   => 'DAILYSIGNIN',
        );
    
        /**
         * 设置方法
         * @param string $config_key 配置项key
         * @param string $config_value 配置型内容(一般为json格式)
         * @returne boolen true/false 插入是否成功
         */
        private function set($config_key, $config_value){
            $sql = "insert into config.config (config_key,config_value) values ('{$config_key}','{$config_value}') on duplicate key update config_value='{$config_value}'";
            return $link->query($sql);
        }
    
        /**
         * 获取值的方法
         * @param $config_key 要获取的配置的key
         * @returne string/false json字符串/失败
         */
        private function get($config_key)
        {
            $sql = "select * from config.config where config_key='{$config_key}'";
            if($ret = $link->getOne($sql, MYSQL_ASSOC)){
                return $ret;
            }
            return false;
        }
    
        /**
         * 重载魔术方法
         * @param string $name 被调用的方法名
         * @param array $arguments 调用时传递的参数
         * @return mixed 返回结果
         */
        public function __call($name, $arguments)
        {
            $act    = substr($name, 0, 3);
            $func   = strtolower(substr($name, 3));
            if(!in_array($func, self::$keys)){
                return false;
            }
            if($act == 'set')
            {
                return $this->set(self::$keys[$name], $arguments[0]);
            }
            elseif($act == 'get')
            {
                return $this->get(self::$keys[$name]);
            }
            return false;
        }
    }

    这样,我们的就可以通过一张表存储多个信息了,调用时也很方便,只需要扩展下Config::$keys数组中的信息就可以了,这样做只是为了规范,为了可以清晰的知道哪些配置存放在了这张表中。

    使用的时候可以像这样去存储和获取

    $config = new Config();
    
    $info = array("12","20");
    
    //设置
    $config->setroboottime(json_encode($info));
    
    //获取
    $config->getroboottime();

    这里再说一个要注意的点,这些配置信息一般会缓存到redis中,放在数据库中只是为了防止redis挂掉之后从数据库中去恢复,这里的一般指的是那些经常去读取的信息,为了减少和db的交互,直接放在缓存中。

    绘图1

      本文版权归作者iforever(luluyrt@163.com)所有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    openssl 自己制作ssl证书:自己签发免费ssl证书,为nginx生成自签名ssl证书
    【nginx】一台nginx服务器多域名配置
    使用 Microsoft.Web.Administration 管理iis
    Android TextView : “Do not concatenate text displayed with setText”
    Android中将十六进制 颜色代码 转换为int类型数值
    android-getTextSize返回值是以像素(px)为单位的,setTextSize()以sp为单位
    Android属性allowBackup安全风险浅析
    Android 如何保持屏幕常亮
    Android 控制ScrollView滚动到底部
    Android 自定义TextView 实现文本间距
  • 原文地址:https://www.cnblogs.com/iforever/p/4214558.html
Copyright © 2011-2022 走看看