试着让类实例化一次(或者,“为什么我一直在打自己的头?”)

时间:2015-11-25 作者:C C

这里有一个非常简单的插件,我在多站点安装中将其放入mu\\u插件中:

<?php
/*
  Plugin Name: Test
 */

class myclass {
    function __construct() {
        error_log("I just punched myself in the head.");
    }
}  // end of class definition

/* start of plugin functions */
function run_plugin() {
    static $counter = 0;
    if (0 === $counter++) 
        $i = new myclass();
}

/* start of execution code */
add_action(\'init\',\'run_plugin\');
好的-我登录到WP admin,并切换页面两次--转到媒体库,然后转到主题。正在计算索引上的第一次着陆。php共有三个页面渲染。

此插件的输出:

I just punched myself in the head.
I just punched myself in the head.
I just punched myself in the head.
那么,给定调用函数中的静态计数器,为什么构造函数会被调用三次?或者,WP是否正在破坏我的插件并在每次加载页面时重新加载它?

我很困惑。

2 个回复
最合适的回答,由SO网友:Milo 整理而成

这个init 操作将在每次页面加载时触发一次。PHP不维护请求之间的状态。如果您想一次又一次地永远运行某个对象,那么您需要存储在请求之间持续存在的对象,例如数据库中的选项,并在执行一次性操作之前进行检查。

SO网友:Mateusz Hajdziony

不幸的是,这不是PHP的工作方式。PHP程序在单个请求期间(即有人加载页面时)完全执行(从头到尾)。一旦单击任何链接(转到网站中的另一个页面),所有内容都将被销毁(每个变量、类实例等),整个脚本将从头开始。

对于WordPress,每次有人请求页面时,都会加载并执行整个WordPress环境。WordPress的每一个动作(比如你在\'init\') 执行,所有插件和类都实例化。

当然,缓存发生在服务器端,但这是一个高级主题,对于初学者来说可能并不感兴趣。

正如Milo所说,如果您想让某些内容在页面加载到页面加载之间保持不变,那么必须将其存储在数据库中,很可能使用transient API (如果这是某种数据,而不是设置或帖子)。如果您所做的是希望每个用户运行一次的操作,则可以将其作为cookie存储在用户的浏览器中。

相关推荐

About Hooks and Filters

嗯,我很难理解动作和过滤器之间的区别。我确实在代码中使用动作,但我是一个新手,甚至连一点过滤器都不知道。我去过codex,以及NickTheGeek、BillErickson、GaryJones等的多个网站,但没有去过vein。如果你能用简单的话告诉我,并举例说明动作、过滤器和挂钩的基本内容和区别。非常感谢。