วิธีที่ดีที่สุดในการส่งตัวแปร PHP ระหว่างงาน Partials?


16

ฉันมีตัวแปรใน header.php เช่น:

$page_extra_title = get_post_meta($this_page->ID, "_theme_extra_title", true);

เมื่อฉันทำ:

var_dump($page_extra_title);

ฉันNULLออกไปข้างนอก header.php เสมอ(var_dump ทำงานอย่างถูกต้องใน header.php เท่านั้น) ฉันได้วางตัวแปรเดียวกันทุกที่ที่ฉันต้องการ (page.php, post.php, footer.php ฯลฯ ) แต่มันบ้าและทำให้ทุกอย่างแทบเป็นไปไม่ได้ที่จะรักษา

ฉันสงสัยว่าอะไรคือวิธีที่ดีที่สุดในการส่งตัวแปรผ่านไฟล์ทั้งหมดในธีมของฉัน ฉันเดาว่าใช้ functions.php พร้อมกับ "get_post_meta" อาจไม่ใช่ความคิดที่ดีที่สุด? :)



ฉันคิดว่าตัวแปรอยู่ในขอบเขตเดียวกันฉันต้องการหลีกเลี่ยงการใช้ GLOBAL ด้วยเหตุผลที่ชัดเจน
Wordpressor

ฉันเชื่อว่าความคิดเห็นของ ialocin เป็นจุดบน สคริปต์ PHP หนึ่งไม่รู้ว่ามีตัวอื่นอยู่และไม่สามารถเข้าถึงตัวแปรในตัวเครื่องหรือค่าของมันได้
jdm2112

1
ส่วนหัวและส่วนท้ายถูกรวมผ่านฟังก์ชั่นดังนั้นขอบเขตของทุกสิ่งในไฟล์เหล่านั้นคือขอบเขตของฟังก์ชันเหล่านั้น
Milo

4
อย่ายิงผู้ส่งสาร :) สิ่งเดียวที่ฉันพูดคือมันเป็นปัญหาของขอบเขตแน่นอน มีวิธีมันglobalใช่ไหม? แต่มันเป็นไปไม่ได้ด้วยเหตุผลที่ดี นอกจากนี้คุณยังต้อง "เรียกใช้" globalด้วยเช่นกันโดยใช้คำหลักเพื่อให้พร้อมใช้งาน ขึ้นอยู่กับช่วงเวลาการใช้งานอาจเป็นวิธีแก้ปัญหา เป็นอย่างอื่น - ดังที่กล่าวไว้ - ฉันคิดว่าฟังก์ชั่นหรือชั้นเรียนที่จะทำงานให้คุณเป็นวิธีที่จะไป
Nicolai

คำตอบ:


10

โครงสร้างข้อมูลแบบแยกพื้นฐาน

ในการส่งผ่านข้อมูลคุณมักจะใช้โมเดล (นั่นคือ "M" ใน "MVC") ลองดูอินเทอร์เฟซที่ง่ายมากสำหรับข้อมูล อินเทอร์เฟซใช้เป็น "สูตรอาหาร" สำหรับหน่วยการสร้างของเรา:

namespace WeCodeMore\Package\Models;
interface ArgsInterface
{
    public function getID();
    public function getLabel();
}

ข้างต้นคือสิ่งที่เราผ่าน: รหัสทั่วไปและ "ป้ายกำกับ"

การแสดงข้อมูลโดยการรวมชิ้นส่วนอะตอม

ต่อไปเราต้องมีมุมมองบางอย่างที่เจรจาระหว่างแบบจำลองของเรากับ ... แม่แบบของเรา

namespace WeCodeMore\Package;
interface PackageViewInterface
{
    /**
     * @param Models\ArgsInterface $args
     * @return int|void
     */
    public function render( Models\ArgsInterface $args );
}

โดยพื้นฐานแล้วอินเตอร์เฟสบอกว่า

"เราสามารถเรนเดอร์บางอย่างและโมเดลจำเป็นสำหรับงานนั้น"

