Организация Кода в functions.php Файле Темы WordPress?

Чем больше настройки, которую я делаю к WordPress, тем больше я начинаю думать о том, если я должен организовывать этот файл или разделять его.

Строго говоря, если у меня есть набор пользовательских функций, которые только относятся к администраторской области и другим, которые просто обращаются к моему общедоступному сайту, там какая-либо причина возможно включать все функции администрирования в их собственном файле или собрать в группу их?

Был бы, разделяя их на отдельные файлы, или собирание в группу их возможно ускоряет веб-сайт WordPress, или WordPress/PHP автоматически перескакивает через функции, которые имеют префикс кода is_admin?

Что является лучшим способом иметь дело с большим файлом функций (мой - 1 370 строк долго).

92
10.10.2012, 14:40
7 ответов

Если Вы переходите к сути дела где код в Вашей теме functions.php запуск должен сокрушить Вас, я определенно сказал бы, что Вы готовы рассмотреть разделение его в несколько файлов. Я склонен делать это почти по второй натуре в этой точке.

Использование Включает Файлы в Вашу Тему functions.php Файл

Я создаю названный подкаталог, "включает" в соответствии с моим каталогом темы, и сегментируйтесь, мой код во включают файлы, организованные тем, что имеет смысл мне в то время (что означает, что я постоянно осуществляю рефакторинг и перемещаю код, поскольку сайт развивается.) Я также редко вставлял любой реальный код functions.php; все входит во включать файлы; просто мое предпочтение.

Только, чтобы дать Вам примером здесь является моя тестовая установка, которую я использую для тестирования моих ответов на вопросы здесь на Ответах WordPress. Каждый раз, когда я отвечаю на вопрос, я имею в наличии код в случае, если мне нужен он снова. Это не точно, что Вы сделаете для живого сайта, но он показывает механику разделения кода:

<?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 сервера в значительной степени, не имеет значения с точки зрения производительности.

И Организация Кода является Персональным Предпочтением

И наконец, что не менее важно, организация кода является персональным предпочтением. Некоторые люди ненавидели бы, как я организую код, как я мог бы ненавидеть, как они делают это также. Найдите что-то, что Вы любите и продолжаете работать с ним, но позволяете Вашей стратегии развиваться со временем, как Вы узнаете больше и становитесь более довольными им.

121
19.02.2020, 21:54
  • 1
    Хороший ответ, я просто прибыл в эту точку, где я должен разделить файл функций. Когда делают Вы думаете, что удобно переместиться от frunctions.php до плагина. Вы сказали в своем ответе: к тому времени, когда я изложил в деталях код, я переместил большую часть своего кода в плагины. Я не понимаю, что полностью, что Вы имеете в виду с изложенным в деталях. –  Saif Bechan 16.08.2011, 10:02
  • 2
    +1 точки для "или создайте плагины". Строго говоря, "плагины функциональности" –  Ian Dunn 19.04.2012, 00:29
  • 3
    с помощью относительных путей не мог бы быть надежным во всех видах настроек, полный путь должен всегда использоваться вместо этого –  Mark Kaplun 22.09.2016, 18:27
  • 4
    @MarkKaplun - Вы абсолютно корректны. Так как я записал этот ответ, я научился тому уроку на горьком опыте. Я собираюсь обновить свой ответ. Спасибо за указание на это. –  MikeSchinkel 23.09.2016, 05:00
  • 5
    я получаю "Использование неопределенного постоянного DIR - принял 'DIR' в C:\wamp\www\site\wp-content\themes\mytheme\functions.php" - PHP v5.6.25 и PHP v7.0.10 - я не могу отформатировать правильно этот DIR в комментарии (underscoreunderscoreDIRunderscoreunderscore), но это работает с dirname (underscoreunderscoreFILEunderscoreunderscore) –  Marko 01.11.2016, 10:08

с точки зрения разбивания его в моем шаблоне я использую пользовательскую функцию для поиска вызванных функций папки в каталоге темы, если это не там, это создает его. Затем, создает массив всех .php файлов, которые он находит в той папке (если таковые имеются) и выполняет включение (); на каждом из них.

Тем путем, каждый раз, когда я должен записать некоторую новую функциональность, я просто добавляю файл 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
19.02.2020, 21:54
  • 1
    @MikeSchinkel я просто называю свое рабочее нечто файлов. _ php, затем отбросьте _php, когда я захочу, чтобы он работал. –  Mild Fuzz 10.09.2010, 18:25
  • 2
    @NetConstructor: интересовался бы некоторым решением также. –  kaiser 01.02.2011, 09:35

