Giảm việc sử dụng bài đăng toàn cầu $


7

Khi tạo các hộp meta, trong mỗi chức năng của hộp meta, có vẻ như một tham chiếu đến global $postđược truyền dưới dạng tham số ($event). Tôi thích điều này vì nó có vẻ phù hợp và ít có khả năng làm mờ $postvar bằng cách tuyên bố nó rõ ràng như tôi đã đọc ở nơi khác.

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
}

Tôi đã tạo một bộ lọc và nhiều chức năng khác hiện đang sử dụng global $postbiến.

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

Có một cách tiêu chuẩn / được đề xuất để truyền global $postbiến như một tham số cho các hàm này không?

Câu trả lời:


8

Khi tôi cần xử lý $postbiến trên quản trị viên, tôi thường sử dụng một lớp để sớm nắm bắt và bao bọc $postbiến toàn cục, có được một cách phổ biến để truy cập vào nó, mà không phụ thuộc vào biến toàn cục.

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'));

Trong giai đoạn đầu tải quản trị, đó là 'admin_init'hook, 'MyAdminPost'lớp tìm kiếm biến ID bài được gửi với yêu cầu và lưu trữ đối tượng bài liên quan.

Điều đó hoạt động trên post.phptrang, nhưng không phải trên post-new.php, bởi vì trên trang đó ID bài đăng không được gửi với yêu cầu vì nó chưa tồn tại. Trong trường hợp đó, tôi thêm một cuộc gọi lại vào 'new_to_auto-draft'đó là một cái "{old_status}_to_{new_status}"móc để lưu bài viết ngay sau khi nó được tạo trên post-new.phptrang.

Theo cách này, trong cả hai trang, đối tượng bài được lưu trữ trong một thuộc tính lớp từ rất sớm.

Ví dụ sử dụng (Thủ tục)

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();
}

Ví dụ sử dụng (OOP)

class ClassThatUsesPostObject
{

  private $post_provider;

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

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

Những lợi ích

  • bạn có thể có được đối tượng bài đăng từ rất sớm theo cách tương thích với cả hai trang post.phppost-new.phpdo đó, trong tất cả các móc nối được bắn trong các trang đó bạn có quyền truy cập để đăng đối tượng mà không cần nỗ lực

  • bạn xóa bất kỳ $posttham chiếu biến toàn cục nào trong mã của bạn

  • mã của bạn trở nên có thể kiểm tra được


Mã thủ tục và OOP rất hữu ích, thankyou. +1
myol

1
@MarkKaplun Không đồng ý. Trách nhiệm lớp này là: "Cung cấp cho đối tượng bài đăng của trang bài đăng quản trị liên quan tôi đang ở". Trong trang bài đăng của quản trị viên, chỉ có một bài đăng đang được chỉnh sửa : bạn có thể thao tác rất nhiều bài đăng, nhưng trong trang đăng bài của quản trị viên nếu bạn muốn biết bài đăng nào bạn đang chỉnh sửa thì lớp này là hoàn hảo. Ngoài ra, nếu một số mã thay đổi bài đăng toàn cầu trong trang bài đăng của quản trị viên, trang sẽ chuyển hướng hoặc không khôi phục nó sau khi chuyển đổi tạm thời (vì bất kỳ lý do nào) thì mã đó là một lỗi. Ngay cả trong quá trình chuyển đổi tạm thời, lớp vẫn hữu ích nếu bạn muốn biết bài đăng có trang chỉnh sửa của mình.
gmazzap

1
@MarkKaplun Để so sánh, hãy suy nghĩ trước một mẫu trang được sử dụng để hiển thị một vòng lặp thứ cấp. Trong vòng lặp đó, bài đăng toàn cầu đề cập đến mọi bài đăng trong vòng lặp. Khỏe. Nhưng nếu trước, trong hoặc sau vòng lặp thứ cấp đó, bạn cần đối tượng trang của trang bạn đang ở? Đó là get_queried_object()tiện dụng. Nó cũng có sẵn trong quản trị viên, nhưng không hoạt động cho trang bài đăng mới và chỉ khả dụng sau khi truy vấn. Lớp này lấp đầy khoảng trống.
gmazzap

1
@MarkKaplun Nếu tôi bắt bạn hoặc bất kỳ ai khác sửa đổi toàn cầu một cách nhanh chóng, tôi sẽ đích thân bắn người chịu trách nhiệm chính xác nơi anh ta đứng.
kaiser

1
Bởi vì cách làm $_REQUESTviệc. Cố gắng gửi 2 giá trị cho cùng một biến, nhưng một trên $_GETvà một trên $_POST. Nếu bạn nhận được giá trị với $_REQUESTgiá trị trên $_GET chiến thắng . @kaiser
gmazzap

1

Bạn không thể dễ dàng sửa đổi các tham số được sử dụng với bộ lọc / hành động hiện có vì chúng được đặt bởi mã "gọi", do đó bạn không thể thêm các tham số bổ sung. Có thể có một số khả năng để làm điều đó bằng cách hack mã lõi đằng sau do_action / application_filter nhưng nếu bạn thành công, rất có thể bạn sẽ phá vỡ tất cả các mã khác móc vào các hành động / bộ lọc đó.


1

admin_head-{$hook_suffix}được kích hoạt trên mọi trang quản trị, do đó, chuyển bất kỳ thứ gì vào chức năng đó có thể sẽ không có ý nghĩa. Bạn có thể thấy trong nguồn không có đối số nào được thông qua:

do_action( "admin_head-$hook_suffix" );

Trong nhiều trường hợp, bạn không có lựa chọn nào khác global $postvà nếu bạn xem qua bất kỳ tệp nguồn lõi nào, bạn sẽ thấy globalxả rác ở mọi nơi, do việc xây dựng lõi chủ yếu theo thủ tục và mục tiêu chính là duy trì khả năng tương thích ngược. Nó lộn xộn nhưng hầu như vô hại nếu bạn chỉ truy cập giá trị của nó trong một bối cảnh đã biết .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.