ในที่สุดเราจำเป็นต้องดำเนินการดังกล่าวข้างต้นและสร้างความเป็นจริงดู อย่างที่คุณเห็นผู้สร้างบอกว่าสิ่งที่จำเป็นสำหรับมุมมองของเราคือเทมเพลตและเราสามารถสร้างมันขึ้นมาได้ เพื่อประโยชน์ในการพัฒนาที่ง่ายเรายังตรวจสอบว่ามีไฟล์เทมเพลตอยู่จริงหรือไม่เพื่อให้เราสามารถทำให้ผู้พัฒนารายอื่นใช้ชีวิตได้

ในขั้นตอนที่สองในฟังก์ชั่นการเรนเดอร์เราใช้การปิดเพื่อสร้างเสื้อคลุมเทมเพลตจริงและbindTo()โมเดลให้กับเทมเพลต

namespace WeCodeMore\Package;

use WeCodeMore\Package\Models\ArgsInterface;

/** @noinspection PhpInconsistentReturnPointsInspection */
class PackageView implements PackageViewInterface
{
    /** @var string|\WP_Error */
    private $template;
    /**
     * @param string $template
     */
    public function __construct( $template )
    {
        $this->template = ! file_exists( $template )
            ? new \WP_Error( 'wcm-package', 'A package view needs a template' )
            : $template;
    }
    /**
     * @param Models\ArgsInterface $args
     * @return int|void
     */
    public function render( Models\ArgsInterface $args )
    {
        if ( is_wp_error( $this->template ) )
            return print $this->template->get_error_message();

        /** @var $callback \Closure */
        $callback = function( $template )
        {
            extract( get_object_vars( $this ) );
            require $template;
        };
        call_user_func(
            $callback->bindTo( $args ),
            $this->template
        );
    }
}

การแยกมุมมองและการเรนเดอร์

ซึ่งหมายความว่าเราสามารถใช้เทมเพลตแบบง่าย ๆ ดังต่อไปนี้

<!--suppress HtmlFormInputWithoutLabel -->
<p><?= $label ?></p>

เพื่อแสดงเนื้อหาของเรา นำชิ้นส่วนต่างๆเข้าด้วยกันเราจะได้บางสิ่งรอบ ๆ บรรทัดต่อไปนี้ (ในตัวควบคุมผู้ไกล่เกลี่ย ฯลฯ ):

namespace WeCodeMore\Package;

$view = new PackageView( plugin_dir_path( __FILE__ ).'tmpl/label.tmpl.php' );
$view->render( new Models\Args );

เราได้อะไร

วิธีนี้เราทำได้

  1. แลกเปลี่ยนแม่แบบได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนโครงสร้างข้อมูล
  2. อ่านเทมเพิลได้ง่าย
  3. หลีกเลี่ยงขอบเขตทั่วโลก
  4. สามารถทดสอบหน่วย
  5. สามารถแลกเปลี่ยนข้อมูลรุ่น / ข้อมูลโดยไม่ทำอันตรายส่วนประกอบอื่น ๆ

การรวม OOP PHP เข้ากับ WP API

หลักสูตรนี้เป็นไปได้แทบจะโดยใช้ฟังก์ชั่นชุดรูปแบบพื้นฐานเช่นget_header(), get_footer()ฯลฯ ใช่มั้ย? ไม่ถูกต้อง. เพียงแค่เรียกคลาสของคุณในเทมเพลตหรือเทมเพลตที่คุณต้องการ แสดงผลแปลงข้อมูลทำในสิ่งที่คุณต้องการ หากคุณเป็นคนดีจริง ๆ คุณเพียงแค่เพิ่มตัวกรองที่กำหนดเองจำนวนมากและมีผู้เจรจาเพื่อดูแลสิ่งที่ได้รับการแสดงผลโดยตัวควบคุมที่โหลดเทมเพลตเส้นทาง / เงื่อนไข

สรุป?

คุณสามารถทำงานกับสิ่งต่าง ๆ ดังกล่าวข้างต้นใน WP โดยไม่มีปัญหาและยังคงยึดตาม API พื้นฐานและใช้รหัสและข้อมูลซ้ำโดยไม่เรียกใช้โกลบอลเดี่ยวหรือทำให้ยุ่งเหยิงและทำให้เกิดมลภาวะพื้นที่ชื่อโกลบอล


3
ดูดี! ฉันจะดูเพิ่มเติมในนี้คำตอบที่ดี!
marko

