WordPress PSR-4 Namespaced插件访问另一个Namespaced插件

时间:2015-09-05 02:34:04

标签: php wordpress plugins namespaces

很快,我正在尝试使用WordPress建立一个'生态系统',我有一个核心插件,然后是额外的附加插件。

更深入的是,每个附加插件都需要核心插件才能运行。我已经使用WordPress标准编码和文件结构实践实现了这一目标。我正在重新设计这个项目,现在使用Namespacing PSR-4,作曲家,凉亭等。

标准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

核心插件psr4通过composer

"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.
    }

}

第一个附加插件psr4通过composer

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

加载项插件中的类

以下是我感到困惑的地方。我正在尝试在不同的命名空间中使用核心插件中的类,我收到错误:

  

致命错误:未在...中找到类'CorePlugin \ Library \ Post_Register'

两个插件都自动加载他们各自的编辑器生成自动加载文件,所以我虽然能够use命名空间。在我深入研究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中,use foo \ bar;和use bar \ foo;像这样。

<?php namespace App\Services;

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

class Registrar implements RegistrarContract {

1 个答案:

答案 0 :(得分: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

这一切都很有效。

希望能有所帮助。