ssnepenthe/metis

Pimple,适用于WordPress的一些实用调整

0.7.0 2017-10-19 01:59 UTC

This package is auto-updated.

Last update: 2024-09-09 14:15:30 UTC


README

Pimple,适用于WordPress的一些实用调整。

要求

PHP 5.3 或更高版本以及Composer。

注意:Metis 应继续在 5.3 以下工作,但不再在 5.4 以下进行测试。

安装

$ composer require ssnepenthe/metis

用法

这基本上是 Pimple,但您将使用 Metis\Container 而不是 Pimple\Container

已添加以下功能

在您的服务提供程序中处理激活和停用逻辑

class Some_Provider implements Pimple\ServiceProviderInterface {
    public function activate( Pimple\Container $container ) {
        // Handle activation here.
    }

    public function deactivate( Pimple\Container $container ) {
        // Handle deactivation here.
    }

    // ...
}

然后调用您的容器实例上的相应方法。

$container = new Metis\Container;
$container->register( new Some_Provider );

register_activation_hook( __FILE__, array( $container, 'activate' ) );
register_deactivation_hook( __FILE__, array( $container, 'deactivate' ) );

在您的服务提供程序中处理引导逻辑(add_action/add_filter 调用)

class Another_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'init', array( $container['service'], 'init' ) );
    }

    // ...
}

然后调用您的容器实例上的相应方法。

$container = new Metis\Container;
$container->register( new Another_Provider );

add_action( 'plugins_loaded', array( $container, 'boot' ) );

服务代理

Pimple 等依赖注入容器的一个好处是,对象在您访问它们的容器条目时按需创建。

这特别适用于只需要有限请求的功能(例如,管理员、cron 等)。

不幸的是,这并不总是在 WordPress 中按您期望的方式工作

class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', array( $container['admin_page'], 'do_something' ) );
    }

    // ...
}

由于 boot() 方法通常附加到 plugins_loaded 钩子,因此无论是否触发了 admin_init,管理员页面对象总会被创建。

一个合理的方法是在调用 add_action() 之前验证当前请求是否为管理员页面

class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        if ( is_admin() ) {
            add_action( 'admin_init', array( $container['admin_page'], 'do_something' ) );
        }
    }

    // ...
}

但这会导致引导方法中充斥着条件语句。

另一种方法是使用匿名函数访问 admin_page 条目

class Admin_Provider implements Pimple\ServiceProviderInterface {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', function() use ( $container ) {
            $container['admin_page']->do_something();
        }
    }

    // ...
}

但这很快就会变得繁琐,并可能导致大量不必要的 Closure 对象四处飘浮。

因此,您可以选择扩展 Metis\Base_Provider 并使用 proxy() 方法

class Admin_Provider extends Metis\Base_Provider {
    public function boot( Pimple\Container $container ) {
        add_action( 'admin_init', array( $this->proxy( $container, 'admin_page' ), 'do_something' ) );
    }

    // ...
}

这将创建一个用于替代管理员页面对象的 Metis\Proxy 对象。该对象将正确代理所有方法调用到容器中的底层服务,同时延迟创建该服务,直到真正需要它。

从容器访问 WordPress 全局变量

使用 WordPress_Provider 类从容器中获取常用 WordPress 全局变量的访问权限。

$container = new Metis\Container;
$container->register( new Metis\WordPress_Provider );

$container['wp'] === $GLOBALS['wp']; // true

$wp$wpdb$wp_query$wp_rewrite$wp_filesystem$wp_object_cache 都已添加到容器中。

在使用这些时要小心时间 - 如果尚未定义,每个都将返回 null。