@kaiser เกือบ 3 ปีต่อมามีการอัพเดตสำหรับความคิดของคุณข้างต้นหรือไม่? การสร้างเทมเพลต WP หลักยังไม่คืบหน้าไปในทิศทางที่สูงขึ้นดังนั้นโซลูชั่นของ บริษัท อื่นยังคงเป็นเช่นนั้น
lkraav

1
@Ikraav ฉันอาจจะไม่เขียนอย่างนี้ทุกวันนี้ แต่ฉันยังคงมั่นใจว่าการไม่ใช้ไวยากรณ์แยกเพื่อส่งออกเนื้อหาของตัวแปรในแท็ก HTML เป็นวิธีที่จะดำเนินการ (และหลีกเลี่ยงค่าใช้จ่ายที่ไม่จำเป็น) ในทางกลับกันฉันไม่ค่อยเขียนส่วนหน้าใน PHP วันนี้ แต่ใน JavaScript และฉันชอบสิ่งที่ VueJS และเพื่อนนำมาสู่โต๊ะ
ไกเซอร์

11

นี่เป็นวิธีทางเลือกสำหรับคำตอบ@kaiserซึ่งฉันพบว่าค่อนข้างดี (+1 จากฉัน) แต่ต้องการงานเพิ่มเติมที่จะใช้กับฟังก์ชั่น core WP และเป็นแบบต่อเนื่องที่รวมเข้ากับลำดับชั้นของเทมเพลต

วิธีที่ฉันต้องการแบ่งปันนั้นขึ้นอยู่กับชั้นเรียนเดียว (เป็นเวอร์ชันที่แยกออกมาจากสิ่งที่ฉันกำลังทำอยู่) ที่ดูแลข้อมูลการแสดงผลสำหรับเทมเพลต

มันมีคุณสมบัติที่น่าสนใจ (IMO):

  • แม่แบบเป็นไฟล์แม่แบบ WordPress มาตรฐาน (single.php, page.php) พวกเขาได้รับพลังงานมากขึ้นเล็กน้อย
  • เทมเพลตที่มีอยู่ใช้งานได้ดังนั้นคุณสามารถรวมเทมเพลตจากธีมที่มีอยู่ได้โดยไม่ต้องใช้ความพยายาม
  • ซึ่งแตกต่างจากวิธี@kaiserในแม่แบบที่คุณเข้าถึงตัวแปรโดยใช้$thisคำสำคัญ: สิ่งนี้ทำให้คุณมีโอกาสที่จะหลีกเลี่ยงการแจ้งเตือนในการผลิตในกรณีที่มีตัวแปรที่ไม่ได้กำหนด

The EngineClass

namespace GM\Template;

class Engine
{
    private $data;
    private $template;
    private $debug = false;

  /**
   * Bootstrap rendering process. Should be called on 'template_redirect'.
   */
  public static function init()
  {
      add_filter('template_include', new static(), 99, 1);
  }

  /**
   * Constructor. Sets debug properties.
   */
  public function __construct()
  {
      $this->debug =
          (! defined('WP_DEBUG') || WP_DEBUG)
          && (! defined('WP_DEBUG_DISPLAY') || WP_DEBUG_DISPLAY);
  }

  /**
   * Render a template.
   * Data is set via filters (for main template) or passed to method for partials.
   * @param string $template template file path
   * @param array  $data     template data
   * @param bool   $partial  is the template a partial?
   * @return mixed|void
   */
  public function __invoke($template, array $data = array(), $partial = false)
  {
      if ($partial || $template) {
          $this->data = $partial
              ? $data
              : $this->provide(substr(basename($template), 0, -4));
          require $template;
          $partial or exit;
      }

      return $template;
  }

  /**
   * Render a partial.
   * Partial-specific data can be passed to method.
   * @param string $template template file path
   * @param array  $data     template data
   * @param bool   $isolated when true partial has no access on parent template context
   */
  public function partial($partial, array $data = array(), $isolated = false)
  {
      do_action("get_template_part_{$partial}", $partial, null);
      $file = locate_template("{$partial}.php");
      if ($file) {
          $class = __CLASS__;
          $template = new $class();
          $template_data =  $isolated ? $data : array_merge($this->data, $data);
          $template($file, $template_data, true);
      } elseif ($this->debug) {
          throw new \RuntimeException("{$partial} is not a valid partial.");
      }
  }

