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

标签 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()

语境

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

例如这将是“classfile.php”;
namespace BnfoAutoload\Includes\

class LoadClass {

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

    public function loadFunction() {
        // something
    }

}

new LoadClass();

潜在解决方案

选项 1:我可以在我的插件文件中手动 require classfile.php,然后静态实例化该类。
require_once ('classfile.php' );

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

我不确定这些是否正确,因此非常感谢任何其他想法。

最佳答案

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

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

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

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

当 WordPress 到达事件驱动堆栈中的“init”操作时,它会创建内存对象“someClass”并将其传递给 init 钩子(Hook)。传递的东西是实例化的对象。 [当然,将指针传递给静态方法可能是一种设计功能,这不是 WordPress 的工作方式]。

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

**** 编辑 ****
好的,所以我仍然说你永远不应该在 WordPress 中使用静态,因为它们很难测试。但是,您可以通过将 Action 调用放在这样的类中来调用静态方法,来自 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();

关于php - 在 PHP 中自动加载静态实例化的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113497/

相关文章:

c# - 名称 'image' 在当前上下文中不存在

php - 写入文本文件不适用于单击的第一个项目

javascript - 上传文件的同时您继续与网站交互

PHP 和 MySQL 为同一日期提供两个不同的周数

php - 黑色菱形/问号替换 WordPress 中的随机字符

ruby-on-rails - rails 3 使用文件夹名称作为 namspace 引发未初始化的常量错误

php - 大型 .zip 文件下载不完整

git - svn: E000002: 提交失败

javascript - 什么是 google bot guard 反垃圾邮件?

c++ - 隐式 “using namespace std” 没有写在源代码中