在PHP中自动加载静态实例化的类

时间:2018-01-05 12:17:40

标签: php wordpress namespaces autoload

我一直在学习最新的Wordpress插件的命名空间和自动加载。

如果可以使用自动加载器静态实例化类,我遇到了一个问题。

到目前为止我做了什么

我已将此自动加载器添加到我的插件文件中:

spl_autoload_register( 'bnfoAutoload' );

function bnfoAutoload( $class ) {

    // project-specific namespace prefix
    $prefix = 'BnfoAutoload\\';

    // base directory for the namespace prefix
    $base_dir = __DIR__ . '/';

    // does the class use the namespace prefix?
    $len = strlen( $prefix );
    if ( strncmp( $prefix, $class, $len ) !== 0 ) {
        // no, move to the next registered autoloader
        return;
    }

    // get the relative class name
    $relative_class = substr( $class, $len );

    // replace the namespace prefix with the base directory, replace namespace
    // separators with directory separators in the relative class name, append
    // with .php
    $file = $base_dir . str_replace( '\\', '/', $relative_class ) . '.php';

    // if the file exists, require it
    if ( file_exists( $file ) ) {
        require $file;
    }

}

我已经有了自动加载功能,可以有效地为的新实例化实例工作,例如:

$response = new BnfoAutoload\Includes\Tester();

$exact_response = $response->testFunction();

并在调用静态方法时通过阅读this SO post,例如

BnfoAutoload\Includes\Tester::testStaticFunction()

上下文

但是,偶尔我想静态实例化一个类,例如,如果我想添加一个过滤器。

e.g。这将是' classfile.php';

namespace BnfoAutoload\Includes\

class LoadClass {

    public function __construct() {
        add_action( 'wp_head', [ $this, 'loadFunction' ];
    }

    public function loadFunction() {
        // something
    }

}

new LoadClass();

潜在解决方案

选项1:我可以在我的插件文件中手动要求classfile.php,然后静态实例化该类。

require_once ('classfile.php' );

选项2:我可以在插件文件中实例化这些静态类,此时它们会被自动加载器拾取

new BnfoAutoload\Includes\LoadClass();

我不确定其中任何一个是否正确,所以任何其他想法都非常赞赏。

1 个答案:

答案 0 :(得分:1)

你有点困惑自己。您无法实例化静态类,只能使用静态方法或属性。要实例化它,意味着它不是静态的。

在任何情况下,PHP中的静态方法都是一种设计气味。现在让我在这里发现一个问题,它们并非毫无用处。如果你举手说: “我需要一个全局命名空间的功能,它共享一个全局系统状态”,[即您的类被设计为由全局空间中的OTHER插件使用]然后静态OOP方法即可。如果你不明白为什么你需要一个全局命名空间的函数,特别是为什么你想在WordPress中想要它,请听取有经验的编码器的建议,不要在PHP中使用静态方法 - 特别是在WORDPRESS!

现在对于WordPress,你特意不能以这种方式使用静态类。考虑一下这种情况下发生的事情:

add_action('init', array(new someClass, 'someMethod'));

当WordPress在事件驱动的堆栈中进入“init”操作时,它会创建内存对象“someClass”并将其传递给init钩子。传递的东西是instatiated对象。 [当然它可能是一个设计功能,将指针传递给静态方法,而不是WordPress如何工作]。

无论如何,总而言之,永远不要在WordPress中使用静态方法。 WordPress使用全局变量,因为它是遗留应用程序。不要让它变得更糟。

****编辑**** 好吧,所以我仍然说你不应该在WordPress中使用静态因为它们很难测试。但是,您可以通过将动作调用放在类developer.wordpress.org

中来调用静态方法
/**
 * Class WP_Docs_Static_Class.
 */
class WP_Docs_Static_Class {

    /**
     * Initializer for setting up action handler
     */
    public static function init() {
        add_action( 'save_post', array( get_called_class(), 'wpdocs_save_posts' ) );
    }

    /**
     * Handler for saving post data.
     */
    public static function wpdocs_save_posts() {
        // do stuff here...
    }
}

WP_Docs_Static_Class::init();