  /**
   * Used in templates to access data.
   * @param string $name
   * @return string
   */
  public function __get($name)
  {
      if (array_key_exists($name, $this->data)) {
          return $this->data[$name];
      }
      if ($this->debug) {
          throw new \RuntimeException("{$name} is undefined.");
      }

      return '';
  }

  /**
   * Provide data to templates using two filters hooks:
   * one generic and another query type specific.
   * @param string $type Template file name (without extension, e.g. "single")
   * @return array
   */
  private function provide($type)
  {
      $generic = apply_filters('gm_template_data', array(), $type);
      $specific = apply_filters("gm_template_data_{$type}", array());

      return array_merge(
        is_array($generic) ? $generic : array(),
        is_array($specific) ? $specific : array()
     );
  }
}

(มีอยู่ในส่วนสำคัญที่นี่)

วิธีใช้

สิ่งเดียวที่จำเป็นคือการเรียกEngine::init()วิธีการที่อาจเกี่ยวกับ'template_redirect'ตะขอ ที่สามารถทำได้ในรูปแบบfunctions.phpหรือจากปลั๊กอิน

require_once '/path/to/the/file/Engine.php';
add_action('template_redirect', array('GM\Template\Engine', 'init'), 99);

นั่นคือทั้งหมดที่

แม่แบบที่มีอยู่ของคุณจะทำงานตามที่อธิบายไว้ แต่ตอนนี้คุณมีความเป็นไปได้ในการเข้าถึงข้อมูลแม่แบบที่กำหนดเอง

ข้อมูลเทมเพลตที่กำหนดเอง

ในการส่งผ่านข้อมูลที่กำหนดเองไปยังเทมเพลตมีสองตัวกรองดังนี้

  • 'gm_template_data'
  • 'gm_template_data_{$type}'

อันแรกนั้นใช้สำหรับเทมเพลตทั้งหมดส่วนที่สองคือเทมเพลตเฉพาะอันที่จริงแล้วส่วน dymamic {$type}เป็นชื่อไฟล์พื้นฐานของไฟล์เทมเพลตที่ไม่มีนามสกุลไฟล์

เช่นตัวกรอง'gm_template_data_single'สามารถใช้เพื่อส่งผ่านข้อมูลไปยังsingle.phpเทมเพลต

การเรียกกลับที่แนบมากับ hooks เหล่านี้จะต้องส่งคืนอาร์เรย์โดยที่คีย์คือชื่อตัวแปร

ตัวอย่างเช่นคุณสามารถส่งผ่านข้อมูลเมตาเป็นข้อมูลเทมเพลตที่ชอบ:

