使用全局变量或返回所述变量的函数进行站点范围的私有可湿性粉剂设置?

时间:2016-11-11 作者:Alex Protopopescu

我有很多函数扩展各种插件并为站点提供逻辑,这些函数使用不同的信息位,我想将这些信息保存在一个地方并访问它,但对使用全局变量感到不舒服,因为我担心由于代码中的漏洞,它们可能会被复制,或者更糟,在全局范围内被覆盖,然后传递给函数。然后我再次认为这有点荒谬,因为如果我的代码有这种漏洞,那么它无论如何都会被破坏——但我确实觉得,在我出错的地方显示一个全局变量而不是预期的变量,仍然比能够调用函数更有可能。

其中一些信息是WP加载的资源名称和路径,其他信息ID和重定向页面的路径。

我在想$settings = array(\'some\'=>\'settings\',\'go\'=>\'here\'); 然后调用varglobal $settings; 进入局部范围。

改为使用:function my_settings(){ return array(\'some\'=>\'settings\',\'go\'=>\'here\'); } 并将此函数调用到$settings = my_settings() 在全局范围之外,进入我需要的任何函数或类,但决不在全局范围内。

总之,这个想法有什么优点,而不是使用globals吗?随着性能的提高,不会因为调用一个或多个函数而降低性能。但是,从安全角度来看,有什么优势吗?

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

除了避免碰撞和防止意外修改之外,没有压倒一切的好处。

不确定这是否会让您感觉更好,但WP core本身对全局变量有很多依赖性。我并不是说这是件好事;这只是事实。

还请记住,您有一个数据库和函数来处理存储和检索选项,这些选项用于您可能希望在不同情况下使用的值:

https://developer.wordpress.org/reference/functions/update_option/

https://developer.wordpress.org/reference/functions/get_option/

SO网友:jgraup

魔术方法创建全局变量而不污染全局空间的最简单方法是利用Singleton 图案Essential仅实例化一次并通过单个静态函数访问的类。

在这种情况下,你可以getterssetters 存储和检索值,但我们可以利用PHP的神奇方法。现在,您可以从任何地方访问该类(只要已加载),并使用任何值保存任何属性。

基本语法是<class>::<singleton>()-><property>

在访问这个类之前,只需加载它一次。

if ( ! class_exists( \'CustomSettingClass\' ) ) {

    class CustomSettingClass {

        private        $s = array ();
        private static $_instance;

        public static function instance() {
            if ( ! static::$_instance ) {
                static::$_instance = new self();
            }

            return static::$_instance;
        }

        // setter
        function __set( $k, $c ) {
            $this->s[ $k ] = $c;
        }

        // getter
        function __get( $k ) {
            return isset( $this->s[ $k ] ) ? $this->s[ $k ] : null;
        }

        // callable
        function __call( $method, $args ) {
            if ( isset( $this->s[ $method ] ) && is_callable( $this->s[ $method ] ) ) {
                return call_user_func_array( $this->s[ $method ], $args );
            } else {
                echo "unknown method " . $method;

                return false;
            }
        }
    }
}
然后只需访问singleton 来自static 访问者。

CustomSettingClass::instance()->foo = \'bar\';

echo CustomSettingClass::instance()->foo; // bar

CustomSettingClass::instance()->complex = array(1,2,3);

print_r( CustomSettingClass::instance()->complex ); // 1,2,3
至于安全性,您可以使用相同的方法magic methods 对安全函数使用私有方法。基本的OOP真的。

还值得注意的是,通过添加__call 神奇的方法,我们可以解析匿名函数。

// create handler
CustomSettingClass::instance()->callback = function($value){ echo $value; };

// add listener
add_action( \'test\', array(CustomSettingClass::instance(), \'callback\'));

// do action
do_action (\'test\', \'some value\'); // some value
现在,您有了一个完全动态且可自定义的对象,其行为就像$global, 可随时调整,并可处理actionsfilters.

简化了静态类函数,所以神奇的方法是过度杀戮而非私有的。那么,一个具有私有内部结构和面向外部的设置getter的静态类怎么样。你只需要在公众面前尽可能多地曝光StaticSettings::settings() 作用

if ( ! class_exists( \'StaticSettings\' ) ) {

    class StaticSettings {

        private static $_location = \'here\';

        public static function settings() {

            return array (
                    \'some\' => \'settings\',
                    \'go\'   => static::$_location,
            );
        }
    }
}

$settings = StaticSettings::settings();
我想说的是,最好的选择是在函数路径中使用静态变量。这实例化了$settings 对象为null 可以触发初始化。在这一点上,它们基本上是缓存的。因此,对该函数的每一次调用都会返回一个已构造的对象。所有内部工作对函数本身都是私有的。

function my_settings() {

    static $settings = null;

    if ( null === $settings ) {

        // initialize settings object once

        $settings = array (
                \'some\' => \'setting\',
                \'go\'   => \'here\',
        );
    }

    // return cached value

    return $settings;
}