Последний ответ

Как включать Ваши файлы правильный путь:

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;

Править: Подход ООП/SPL

Поскольку я просто возвратился и видел, что этот ответ получает все больше upvotes, я думал, что мог бы показать, как я делаю его в наше время - в PHP 5.3 + мир. Следующий пример загружает все файлы из названной подпапки тем src/. Это - то, где у меня есть свои библиотеки, которые справляются с определенными задачами как меню, изображения, и т.д. Вы не должны даже заботиться об имени, поскольку каждый файл загружается. Если у Вас есть другие подпапки в этом каталоге, они проигнорированы.

\FilesystemIterator PHP 5.3 + supercedor по \DirectoryIterator. Оба - часть SPL PHP. В то время как 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.

РЕДАКТИРОВАНИЕ, очевидно, корректный путь должно использовать namespaced код, подготовленный к автозагрузке PSR-4 путем помещения всего в соответствующий каталог, который уже определяется через пространство имен. Затем просто используйте Компоновщик и a composer.json управлять Вашими зависимостями и позволять ему автосоздать Ваш автопогрузчик PHP (который импортирует автоматически файл, просто звоня use \<namespace>\ClassName). Это - фактический стандарт в мире PHP, самый легкий способ пойти и еще более предварительно автоматизированный и упрощенный Начинающим WP.

51
19.02.2020, 21:54

Мне нравится использовать функцию для файлов в папке. Этот подход помогает добавить новые опции при добавлении новых файлов. Но я всегда пишу в классе, или с пространствами имен - дают ему больше контроля о Пространстве имен функций, метод и т.д.

Ниже небольшого примера; единое время также useage с соглашением о 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;

}

В Темах я часто использую другой сценарий. Я определяю функцию внешнего файла в идентификаторе поддержки, вижу пример. Это полезно, если я буду легкий деактивировать feture внешнего файла. Я использую базовую функцию WP require_if_theme_supports() и он загружается только, если идентификатор поддержки был активен. В последовать примере I deifned этот поддерживаемый идентификатор в строке перед загрузкой файл.

    /**
     * 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 этой темы.

5
19.02.2020, 21:54

Я управляю сайтом приблизительно с 50 уникальными пользовательскими типами страницы на serveral различных языках по монтажу сети. Наряду с ТОННОЙ плагинов.

Мы, где вызвано для разделения всего этого в какой-то момент. Файл функций с 20-30k строками кода не забавен вообще.

Мы решили полностью осуществить рефакторинг весь код для управления кодовой базой лучше. Структура темы Wordpress по умолчанию хороша для небольших сайтов, но не для больших сайтов.

Наш новый functions.php только содержит то, что необходимо для создавания сайта, но ничто, что принадлежит определенной странице.

Расположение темы, которое мы используем теперь, подобно шаблону разработки MCV, но в процедурном стиле кодирования.

Например, наша членская страница:

страница-member.php. Ответственный за инициализацию страницы. Вызов корректного ajax функционирует или подобный. Мог быть equivialent к части Контроллера в стиле MCV.

функции-member.php. Содержит все функции, связанные с этой страницей. Это также включено в serveral другие страницы, которым нужны функции для наших участников.

содержание-member.php. Готовится данные для HTML Могли быть equivialent к Модели в MCV.

расположение-member.php. Часть HTML.

Efter мы сделали эти изменения время разработки, легко отбросили на 50%, и теперь владелец продукта испытывает затруднения при предоставлении нам новых задач.:)

4
19.02.2020, 21:54
  • 1
    Для создания этого более полезным, Вы могли бы рассмотреть показ, как этот шаблон MVC действительно работает. –  kaiser 05.10.2012, 13:57
  • 2
    мне также было бы любопытно видеть пример Вашего подхода, предпочтительно с некоторыми ситуациями с деталями / различными ситуациями. Подход звучит очень межпокоящимся. Вы сравнили загрузку/производительность сервера со стандартным использованием других методологии? действительно обеспечьте пример GitHub если вообще возможный. –  NetConstructor.com 10.10.2012, 14:29

В functions.php более изящный способ назвать необходимый файл был бы:

require_once locate_template ('/inc/functions/shortcodes.php');

0
19.02.2020, 21:54

От дочерних тем functions.php файл:

    require_once( get_stylesheet_directory() . '/inc/custom.php' );
3
19.02.2020, 21:54

Теги

Похожие вопросы