add_filter('gm_template_data', function($data) {
    if (is_singular()) {
        $id = get_queried_object_id();
        $data['extra_title'] = get_post_meta($id, "_theme_extra_title", true);
    }

    return $data;
};

จากนั้นภายในเทมเพลตคุณสามารถใช้:

<?= $this->extra_title ?>

โหมดแก้ไขข้อบกพร่อง

เมื่อทั้งค่าคงที่WP_DEBUGและWP_DEBUG_DISPLAYเป็นจริงคลาสจะทำงานในโหมดดีบัก หมายความว่าหากไม่ได้กำหนดตัวแปรข้อยกเว้นจะถูกส่งออกไป

เมื่อคลาสไม่ได้อยู่ในโหมดดีบัก (อาจเป็นในการผลิต) การเข้าถึงตัวแปรที่ไม่ได้กำหนดจะส่งออกสตริงว่างเปล่า

ตัวแบบข้อมูล

วิธีที่ดีและบำรุงรักษาในการจัดระเบียบข้อมูลของคุณคือการใช้คลาสโมเดล

พวกเขาสามารถเป็นคลาสที่ง่ายมากที่ส่งคืนข้อมูลโดยใช้ตัวกรองเดียวกันที่อธิบายไว้ข้างต้น ไม่มีอินเทอร์เฟซพิเศษให้ติดตามพวกเขาสามารถจัดระเบียบตามความต้องการของคุณ

ด้านล่างมีเพียงตัวอย่าง แต่คุณมีอิสระที่จะทำในแบบของคุณเอง

class SeoModel
{
  public function __invoke(array $data, $type = '')
  {
      switch ($type) {
          case 'front-page':
          case 'home':
            $data['seo_title'] = 'Welcome to my site';
            break;
          default:
            $data['seo_title'] = wp_title(' - ', false, 'right');
            break;
      }

      return $data;
  }
}

add_filter('gm_template_data', new SeoModel(), 10, 2);

__invoke()วิธี (ที่วิ่งเมื่อชั้นถูกนำมาใช้เช่นการติดต่อกลับ) กลับสตริงที่จะใช้สำหรับ<title>แท็กของแม่

ขอบคุณที่ข้อเท็จจริงที่ว่าอาร์กิวเมนต์ที่สองผ่านไป'gm_template_data'เป็นชื่อแม่แบบวิธีการส่งกลับชื่อที่กำหนดเองสำหรับหน้าแรก

มีรหัสข้างต้นเป็นไปได้ที่จะใช้สิ่งที่ชอบ

 <title><?= $this->seo_title ?></title>

ใน<head>ส่วนของหน้า

partials

WordPress มีฟังก์ชั่นเช่นget_header()หรือget_template_part()ที่สามารถใช้ในการโหลดบางส่วนลงในเทมเพลตหลัก

ฟังก์ชั่นเหล่านี้เช่นเดียวกับฟังก์ชั่น WordPress อื่น ๆ สามารถใช้ในเทมเพลตเมื่อใช้Engineคลาส

ปัญหาเดียวก็คือว่าภายใน partials โหลดโดยใช้ฟังก์ชั่นหลัก WordPress เป็นไปไม่ได้ที่จะใช้ขั้นสูง$thisคุณลักษณะของการรับข้อมูลโดยใช้แม่แบบกำหนดเอง

ด้วยเหตุผลนี้Engineคลาสมีวิธีการpartial()ที่อนุญาตให้โหลดบางส่วน (ในวิธีที่เข้ากันได้กับธีมลูกทั้งหมด) และยังสามารถใช้ในส่วนของเทมเพลตข้อมูลที่กำหนดเองได้

การใช้งานค่อนข้างง่าย

สมมติว่ามีไฟล์ชื่อpartials/content.phpในโฟลเดอร์ theme (หรือธีมลูก) มันสามารถรวมโดยใช้:

<?php $this->partial('partials/content') ?>

ภายในบางส่วนนั้นจะสามารถเข้าถึงข้อมูลธีมหลักทั้งหมดได้ในลักษณะเดียวกัน

ซึ่งแตกต่างจากฟังก์ชั่น WordPress Engine::partial()วิธีการอนุญาตให้ส่งผ่านข้อมูลที่เฉพาะเจาะจงไปยัง partials เพียงแค่ส่งอาร์เรย์ของข้อมูลเป็นอาร์กิวเมนต์ที่สอง

<?php $this->partial('partials/content', array('greeting' => 'Welcome!')) ?>

โดยค่าเริ่มต้น partials สามารถเข้าถึงข้อมูลที่มีอยู่ในชุดรูปแบบหลักและส่งผ่านข้อมูลอย่างชัดเจน

หากตัวแปรบางตัวที่ส่งผ่านไปยังบางส่วนมีชื่อเดียวกันของตัวแปรธีมหลักอย่างชัดเจนดังนั้นตัวแปรนั้นจะผ่านการชนะอย่างชัดเจน

อย่างไรก็ตามยังเป็นไปได้ที่จะรวมบางส่วนในโหมดแยกเช่นบางส่วนไม่มีการเข้าถึงข้อมูลชุดรูปแบบหลัก ในการทำเช่นนั้นให้ส่งtrueอาร์กิวเมนต์ที่สามไปที่partial():

<?php $this->partial('partials/content', array('greeting' => 'Welcome!'), true) ?>

ข้อสรุป

แม้ว่าจะค่อนข้างเรียบง่าย แต่Engineคลาสก็ค่อนข้างสมบูรณ์ แต่ก็สามารถปรับปรุงให้ดีขึ้นได้ เช่นไม่มีวิธีการตรวจสอบว่ามีการกำหนดตัวแปรหรือไม่

ด้วยความเข้ากันได้ 100% กับฟีเจอร์ WordPress และลำดับชั้นของเทมเพลตคุณสามารถรวมเข้ากับโค้ดที่มีอยู่และรหัสบุคคลที่สามได้โดยไม่มีปัญหา

อย่างไรก็ตามโปรดทราบว่ามีการทดสอบเพียงบางส่วนเท่านั้นดังนั้นจึงอาจมีปัญหาที่ฉันยังไม่ได้ค้นพบ

ห้าคะแนนภายใต้"เราได้อะไรมา?" ในคำตอบ@kaiser :

  1. แลกเปลี่ยนแม่แบบได้อย่างง่ายดายโดยไม่ต้องเปลี่ยนโครงสร้างข้อมูล
  2. อ่านเทมเพิลได้ง่าย
  3. หลีกเลี่ยงขอบเขตทั่วโลก
  4. สามารถทดสอบหน่วย
  5. สามารถแลกเปลี่ยนข้อมูลรุ่น / ข้อมูลโดยไม่ทำอันตรายส่วนประกอบอื่น ๆ

ถูกต้องสำหรับชั้นเรียนของฉันเช่นกัน


1
ฮิฮิ. ทำได้ดีมากเพื่อน :) +1
kaiser

