问题描述

当创建元框时,在每个元框功能中,似乎引用 global $post 作为参数传递为 ($event)。我喜欢这个,因为它似乎是一致的,并且不太可能用 $post 变量来声明它,因为我在其他地方已经明确地声明了这一点。

add_action('admin_init', 'events_admin');
function events_admin()
{
     add_meta_box('display_events_date_meta_box',
        'Dates',
        'display_events_date_meta_box',
        'events', 'normal', 'high'
    );

}

function display_events_date_meta_box($event) // Referenced
{
     //$event in this case is the $post global
}

我已经创建了一个过滤器和各种其他功能,目前只使用 global $post 变量。

add_action( 'admin_head-post-new.php', 'test' );
add_action( 'admin_head-post.php', 'test' );
function test()
{
    global $post; // Declared explicitly
}

有没有一个标准/推荐的方式来传递 global $post 变量作为这些功能的参数?

最佳解决方案

当我需要在管理员处理 $post 变量时,我通常使用一个类来早期捕获并包装全局 $post 变量,获得通用的方式来访问它,而不用重复依赖于全局变量。

class MyAdminPost
{

   private static $post;

   public static function init()
   {
     $p_get = filter_input(INPUT_GET, 'post', FILTER_SANITIZE_NUMBER_INT);
     $p_post = filter_input(INPUT_POST, 'post', FILTER_SANITIZE_NUMBER_INT);
     if ($p_get > 0 || $p_post > 0) {
       self::$post = $p_get > 0 ? get_post($p_get) : get_post($p_post);
     } elseif ($GLOBALS['pagenow'] === 'post-new.php') {
       add_action('new_to_auto-draft', function(WP_Post $post) {
         if (is_null(MyAdminPost::$post)) {
           MyAdminPost::$post = $post;
         }
       }, 0);
     }
   }

   public function get()
   {
     return self::$post;
   }
}

add_action('admin_init', array('MyAdminPost', 'init'));

在管理员加载的早期阶段,即'admin_init'钩子,'MyAdminPost'类查找发送与请求和存储相关的后期对象的帖子 ID 变量。

这在 post.php 页面上工作,但不是在 post-new.php 上,因为在该页面上,由于它还没有发送请求,因此不发送请求。在这种情况下,我向'new_to_auto-draft'添加回调,'new_to_auto-draft'"{old_status}_to_{new_status}"钩子,用于在 post-new.php 页面创建后立即存储该帖子。

这样,在两个页面中,post 对象很早就存储在一个类属性中。

使用示例 (程序)

function get_my_admin_post()
{
   static $post = null;
   if (is_null($post) && did_action('admin_init')) {
     $map = new MyAdminPost();
     $post = $map->get();
   }

   return $post;
}

add_action('admin_head-post.php', 'test');

function test()
{
    $post = get_my_admin_post();
}

使用示例 (OOP)

class ClassThatUsesPostObject
{

  private $post_provider;

  function __construct(MyAdminPost $map)
  {
     $this->post_provider = $map;
  }

  function doSomethingWithPost()
  {
    $post = $this->post_provider->get();
  }
}

Benefits

  • 您可以以兼容 post.phppost-new.php 页面的方式获得 Post 对象,所以在所有这些页面中的所有钩子都可以无缝地访问 post 对象

  • 您删除代码中的任何全局 $post 变量引用

  • 您的代码可以孤立地进行测试

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。