Reduzierung der Verwendung von globalem $ post


7

Beim Erstellen von Meta-Boxen scheint in jeder Meta-Box-Funktion ein Verweis auf die global $postals Parameter übergeben zu werden ($event). Ich bevorzuge dies, da es konsistent erscheint und weniger wahrscheinlich ist, die $postVar zu verfälschen, indem es explizit deklariert wird, wie ich es an anderer Stelle gelesen habe.

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
}

Ich habe einen Filter und verschiedene andere Funktionen erstellt, die derzeit nur die global $postVariable verwenden.

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

Gibt es eine Standard- / empfohlene Möglichkeit, die global $postVariable als Parameter an diese Funktionen zu übergeben?

Antworten:


8

Wenn ich mich mit $postVariablen in admin befassen muss , verwende ich normalerweise eine Klasse, um globale $postVariablen frühzeitig abzufangen und zu verpacken und eine universelle Möglichkeit zu erhalten, auf sie zuzugreifen, ohne sich wiederholt auf die globale Variable zu verlassen.

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

Am frühen Stadium des Admin - Ladens, das ist 'admin_init'Haken, 'MyAdminPost'Klasse sieht für die Zeit nach ID - Variable gesendet mit Anfrage und Shop an Post - Objekt.

Das funktioniert auf post.phpSeite, aber nicht auf post-new.php, da auf dieser Seite die Post-ID nicht mit Anfrage gesendet wird, da sie noch nicht existiert. In diesem Fall füge ich einen Rückruf hinzu 'new_to_auto-draft', der den "{old_status}_to_{new_status}"Haken zum Speichern des Beitrags unmittelbar nach dem Erstellen auf der post-new.phpSeite darstellt.

Auf diese Weise wird das Post-Objekt auf beiden Seiten sehr früh in einer Klasseneigenschaft gespeichert.

Anwendungsbeispiel (Verfahren)

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

Anwendungsbeispiel (OOP)

class ClassThatUsesPostObject
{

  private $post_provider;

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

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

Leistungen

  • Sie können Post-Objekte sehr früh auf eine Weise abrufen, die sowohl mit post.phpals auch mit post-new.phpSeiten kompatibel ist. In allen Hooks, die auf diesen Seiten ausgelöst werden, können Sie also mühelos auf Post-Objekte zugreifen

  • Sie entfernen alle globalen $postVariablenreferenzen in Ihrem Code

  • Ihr Code wird isoliert getestet


Der Verfahrens- und OOP-Code waren sehr hilfreich, danke. +1
Myol

1
@ MarkKaplun Nicht einverstanden. Diese Klassenverantwortung lautet: "Geben Sie das Post-Objekt der zugehörigen Admin- Post-Seite an, auf der ich mich befinde ". Auf der Admin-Post-Seite wird nur ein Post bearbeitet : Sie können viele Posts bearbeiten. Auf der Admin-Post-Seite ist diese Klasse jedoch perfekt, wenn Sie wissen möchten, welchen Post Sie bearbeiten. Wenn ein Code den globalen Beitrag auf der Seite des Administratorbeitrags ändert, ohne die Seite umzuleiten oder ohne ihn nach einem vorübergehenden Wechsel (aus irgendeinem Grund) wiederherzustellen, ist dieser Code ein Fehler. Selbst während des vorübergehenden Schaltens ist der Unterricht nützlich, wenn Sie den Beitrag kennen möchten, auf dessen Bearbeitungsseite Sie sich befinden.
gmazzap

1
@MarkKaplun Denken Sie zum Vergleich im Frontend an eine Seitenvorlage, mit der eine sekundäre Schleife angezeigt wird. Während dieser Schleife bezieht sich globaler Beitrag auf jeden Beitrag in der Schleife. Fein. Aber wenn Sie vor, während oder nach dieser sekundären Schleife das Seitenobjekt der Seite benötigen, in der Sie sich befinden? Da ist get_queried_object()das praktisch. Es ist auch in admin verfügbar, funktioniert jedoch nicht für neue Postseiten und ist erst nach der Abfrage verfügbar. Diese Klasse füllt die Lücke.
gmazzap

1
@MarkKaplun Wenn ich dich oder jemanden erwische, der Globals im laufenden Betrieb modifiziert, werde ich den Verantwortlichen persönlich genau dort erschießen, wo er steht.
Kaiser

1
Denn so $_REQUESTfunktioniert es. Versuchen Sie, 2 Werte für dieselbe Variable zu senden, aber einen an $_GETund einen an $_POST. Wenn Sie den Wert mit $_REQUESTdem Wert auf $_GET gewinnt . @kaiser
gmazzap

1

Sie können die mit einem vorhandenen Filter / einer Aktion verwendeten Parameter nicht einfach ändern, da sie durch den "aufrufenden" Code festgelegt werden. Daher können Sie keine zusätzlichen Parameter einfügen. Möglicherweise besteht die Möglichkeit, dies zu tun, indem Sie den Kerncode hinter do_action / apply_filter hacken. Wenn Sie jedoch erfolgreich sind, wird höchstwahrscheinlich der gesamte andere Code beschädigt, der diese Aktionen / Filter verknüpft.


1

admin_head-{$hook_suffix}wird auf jeder Administrationsseite ausgelöst, daher wäre es wahrscheinlich nicht sinnvoll, etwas an diese Funktion zu übergeben. Sie können in der Quelle sehen, dass keine Argumente übergeben werden:

do_action( "admin_head-$hook_suffix" );

In vielen Fällen haben Sie keine Alternative zu global $postund wenn Sie fast jede Kernquelldatei durchsehen, werden Sie globalüberall Müll sehen , da der Kern größtenteils prozedural aufgebaut ist und das Hauptziel darin besteht, die Abwärtskompatibilität aufrechtzuerhalten. Es ist chaotisch, aber meistens harmlos, wenn Sie nur in einem bekannten Kontext auf seinen Wert zugreifen .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.