@gmazzap เกือบ 3 ปีต่อมามีการอัพเดตใด ๆ สำหรับความคิดของคุณข้างต้นหรือไม่? การสร้างเทมเพลต WP หลักยังไม่คืบหน้าไปในทิศทางที่สูงขึ้นดังนั้นโซลูชั่นของ บริษัท อื่นยังคงเป็นเช่นนั้น
lkraav

1
วันนี้ฉันไม่ทำงานหลายรูปแบบ เมื่อเร็ว ๆ นี้วิธีที่ฉันจะไปคือการรวมgithub.com/Brain-WP/Context + github.com/Brain-WP/Hierarchyเพื่อสร้างข้อมูลและส่งไปยังแม่แบบ สำหรับเครื่องมือเทมเพลตนั้นฉันใช้วิธีที่แตกต่างกันฟอยล์ (แน่นอน) หนวด แต่ยังทวิก (เฉพาะตอนที่ฉันสามารถควบคุม webiste ทั้งหมดเพื่อหลีกเลี่ยงการพึ่งพานรก) @lkraav
gmazzap

5

คำตอบง่ายๆไม่ส่งผ่านตัวแปรใด ๆ เพราะมันเหมือนการใช้ตัวแปรทั่วโลกที่ชั่วร้าย

จากตัวอย่างของคุณดูเหมือนว่าคุณกำลังพยายามเพิ่มประสิทธิภาพ แต่เนิ่นๆอีก)

ใช้ wordpress API เพื่อรับข้อมูลที่เก็บไว้ในฐานข้อมูลและอย่าพยายามที่จะเอาชนะและเพิ่มประสิทธิภาพการใช้งานเพราะ API ทำได้มากกว่าเพียงแค่ดึงค่าและเปิดใช้งานตัวกรองและการกระทำ ด้วยการลบการเรียก API คุณจะลบความสามารถของนักพัฒนาซอฟต์แวร์อื่นในการเปลี่ยนพฤติกรรมของรหัสของคุณโดยไม่ต้องแก้ไข


2

แม้ว่าคำตอบของไกเซอร์นั้นถูกต้องทางเทคนิค แต่ฉันสงสัยว่ามันเป็นคำตอบที่ดีที่สุดสำหรับคุณ

หากคุณกำลังสร้างธีมของคุณเองฉันคิดว่ามันเป็นวิธีที่ดีที่สุดในการตั้งค่าเฟรมเวิร์กโดยใช้คลาส (และอาจเป็นเนมสเปซและอินเทอร์เฟซเช่นกันแม้ว่ามันอาจจะมากเกินไปสำหรับธีม WP)

ในทางตรงกันข้ามถ้าคุณเป็นเพียงการขยาย / globalการปรับรูปแบบที่มีอยู่และต้องการเพียงที่จะผ่านการอย่างใดอย่างหนึ่งหรือตัวแปรไม่กี่ฉันคิดว่าคุณควรติดกับ เนื่องจากheader.phpรวมอยู่ในฟังก์ชันตัวแปรที่คุณประกาศในไฟล์นั้นจึงสามารถใช้งานได้ในไฟล์นั้นเท่านั้น เมื่อglobalคุณทำให้พวกเขาสามารถเข้าถึงได้ในโครงการ WP ทั้งหมด:

ในheader.php:

global $page_extra_title;

