【问题标题】:Autoload statically instantiated classes in PHP在 PHP 中自动加载静态实例化的类
【发布时间】:2018-06-15 06:14:03
【问题描述】:

我一直在学习我最新的 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()

上下文

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

例如这将是“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();

我不确定其中任何一个是否正确,因此非常感谢任何替代想法。

【问题讨论】:

  • 有什么东西阻止你使用 composer?
  • 可能没有,但我之前没有使用过composer,我还没准备好开始。
  • 好吧,那就用spl_autoload_register吧。
  • @chay22。我目前正在使用 spl_autoload_register。我已经更新了我的例子来展示它。我遇到的问题不是自动加载,而是自动加载静态实例化的类。谢谢

标签: php wordpress namespaces autoload


【解决方案1】:

你有点搞糊涂了。您不能实例化静态类,只能使用静态方法或属性。 实例化它,意味着它不是静态的。

无论如何,PHP 中的静态方法是一种设计味道。现在让我在这里提出一个警告,它们并不是没用的。如果你举手说: “我需要一个共享全局系统状态的全局命名空间函数”,[即您的类旨在供全局空间中的其他插件使用]然后静态OOP方法是要走的路。如果您不明白为什么需要全局命名空间函数,尤其是为什么您不想在 WordPress 中使用它,请听取经验丰富的编码人员的建议,并且不要在 PHP 中使用静态方法 - 特别是在 WORDPRESS 中!强>

现在对于 WordPress,您特别不能以这种方式使用静态类。考虑在这种情况下发生了什么:

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

当 WordPress 在事件驱动堆栈中执行“init”操作时,它会创建内存对象“someClass”并将其传递给 init 挂钩。传递的东西是实体化的对象。 [当然,将指针传递给静态方法可能是一项设计功能,但这不是 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();

【讨论】:

  • 谢谢约翰。我所说的“静态类”不是指插件加载时我想加载的单实例类。但我在其他地方找到了我的答案。不过,这是非常有用的指导——我是在自学,所以像这样的 cmets 可以帮助我回到正轨!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 2015-04-16
  • 1970-01-01
  • 2013-04-12
  • 2021-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多