• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

巧妙的重载魔术方法__call()

php 搞代码 4年前 (2022-01-23) 19次浏览 已收录 0个评论

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

posted @ 2015-01-10 12:23 奔跑的Man 阅读() 评论() 编辑 收藏

<script type=”text/javascript”>var allowComments=true,isLogined=false,cb_blogId=199201,cb_entryId=4214558,cb_blogApp=currentBlogApp,cb_blogUserGuid=’89ec8f1e-f543-e411-b908-9dcfd8948a71′,cb_entryCreatedDate=’2015/1/10 12:23:00′;loadViewCount(cb_entryId);</script>

<script type=”text/javascript”>var commentManager = new blogCommentManager();commentManager.renderComments(0);</script>

刷新评论刷新页面返回顶部

博客园首页博问新闻闪存程序员招聘知识库

<script type=”text/javascript”> var enableGoogleAd = canShowAdsense(); var googletag = googletag || {}; googletag.cmd = googletag.cmd || []; fixPostBodyFormat();</script>

<script type=’text/javascript’> var googletag = googletag || {}; googletag.cmd = googletag.cmd || []; (function () { if (enableGoogleAd) { var gads = document.createElement(‘script’); gads.async = true; gads.type = ‘text/javascript’; var useSSL = ‘https:’ == document.location.protocol; gads.src = (useSSL ? ‘https:’ : ‘http:’) + ‘//www.googletagservices.com/tag/js/gpt.js’; var node = document.getElementsByTagName(‘script’)[0]; node.parentNode.insertBefore(gads, node); } })();</script><script type=’text/javascript’> try { if (enableGoogleAd) { googletag.cmd.push(function () { googletag.defineSlot(‘/1090369/cnblogs_blogpost_C1_sitehome’, [300, 250], ‘div-gpt-ad-1346480159711-0’).addService(googletag.pubads()); googletag.defineSlot(‘/1090369/cnblogs_blogpost_C2’, [468, 60], ‘div-gpt-ad-1410860226396-0’).addService(googletag.pubads()); googletag.pubads().enableSingleRequest(); googletag.enableServices(); }); }; } catch (e) { }</script>

<script type=’text/javascript’> try { if (enableGoogleAd) { googletag.cmd.push(function () { googletag.display(‘div-gpt-ad-1346480159711-0’); }); } else { $(‘#div-gpt-ad-1346480159711-0’).hide(); } } catch (e) { } </script>

<script type=’text/javascript’>try { if (enableGoogleAd) { googletag.cmd.push(function () { googletag.display(‘div-gpt-ad-1410860226396-0’); }); } else { $(‘#div-gpt-ad-1346480159711-0’).hide(); }} catch (e) { }</script>

<script type=”text/javascript”>$(function () { loadNewsAndKb(); loadBlogSignature(); LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid); GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate); loadOptUnderPost(); GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate); setTimeout(function () { incrementViewCount(cb_entryId); }, 200);});</script>

公告

<script type=”text/javascript”>loadBlogNews();</scri

本文#来源gaodai.ma#com搞##代!^码7网
搞代gaodaima码

pt>

<script type=”text/javascript”>loadBlogDefaultCalendar();</script>

<script type=”text/javascript”>loadBlogSideColumn();</script>

Copyright ©2015 奔跑的Man

以上就介绍了巧妙的重载魔术方法__call(),包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:巧妙的重载魔术方法__call()

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址