$page_extra_title = get_post_meta($this_page->ID, "_theme_extra_title", true);

ในsingle.php(ตัวอย่าง):

global $page_extra_title;

var_dump( $page_extra_title );

3
ฉันไม่ต้องการที่จะหยาบคายหรืออะไร แต่มันเป็นการฝึกฝนที่เลวร้ายในขอบเขตของโลก คุณควรหลีกเลี่ยงการเพิ่มในขอบเขตส่วนกลางอย่างสมบูรณ์ คุณจะต้องระมัดระวังในการตั้งชื่ออนุสัญญาที่นี่และคุณต้องตรวจสอบให้แน่ใจว่าชื่อตัวแปรของคุณจะไม่ซ้ำกันในลักษณะที่ไม่มีใครสามารถทำซ้ำชื่อดังกล่าวได้ วิธีการ @kaiser อาจดูเหมือนคุณมากเกินไป แต่มันก็เป็นวิธีที่ดีที่สุดและปลอดภัยที่สุด ฉันไม่สามารถบอกคุณได้ว่าจะแก้ไขปัญหานี้อย่างไร แต่ฉันขอแนะนำให้คุณหลีกเลี่ยงขอบเขตทั่วโลก :-)
Pieter Goosen

3
แน่นอนคุณต้องระวังว่าคุณจะไม่เขียนทับตัวแปรอื่น ๆ คุณสามารถเล่นงานนั้นโดยใช้คำนำหน้าที่ไม่ซ้ำกันหรืออาร์เรย์กับตัวแปรที่กำหนดเองของคุณ$wp_theme_vars_page_extra_titleหรือ$wp_theme_vars['page_extra_title']ตัวอย่างเช่น มันเป็นเพียงคำอธิบายว่าทำไมคนทั่วโลกถึงทำงานที่นี่ OP ถามถึงวิธีการส่งตัวแปรผ่านไฟล์ทั้งหมดโดยใช้globalเป็นวิธีการทำเช่นนั้น
redelschaap

2
ไม่กลมกลืนไม่ใช่วิธีที่จะทำเช่นนั้นได้ มีวิธีที่ดีกว่ามากในการบรรลุเป้าหมายเดียวกันโดยไม่ต้องใช้ globals อย่างที่ฉันพูดไว้ก่อนหน้านี้และตามที่ @kaiser ระบุไว้ในคำตอบของเขาให้หลีกเลี่ยงขอบเขตทั่วโลกและหลีกเลี่ยงมัน ยกตัวอย่างเช่นใช้ทางเลือกที่ง่ายมากห่อโค้ดของคุณในฟังก์ชันและเรียกใช้ฟังก์ชันที่จำเป็น ด้วยวิธีนี้คุณไม่จำเป็นต้องตั้งค่าหรือใช้ทั่วโลก
Pieter Goosen

3
ใช่แล้ว. มันอาจไม่ใช่วิธีที่ดีที่สุด แต่ก็เป็นวิธีที่แน่นอน
redelschaap

2
but it is really bad practice diving into the global scopeฉันหวังว่าจะมีคนบอกกับนักพัฒนาหลัก WP ฉันไม่เข้าใจจุดที่ใช้เนมสเปซ, ข้อมูลนามธรรม, รูปแบบการออกแบบ, การทดสอบหน่วยและแนวปฏิบัติที่ดีที่สุดในการเขียนโปรแกรม / เทคนิคต่าง ๆ ในโค้ดที่เขียนขึ้นสำหรับ Wordpress เมื่อ Wordpress แกนกลางเกลื่อนไปด้วย รหัส).
Ejaz

1

ทางออกที่ง่ายคือการเขียนฟังก์ชั่นเพื่อให้ได้ชื่อพิเศษ ฉันใช้ตัวแปรแบบสแตติกเพื่อให้ฐานข้อมูลโทรไปยังหนึ่งเท่านั้น ใส่สิ่งนี้ไว้ในฟังก์ชั่นของคุณ

function get_extra_title($post_id) {
    static $title = null;
    if ($title === null) {
        $title = get_post_meta($post_id, "_theme_extra_title", true)
    }
    return $title;
}

นอก header.php ให้เรียกใช้ฟังก์ชันเพื่อรับค่า:

var_dump(get_extra_title($post->ID));
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.