WordPress PSR-4命名空间插件访问另一个命名空间插件

5

简单来说,我正在尝试使用WordPress构建一个“生态系统”,其中包括一个核心插件和其他附加插件。

更深入地说,每个附加插件都需要核心插件才能正常运行。我已经使用WordPress标准编码和文件结构实践来实现这一点。现在,我正在重新设计这个项目,使用命名空间PSR-4、composer、bower等工具。

标准WordPress安装

|
|__www
  |
  |___wp-admin
  |
  |___wp-content
  |   | 
  |   |___plugins
  |   |   |
  |   |   |___my-core-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |    |
  |   |   |   |    |___class-post-register.php
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |   |___my-first-addon-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |   |___my-second-addon-plugin
  |   |   |   |
  |   |   |   |___library
  |   |   |   |
  |   |   |   |___vendor
  |   |   |   |    |
  |   |   |   |    |___autoload.php
  |   |   |   |
  |   |   |   |___composer.json
  |   |   |   |
  |   |   |   |___core.php
  |   |   |
  |   |___themes
  |   |   |   
  |   |   |___my-custom-theme
  |   |
  |   wp-includes

通过composer使用核心插件psr4

"autoload": {
    "psr-4": {
        "CorePlugin\\Library\\": "library"
    }
}

示例核心插件类

<?php 

namespace CorePlugin\library;

class Post_Register {

    private __construct() {
        // ... code
     }

    private init() {

    }

    private register( $data ) {
        // .. code to register a custom post for example.
    }

}

首先通过composer添加psr4插件

"autoload": {
    "psr-4": {
        "FirstAddon\\Library\\": "library"
    }
}

来自插件的类

以下是我困惑的地方。我尝试在不同的命名空间中使用核心插件中的一个类,结果出现了以下错误:

致命错误:未找到“CorePlugin\Library\Post_Register”类...

这两个插件都自动加载其各自生成的Composer自动加载文件,因此我认为我应该能够使用命名空间。在深入研究PHP手册的这一部分之前,我来这里询问一下 (http://php.net/manual/en/language.namespaces.php) ,也许我会尝试子命名空间。

<?php 

namespace FirstAddon;

use CorePlugin\Library\Post_Register;

class First_Addon {

    private __construct() {
        // ... code
     }

    private init() {

    }

    private another_function() {

    }

}

此外,我不确定是否应该使用带括号的子命名空间,例如在 Laravel 中:usefoo\bar; 和 usebar\foo;。
<?php namespace App\Services;

use App\User;
use Validator;
use Illuminate\Contracts\Auth\Registrar as RegistrarContract;

class Registrar implements RegistrarContract {
1个回答

0

我知道你可能已经解决了这个问题,但是我还是想回答一下,以防其他人尝试让插件相互依赖。我在我的插件中使用类和命名空间。我的插件重用彼此的类。

命名空间插件

首先,基本上这归结为 Wordpress 加载插件的顺序。我自己来自 C#/Java,最初对 WP 的做法感到困惑。您需要确保要使用的插件已经加载。最好的方法是通过一个后期钩子来实例化类 - 一个您知道在插件加载后发生的钩子。例如:

add_action('plugins_loaded', function () { new whatever() });

然后让构造函数在其他插件(或任何需要它的地方)中使用该类:

function __construct() {
  $other_plugin_class = new \Namespace\To\Other\Plugin\MyClass();
}

依赖关系

如果插件之间存在依赖关系,并且需要根据启用的插件和未启用的插件来执行不同的操作,可以这样做:

if ( ! function_exists( 'is_plugin_active' ) )
  require_once( ABSPATH . '/wp-admin/includes/plugin.php' );

if ( is_admin() and is_plugin_active('myplugin1/plugin1.php') ) {
  add_action( 'admin_menu', array( $this, 'add_a_menu_depending_on_another_plugin' ), 99 );
}

首先,它确保所需的函数已加载,然后检查相关插件是否已启用。

自动加载器

值得一提的是,我使用内置的自动加载器:

spl_autoload_register( 'my_autoloader' );
function my_autoloader( $class_name ) {
  if ( false !== strpos( $class_name, 'Nuvobook' ) ) {
    $classes_dir = plugin_dir_path( __DIR__ );
    $class_file = strtolower(str_replace( '_', '-', str_replace( '\\', DIRECTORY_SEPARATOR, $class_name ) ) . '.php');
    include_once $classes_dir . $class_file;
  }
}

将我的类命名规则My_Class映射到文件名my-class.php

一切都运行得很好。

希望这可以帮助某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接