การจัดระเบียบรหัสในไฟล์ฟังก์ชั่นของ WordPress Theme.php?


92

ยิ่งฉันปรับแต่ง WordPress มากเท่าไหร่ฉันก็ยิ่งเริ่มคิดว่าฉันควรจะจัดระเบียบไฟล์นี้หรือแยกมันออก

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

การแบ่งพวกมันออกเป็นไฟล์แยกหรือรวมกลุ่มเข้าด้วยกันอาจทำให้เว็บไซต์ WordPress เร็วขึ้นหรือว่า WordPress / PHP จะข้ามฟังก์ชันที่มีรหัสนำหน้า is_admin โดยอัตโนมัติหรือไม่?

เป็นวิธีที่ดีที่สุดในการจัดการกับไฟล์ฟังก์ชั่นขนาดใหญ่ (ของฉันมีความยาว 1370 บรรทัด)

คำตอบ:


120

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

การใช้งานรวมถึงไฟล์ในรูปแบบของfunctions.phpไฟล์

ฉันสร้างไดเรกทอรีย่อยที่เรียกว่า"รวมถึง"ภายใต้ไดเรกทอรีธีมของฉันและแบ่งรหัสของฉันเป็นไฟล์รวมที่จัดเรียงตามสิ่งที่สมเหตุสมผลสำหรับฉันในเวลานั้น (ซึ่งหมายความว่าฉันจะทำการเปลี่ยนโครงสร้างใหม่และเคลื่อนย้ายโค้ดอย่างต่อเนื่อง ใส่รหัสจริงใด ๆ ในfunctions.php; ทุกอย่างไปในไฟล์รวมถึง; เพียงแค่การตั้งค่าของฉัน

นี่เป็นเพียงตัวอย่างการติดตั้งทดสอบที่ฉันใช้ทดสอบคำตอบของคำถามที่นี่ใน WordPress Answers ทุกครั้งที่ฉันตอบคำถามฉันจะเก็บรหัสไว้ในกรณีที่ฉันต้องการอีกครั้ง นี่ไม่ใช่สิ่งที่คุณจะทำกับไซต์สด แต่มันแสดงกลไกของการแยกรหัส:

<?php 
/*
 * functions.php
 * 
 */
require_once( __DIR__ . '/includes/null-meta-compare.php');
require_once( __DIR__ . '/includes/older-examples.php');
require_once( __DIR__ . '/includes/wp-admin-menu-classes.php');
require_once( __DIR__ . '/includes/admin-menu-function-examples.php');

// WA: Adding a Taxonomy Filter to Admin List for a Custom Post Type?
// http://wordpress.stackexchange.com/questions/578/
require_once( __DIR__ . '/includes/cpt-filtering-in-admin.php'); 
require_once( __DIR__ . '/includes/category-fields.php');
require_once( __DIR__ . '/includes/post-list-shortcode.php');
require_once( __DIR__ . '/includes/car-type-urls.php');
require_once( __DIR__ . '/includes/buffer-all.php');
require_once( __DIR__ . '/includes/get-page-selector.php');

// http://wordpress.stackexchange.com/questions/907/
require_once( __DIR__ . '/includes/top-5-posts-per-category.php'); 

// http://wordpress.stackexchange.com/questions/951/
require_once( __DIR__ . '/includes/alternate-category-metabox.php');  

// http://lists.automattic.com/pipermail/wp-hackers/2010-August/034384.html
require_once( __DIR__ . '/includes/remove-status.php');  

// http://wordpress.stackexchange.com/questions/1027/removing-the-your-backup-folder-might-be-visible-to-the-public-message-generate
require_once( __DIR__ . '/includes/301-redirects.php');  

หรือสร้างปลั๊กอิน

ตัวเลือกอื่นเพื่อเริ่มการจัดกลุ่มรหัสของคุณตามฟังก์ชั่นและสร้างปลั๊กอินของคุณเอง สำหรับฉันฉันเริ่มเขียนโค้ดในfunctions.phpไฟล์ของธีมและตามเวลาที่ฉันได้รหัสออกมาฉันได้ย้ายโค้ดส่วนใหญ่ของฉันไปเป็นปลั๊กอิน

อย่างไรก็ตามไม่มีประสิทธิภาพที่สำคัญได้รับจากองค์กรรหัส PHP

ในทางกลับกันการจัดโครงสร้างไฟล์ PHP ของคุณคือ 99% เกี่ยวกับการสร้างคำสั่งซื้อและการบำรุงรักษาและ 1% เกี่ยวกับประสิทธิภาพหากนั่น (การจัดระเบียบ.jsและ.cssไฟล์ที่เรียกใช้โดยเบราว์เซอร์ผ่าน HTTP เป็นกรณีที่แตกต่างกันโดยสิ้นเชิง โค้ด PHP ของคุณบนเซิร์ฟเวอร์นั้นไม่ได้สำคัญกับประสิทธิภาพ

และรหัสองค์กรคือการตั้งค่าส่วนตัว

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


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

5
+1 สำหรับ "หรือสร้างปลั๊กอิน" โดยเฉพาะอย่างยิ่ง " ปลั๊กอินการทำงาน "
Ian Dunn

3
การใช้พา ธ สัมพัทธ์อาจไม่น่าเชื่อถือในการตั้งค่าทุกประเภทควรใช้พา ธ สัมบูรณ์แทน
Mark Kaplun

2
@ MarkKaplun - คุณถูกต้องอย่างแน่นอน ตั้งแต่ฉันเขียนคำตอบนี้ฉันเรียนรู้บทเรียนนั้นอย่างยากลำบาก ฉันจะอัปเดตคำตอบของฉัน ขอบคุณที่ชี้นำสิ่งนี้
MikeSchinkel

ฉันได้รับ "การใช้ค่าคงที่DIR ที่ไม่ได้กำหนด- สันนิษฐานว่า" DIR "ใน C: \ wamp \ www \ site \ wp-content \ themes \ mytheme \ function.php" - PHP v5.6.25 และ PHP v7.0.10 - ฉันไม่สามารถ จัดรูปแบบให้ถูกต้อง DIR นี้ในความคิดเห็น (underscoreunderscoreDIRunderscoreunderscore) แต่ทำงานกับ dirname (underscoreunderscoreFILEunderscoreunderscore)
Marko

50

ตอบช้า

วิธีรวมไฟล์ของคุณอย่างถูกวิธี:

function wpse1403_bootstrap()
{
    // Here we load from our includes directory
    // This considers parent and child themes as well    
    locate_template( array( 'inc/foo.class.php' ), true, true );
}
add_action( 'after_setup_theme', 'wpse1403_bootstrap' );

การทำงานแบบเดียวกันกับปลั๊กอินก็เช่นกัน

วิธีรับเส้นทางที่ถูกต้องหรือ URi

ดูที่ฟังก์ชัน API ของระบบไฟล์เช่น:

  • home_url()
  • plugin_dir_url()
  • plugin_dir_path()
  • admin_url()
  • get_template_directory()
  • get_template_directory_uri()
  • get_stylesheet_directory()
  • get_stylesheet_directory_uri()
  • เป็นต้น

วิธีลดจำนวน include/require

หากคุณต้องการดึงไฟล์ทั้งหมดจากไดเรกทอรีไปด้วย

foreach ( glob( 'path/to/folder/*.php' ) as $file )
    include $file;

โปรดทราบว่าการดำเนินการนี้จะละเว้นความล้มเหลว (อาจดีสำหรับการใช้งานจริง) / ไม่ใช่ไฟล์ที่โหลดได้

หากต้องการเปลี่ยนพฤติกรรมนี้คุณอาจต้องการใช้การตั้งค่าที่แตกต่างกันระหว่างการพัฒนา:

$files = ( defined( 'WP_DEBUG' ) AND WP_DEBUG )
    ? glob( 'path/to/folder/*.php', GLOB_ERR )
    : glob( 'path/to/folder/*.php' )

foreach ( $files as $file )
    include $file;

แก้ไข: วิธี OOP / SPL

เมื่อฉันเพิ่งกลับมาและเห็นว่าคำตอบนี้เพิ่มจำนวนขึ้นอย่างรวดเร็วฉันคิดว่าฉันอาจแสดงให้เห็นว่าฉันกำลังทำอะไรอยู่ทุกวันนี้ในโลก 5.3+ PHP src/ตัวอย่างต่อไปนี้โหลดไฟล์ทั้งหมดจากธีมโฟลเดอร์ย่อยชื่อ นี่คือที่ฉันมีห้องสมุดของฉันที่จัดการงานบางอย่างเช่นเมนูรูปภาพ ฯลฯ คุณไม่ต้องสนใจชื่อเมื่อไฟล์ทุกไฟล์ถูกโหลด หากคุณมีโฟลเดอร์ย่อยอื่น ๆ ในไดเรกทอรีนี้พวกเขาจะถูกละเว้น

\FilesystemIteratorเป็น PHP 5.3+ supercedor\DirectoryIteratorมากกว่า ทั้งสองเป็นส่วนหนึ่งของ PHP SPL ในขณะที่ PHP 5.2 ทำให้สามารถปิดส่วนขยาย SPL ที่สร้างขึ้นได้ (ต่ำกว่า 1% ของการติดตั้งทั้งหมดนั้น) SPL ในตอนนี้เป็นส่วนหนึ่งของแกน PHP

<?php

namespace Theme;

$files = new \FilesystemIterator( __DIR__.'/src', \FilesystemIterator::SKIP_DOTS );
foreach ( $files as $file )
{
    /** @noinspection PhpIncludeInspection */
    ! $files->isDir() and include $files->getRealPath();
}

ก่อนหน้านี้ขณะที่ฉันยังคงรองรับ PHP 5.2.x ฉันใช้วิธีแก้ไขปัญหาต่อไปนี้: A \FilterIteratorในsrc/Filtersไดเรกทอรีเพื่อเรียกค้นไฟล์เท่านั้น (ไม่ใช่จุดตัวชี้ของโฟลเดอร์) และ a \DirectoryIteratorเพื่อทำการวนซ้ำและโหลด

namespace Theme;

use Theme\Filters\IncludesFilter;

$files = new IncludesFilter( new \DirectoryIterator( __DIR__.'/src' ) );
foreach ( $files as $file )
{
    include_once $files->current()->getRealPath();
}

\FilterIteratorเป็นเรื่องง่ายเหมือนที่:

<?php

namespace Theme\Filters;

class IncludesFilter extends \FilterIterator
{
    public function accept()
    {
        return
            ! $this->current()->isDot()
            and $this->current()->isFile()
            and $this->current()->isReadable();
    }
}

นอกเหนือจาก PHP 5.2 ที่ตายแล้ว / EOL ในตอนนี้ (และ 5.3 เช่นกัน) มีความจริงที่ว่ามันเป็นรหัสเพิ่มเติมและอีกหนึ่งไฟล์ในเกมดังนั้นจึงไม่มีเหตุผลที่จะไปด้วยในภายหลังและรองรับ PHP 5.2.x

สรุป

แม้เพิ่มเติมในเชิงลึกบทความสามารถพบได้ที่นี่ใน WPKrauts

แก้ไขวิธีที่ถูกต้องชัดเจนคือการใช้namespaceรหัส d ซึ่งเตรียมไว้สำหรับการโหลดอัตโนมัติPSR-4โดยใส่ทุกอย่างในไดเรกทอรีที่เหมาะสมซึ่งกำหนดไว้แล้วผ่านทางเนมสเปซ จากนั้นเพียงใช้Composerและ a composer.jsonเพื่อจัดการการขึ้นต่อกันของคุณและปล่อยให้มันสร้างออโต้โหลด PHP อัตโนมัติของคุณ (ซึ่งจะนำเข้าไฟล์โดยอัตโนมัติเพียงแค่โทรหาuse \<namespace>\ClassName) นั่นเป็นมาตรฐานโดยพฤตินัยในโลก PHP, วิธีที่ง่ายที่สุดที่จะไปและมากยิ่งขึ้นก่อนโดยอัตโนมัติและง่ายโดยWP Starter


5

ในแง่ของการทำลายมันในจานหม้อไอน้ำของฉันฉันใช้ฟังก์ชั่นที่กำหนดเองเพื่อค้นหาโฟลเดอร์ที่เรียกว่าฟังก์ชั่นในไดเรกทอรีธีมถ้ามันไม่ได้มีมันสร้าง จากนั้นจะสร้างอาร์เรย์ของไฟล์. php ทั้งหมดที่พบในโฟลเดอร์นั้น (ถ้ามี) และเรียกใช้ include (); ในแต่ละของพวกเขา

ด้วยวิธีนี้ทุกครั้งที่ฉันต้องเขียนฟังก์ชั่นใหม่ ๆ ฉันแค่เพิ่มไฟล์ PHP ลงในโฟลเดอร์ฟังก์ชั่นและไม่ต้องกังวลกับการเขียนโค้ดลงในเว็บไซต์

<?php
/* 
FUNCTIONS for automatically including php documents from the functions folder.
*/
//if running on php4, make a scandir functions
if (!function_exists('scandir')) {
  function scandir($directory, $sorting_order = 0) {
    $dh = opendir($directory);
    while (false !== ($filename = readdir($dh))) {
      $files[] = $filename;
    }
    if ($sorting_order == 0) {
      sort($files);
    } else {
      rsort($files);
    }
    return ($files);
  }
}
/*
* this function returns the path to the funtions folder.
* If the folder does not exist, it creates it.
*/
function get_function_directory_extension($template_url = FALSE) {
  //get template url if not passed
  if (!$template_url)$template_url = get_bloginfo('template_directory');


  //replace slashes with dashes for explode
  $template_url_no_slash = str_replace('/', '.', $template_url);

  //create array from URL
  $template_url_array = explode('.', $template_url_no_slash);

  //--splice array

  //Calculate offset(we only need the last three levels)
  //We need to do this to get the proper directory, not the one passed by the server, as scandir doesn't work when aliases get involved.
  $offset = count($template_url_array) - 3;

  //splice array, only keeping back to the root WP install folder (where wp-config.php lives, where the front end runs from)
  $template_url_array = array_splice($template_url_array, $offset, 3);
  //put back togther as string
  $template_url_return_string = implode('/', $template_url_array);
  fb::log($template_url_return_string, 'Template'); //firephp

  //creates current working directory with template extention and functions directory    
  //if admin, change out of admin folder before storing working dir, then change back again.
  if (is_admin()) {
    $admin_directory = getcwd();
    chdir("..");
    $current_working_directory = getcwd();
    chdir($admin_directory);
  } else {
    $current_working_directory = getcwd();
  }
  fb::log($current_working_directory, 'Directory'); //firephp

  //alternate method is chdir method doesn't work on your server (some windows servers might not like it)
  //if (is_admin()) $current_working_directory = str_replace('/wp-admin','',$current_working_directory);

  $function_folder = $current_working_directory . '/' . $template_url_return_string . '/functions';


  if (!is_dir($function_folder)) mkdir($function_folder); //make folder, if it doesn't already exist (lazy, but useful....ish)
  //return path
  return $function_folder;

}

//removed array elements that do not have extension .php
function only_php_files($scan_dir_list = false) {
  if (!$scan_dir_list || !is_array($scan_dir_list)) return false; //if element not given, or not array, return out of function.
  foreach ($scan_dir_list as $key => $value) {
    if (!strpos($value, '.php')) {

      unset($scan_dir_list[$key]);
    }
  }
  return $scan_dir_list;
}
//runs the functions to create function folder, select it,
//scan it, filter only PHP docs then include them in functions

add_action('wp_head', fetch_php_docs_from_functions_folder(), 1);
function fetch_php_docs_from_functions_folder() {

  //get function directory
  $functions_dir = get_function_directory_extension();
  //scan directory, and strip non-php docs
  $all_php_docs = only_php_files(scandir($functions_dir));

  //include php docs
  if (is_array($all_php_docs)) {
    foreach ($all_php_docs as $include) {
      include($functions_dir . '/' . $include);
    }
  }

}

5
@ildfuzz : เคล็ดลับดี โดยส่วนตัวฉันจะไม่ใช้มันสำหรับรหัสการผลิตเพราะมันจะโหลดทุกหน้าสิ่งที่เราสามารถทำได้อย่างง่ายดายเมื่อเราเปิดตัวเว็บไซต์ นอกจากนี้ฉันจะเพิ่มวิธีการละเว้นไฟล์บางอย่างเช่นไม่โหลดสิ่งที่เริ่มต้นด้วยการขีดเส้นใต้ดังนั้นฉันยังสามารถเก็บงานที่ดำเนินการอยู่ในไดเรกทอรีธีม มิฉะนั้นดี!
MikeSchinkel

ชอบความคิดนี้ แต่ฉันยอมรับว่าสิ่งนี้อาจนำไปสู่การโหลดที่ไม่จำเป็นสำหรับแต่ละคำขอ มีความคิดใดที่จะมีวิธีง่ายๆในการสร้างไฟล์ functions.php สุดท้ายที่สร้างขึ้นโดยอัตโนมัติด้วยการอัปเดตบางประเภทหาก / เมื่อมีการเพิ่มไฟล์ใหม่หรือในช่วงเวลาใดเวลาหนึ่ง
NetConstructor.com

ดี แต่มันนำไปสู่ความยืดหยุ่นได้เช่นกันจะเกิดอะไรขึ้นถ้าผู้โจมตีสามารถวางโค้ดในที่นั้นได้? และจะเกิดอะไรขึ้นถ้าการจัดลำดับของสิ่งที่มีความสำคัญ?
Tom J Nowell

1
@ MikeSchinkel ฉันเพิ่งเรียกไฟล์ที่ทำงานของฉัน foo._php จากนั้นปล่อย _php เมื่อฉันต้องการให้มันทำงาน
Mild Fuzz

@NetConstructor: จะมีความสนใจในการแก้ปัญหาด้วยเช่นกัน
ไกเซอร์

5

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

ด้านล่างเป็นตัวอย่างเล็ก ๆ โปรดใช้ข้อตกลงเกี่ยวกับ class * .php ด้วย

public function __construct() {

    $this->load_classes();
}

/**
 * Returns array of features, also
 * Scans the plugins subfolder "/classes"
 *
 * @since   0.1
 * @return  void
 */
protected function load_classes() {

    // load all files with the pattern class-*.php from the directory classes
    foreach( glob( dirname( __FILE__ ) . '/classes/class-*.php' ) as $class )
        require_once $class;

}

ในชุดรูปแบบฉันมักใช้สถานการณ์อื่น ฉันกำหนดฟังก์ชั่นของไฟล์ภายนอกใน ID การสนับสนุนดูตัวอย่าง นั่นคือมีประโยชน์ถ้าฉันจะปิดการใช้งาน feture ของไฟล์ externel ได้อย่างง่ายดาย ฉันใช้ฟังก์ชั่น WP core require_if_theme_supports()และเขาโหลดเท่านั้นหาก ID การสนับสนุนเปิดใช้งานอยู่ ในตัวอย่างต่อไปนี้ฉัน deifned ID ที่สนับสนุนนี้ในบรรทัดก่อนที่จะโหลดไฟล์

    /**
     * Add support for Theme Customizer
     * 
     * @since  09/06/2012
     */
    add_theme_support( 'documentation_customizer', array( 'all' ) );
    // Include the theme customizer for options of theme options, if theme supported
    require_if_theme_supports( 
        'documentation_customizer',
        get_template_directory() . '/inc/theme-customize.php'
    );

คุณสามารถเห็นสิ่งนี้เพิ่มเติมได้ในrepo ของชุดรูปแบบนี้


4

ฉันจัดการไซต์ที่มีประเภทหน้าเว็บที่กำหนดเองที่ไม่ซ้ำกันประมาณ 50 ภาษาในภาษาต่างๆผ่านการติดตั้งเครือข่าย พร้อมกับปลั๊กอินของ TON

เราถูกบังคับให้แยกมันทั้งหมดในบางจุด ไฟล์ฟังก์ชั่นที่มีรหัส 20-30k บรรทัดนั้นไม่ตลกเลย

เราตัดสินใจที่จะสร้างรหัสทั้งหมดเพื่อจัดการ codebase ให้ดีขึ้น โครงสร้างธีม wordpress เริ่มต้นนั้นดีสำหรับไซต์ขนาดเล็ก แต่ไม่เหมาะสำหรับไซต์ที่ใหญ่กว่า

function.php ใหม่ของเรามีเฉพาะสิ่งที่จำเป็นในการเริ่มต้นเว็บไซต์ แต่ไม่มีสิ่งใดเป็นของหน้าเฉพาะ

เค้าโครงของชุดรูปแบบที่เราใช้อยู่ในขณะนี้คล้ายกับรูปแบบการออกแบบ MCV แต่ในรูปแบบการเขียนโปรแกรมแบบขั้นตอน

ตัวอย่างเช่นหน้าสมาชิกของเรา:

หน้า member.php รับผิดชอบในการเริ่มต้นหน้า การเรียกฟังก์ชัน ajax ที่ถูกต้องหรือคล้ายกัน อาจเทียบเท่ากับส่วนคอนโทรลเลอร์ในสไตล์ MCV

ฟังก์ชั่น member.php มีฟังก์ชั่นทั้งหมดที่เกี่ยวข้องกับหน้านี้ นี่รวมอยู่ในหน้าอื่น ๆ ของเซิร์ฟเวอร์ซึ่งต้องการฟังก์ชั่นสำหรับสมาชิกของเรา

เนื้อหา member.php เตรียมข้อมูลสำหรับ HTML อาจเทียบได้กับโมเดลใน MCV

เค้าโครง member.php ส่วนที่เป็น HTML

หลังจากเราทำการเปลี่ยนแปลงเหล่านี้เวลาในการพัฒนาลดลง 50% และตอนนี้เจ้าของผลิตภัณฑ์มีปัญหาในการให้งานใหม่กับเรา :)


7
เพื่อให้มีประโยชน์มากขึ้นคุณอาจลองพิจารณาว่ารูปแบบ MVC นี้ใช้งานได้จริงอย่างไร
ไกเซอร์

ฉันก็อยากจะเห็นตัวอย่างของวิธีการของคุณโดยเฉพาะอย่างยิ่งกับรายละเอียด / สถานการณ์ต่าง ๆ วิธีการฟังดูน่าดึงดูดใจมาก คุณเปรียบเทียบโหลดเซิร์ฟเวอร์ / ประสิทธิภาพกับวิธีการมาตรฐานที่ผู้อื่นใช้หรือไม่ ทำตัวอย่าง GitHub ถ้าเป็นไปได้ทั้งหมด
NetConstructor.com



0

ฉันรวม@kaiser 's และ@mikeschinkel ' s คำตอบ

ฉันมีการกำหนดธีมของฉันเองทั้งหมดใน/includesโฟลเดอร์และภายในโฟลเดอร์นั้นฉันมีทุกอย่างแยกย่อยเป็นโฟลเดอร์ย่อย

ฉันต้องการ/includes/adminและรวมเนื้อหาย่อยเท่านั้นเมื่อtrue === is_admin()

หากโฟลเดอร์ถูกแยกออกiterator_check_traversal_callbackโดยส่งคืนfalseไดเรกทอรีย่อยจะไม่ถูกทำซ้ำ (หรือส่งผ่านไปยังiterator_check_traversal_callback)

/**
 *  Require all customizations under /includes
 */
$includes_import_root = 
    new \RecursiveDirectoryIterator( __DIR__ . '/includes', \FilesystemIterator::SKIP_DOTS );

function iterator_check_traversal_callback( $current, $key, $iterator ) {
    $file_name = $current->getFilename();

    // Only include *.php files
    if ( ! $current->isDir() ) {
        return preg_match( '/^.+\.php$/i', $file_name );
    }

    // Don't include the /includes/admin folder when on the public site
    return 'admin' === $file_name
        ? is_admin()
        : true;
}

$iterator_filter = new \RecursiveCallbackFilterIterator(
    $includes_import_root, 'iterator_check_traversal_callback'
);

foreach ( new \RecursiveIteratorIterator( $iterator_filter ) as $file ) {
    include $file->getRealPath();
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.