Организуете код в файле functions.php вашей темы WordPress?
8 ответ
- голосов
-
- 2010-09-06
Если вы приближаетесь к тому моменту,когда код в
functions.php
вашей темы начинает перегружать вас,я определенно скажу,что вы готовы рассмотреть возможность разделения его на несколько файлов. На данный момент я склонен делать это почти второй натурой.Используйте файлы включения в файле
functions.php
вашей темыЯ создаю подкаталог с именем "includes" в каталоге моей темы и сегментирую свой код на файлы включения,организованные по тому,что имеет для меня смысл в данный момент (что означает,что я постоянно реорганизую и перемещаю код по мере развития сайта.) Я также редко помещаю настоящий код в
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-код на сервере,практически не имеет значения с точки зрения производительности.Организация кода - это личное предпочтение
И последнее,но не менее важное,организация кода - это личные предпочтения. Некоторым людям не понравится то,как я организую код,так же,как я могу ненавидеть,как они это делают. Найдите то,что вам нравится,и придерживайтесь этого,но позвольте вашей стратегии развиваться со временем,по мере того,как вы будете узнавать больше и привыкать к этому.
If you are getting to the point where the code in your theme's
functions.php
is starting to overwhelm you I would definitely say you are ready to consider splitting it up into multiple files. I tend to do that almost by second nature at this point.Use Include Files in your Theme's
functions.php
FileI create a subdirectory called "includes" under my theme directory and segment my code into include files organized by what makes sense to me at the time (which means I'm constantly refactoring and moving code around as a site evolves.) I also rarely put any real code in
functions.php
; everything goes in the include files; just my preference.Just to give you an example here's my test install that I use to test my answers to questions here on WordPress Answers. Every time I answer a question I keep the code around in case I need it again. This isn't exactly what you'll do for a live site but it shows the mechanics of splitting up the code:
<?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');
Or Create Plugins
Another option it to start grouping your code by function and create your own plugins. For me I start coding in the theme's
functions.php
file and by the time I get the code fleshed out I've moved most of my code into plugins.However NO Significant Performance Gain From PHP Code Organization
On the other hand structuring your PHP files is 99% about creating order and maintainability and 1% about performance, if that (organizing
.js
and.css
files called by the browser via HTTP is a completely different case and has huge performance implications.) But how you organize your PHP code on the server pretty much doesn't matter from a performance perspective.And Code Organization is Personal Preference
And last but not least code organization is personal preference. Some people would hate how I organize code just as I might hate how they do it too. Find something you like and stick with it, but allow your strategy to evolve over time as you learn more and get more comfortable with it.
-
Хороший ответ,я только что дошел до того момента,когда мне нужно разделить файл функций.Как вы думаете,когда удобно перейти сfrunctions.php на плагин?В своем ответе вы сказали: «К тому времени,когда я получу конкретный код,я переместил большую часть своего кода в плагины».Я не совсем понимаю,что вы имеете в виду под конкретизацией.Nice answer, I just arrived to this point where i need to split the functions file. When do you think it's handy to move from frunctions.php to a plugin. You said in your answer: _by the time I get the code fleshed out I've moved most of my code into plugins_. I do not understand that fully, what do you mean with fleshed out.
- 0
- 2011-08-16
- Saif Bechan
-
+1 за «или создать плагины».В частности,«[плагины функциональности] (http://www.doitwithwp.com/create-functions-plugin/)»+1 for "or create plugins". More specifically, "[functionality plugins](http://www.doitwithwp.com/create-functions-plugin/)"
- 5
- 2012-04-18
- Ian Dunn
-
использование относительных путей может быть ненадежным во всех типах настроек,всегда следует использовать абсолютный путьusing relative paths might not be reliable in all kinds of settings, absolute path should always be used instead
- 3
- 2016-09-22
- Mark Kaplun
-
@MarkKaplun - Вы ** абсолютно ** правы.С тех пор,как я написал этот ответ,я усвоил этот урок на собственном горьком опыте.Я собираюсь обновить свой ответ.Спасибо за указание на это.@MarkKaplun - You are **absolutely** correct. Since I wrote this answer I learned that lesson the hard way. I am going to update my answer. Thanks for pointing this out.
- 2
- 2016-09-23
- MikeSchinkel
-
Я получаю сообщение «Использование неопределенной константы __DIR__ - предполагается '__DIR__' в C: \ wamp \ www \ site \ wp-content \themes \mytheme \functions.php» - PHP v5.6.25 и PHP v7.0.10 - Я не могуправильно отформатируйте этот DIR в комментарии (подчеркивание,подчеркивание,DIR,underscore,подчеркивание),но оно работает с именем каталога (подчеркивание,подчеркивание,Core,FI,,подчеркивание,подчеркивание).I get "Use of undefined constant __DIR__ - assumed '__DIR__' in C:\wamp\www\site\wp-content\themes\mytheme\functions.php" - PHP v5.6.25 and PHP v7.0.10 - I can't format properly this DIR in comment (underscoreunderscoreDIRunderscoreunderscore), but it works with dirname(underscoreunderscoreFILEunderscoreunderscore)
- 0
- 2016-11-01
- Marko
-
Внимание: вам нужно использовать __DIR__ вместо __DIR ___,иначе вы получите внутреннюю ошибку сервера (500).Caution: you'd need to use `__DIR__` instead of `__DIR___`, otherwise you'll be presented with an Internal Server Error (500).
- 0
- 2017-02-13
- robro
-
@robro - Ах,спасибо,что поймали это!_ (Блин опечатки. Гррр ...) _ :-)@robro - Ah, thanks for catching that! _(Damn typos. Grrr...)_ :-)
- 0
- 2017-02-13
- MikeSchinkel
-
- 2012-10-13
Поздний ответ
Как правильно включить файлы:
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
Когда я только что вернулся и увидел,что этот ответ получает все больше и больше голосов,я подумал,что могу показать,как я это делаю сейчас - в мире PHP 5.3+. В следующем примере загружаются все файлы из подпапки тем с именем
src/
. Здесь у меня есть библиотеки,которые обрабатывают определенные задачи,такие как меню,изображения и т. Д. Вам даже не нужно заботиться об имени,поскольку загружается каждый отдельный файл. Если в этом каталоге есть другие подпапки,они игнорируются.\FilesystemIterator
- это суперседор PHP 5.3+ над\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,я использовал следующее решение:
\FilterIterator
в каталогеsrc/Filters
,чтобы получать только файлы (а не точки указатели папок) и\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 .
Подведены итоги
РЕДАКТИРОВАТЬ Очевидно правильный способ - использовать код
namespace
d,подготовленный для PSR-4 автозагрузка путем помещения всего в соответствующий каталог,который уже определен через пространство имен. Затем просто используйте Composer иcomposer.json
для управления своими зависимостями и позвольте ему автоматически создайте свой автозагрузчик PHP (который автоматически импортирует файл,просто вызываяuse \<namespace>\ClassName
). Это де-факто стандарт в мире PHP,самый простой способ,который еще более автоматизирован и упрощен с помощью WP. Стартер .Late answer
How to include your files the right way:
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' );
The same works in plugins too.
How to get the right path or URi
Also take a look at file system API functions like:
home_url()
plugin_dir_url()
plugin_dir_path()
admin_url()
get_template_directory()
get_template_directory_uri()
get_stylesheet_directory()
get_stylesheet_directory_uri()
- etc.
How to reduce the number of
include/require
If you need to fetch all files from a directory go with
foreach ( glob( 'path/to/folder/*.php' ) as $file ) include $file;
Keep in mind that this ignores failures (maybe good for production use)/not loadable files.
To alter this behavior you might want to use a different config during development:
$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;
Edit: OOP/SPL approach
As I just came back and saw that this answer is getting more and more upvotes, I thought I might show how I'm doing it nowadays - in a PHP 5.3+ world. The following example loads all files from a themes subfolder named
src/
. This is where I have my libraries that handle certain tasks like menus, images, etc. You don't even have to care about the name as every single file gets loaded. If you have other subfolders in this directory, they get ignored.The
\FilesystemIterator
is the PHP 5.3+ supercedor over the\DirectoryIterator
. Both are part of the PHP SPL. While PHP 5.2 made it possible to turn the built in SPL extension off (below 1% of all installs did that), the SPL now is part of PHP core.<?php namespace Theme; $files = new \FilesystemIterator( __DIR__.'/src', \FilesystemIterator::SKIP_DOTS ); foreach ( $files as $file ) { /** @noinspection PhpIncludeInspection */ ! $files->isDir() and include $files->getRealPath(); }
Previously while I still supported PHP 5.2.x, I used the following solution: A
\FilterIterator
in thesrc/Filters
directory to only retrieve files (and not dot pointers of folders) and a\DirectoryIterator
to do the looping and loading.namespace Theme; use Theme\Filters\IncludesFilter; $files = new IncludesFilter( new \DirectoryIterator( __DIR__.'/src' ) ); foreach ( $files as $file ) { include_once $files->current()->getRealPath(); }
The
\FilterIterator
was as easy as that:<?php namespace Theme\Filters; class IncludesFilter extends \FilterIterator { public function accept() { return ! $this->current()->isDot() and $this->current()->isFile() and $this->current()->isReadable(); } }
Aside from PHP 5.2 being dead/EOL by now (and 5.3 as well), there's the fact that it's more code and one more file in the game, so there's no reason to go with the later and support PHP 5.2.x.
Summed up
EDIT The obviously correct way is to use
namespace
d code, prepared for PSR-4 autoloading by putting everything in the appropriate directory that already is defined via the namespace. Then just use Composer and acomposer.json
to manage your dependencies and let it auto-build your PHP autoloader (that imports automatically a file by just callinguse \<namespace>\ClassName
). That's the de-facto standard in the PHP world, the easiest way to go and even more pre-automated and simplified by WP Starter. -
- 2012-10-04
Мне нравится использовать функцию для файлов внутри папки. Такой подход позволяет легко добавлять новые функции при добавлении новых файлов. Но я всегда пишу в классе или с пространствами имен - дайте ему больше контроля над пространством имен функций,методов и т. Д.
Ниже небольшой пример; но также использование с соглашением о классе * .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; }
В Темах я часто использую другой сценарий. Я определяю функцию файлаexternel в идентификаторе поддержки,см. Пример. Это полезно,если я легко деактивирую возможность файлаexternel. Я использую основную функцию WP
require_if_theme_supports()
,и он загружается только в том случае,если идентификатор поддержки был активен. В следующем примере я определил этот поддерживаемый идентификатор в строке перед загрузкой файла./** * 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' );
Подробнее об этом можно узнать в репозитории этой темы .
I like to use a function to the files inside a folder. This approach makes it easy to add new features when adding new files. But I write always in class or with namespaces - give it more control about the Namespace of functions, method etc.
Below a small example; ut also useage with the agreement about the 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; }
In Themes I use often a other scenario. I define the function of the externel file in a support ID, see the example. That is usefull if I will easy deactivate the feture of the externel file. I use the WP core function
require_if_theme_supports()
and he load only, if the support ID was active. In the follow example I deifned this supported ID in the line before load the file./** * 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' );
You can see more of this in the repo of this theme.
-
- 2010-09-06
с точки зрения разбиения на части,в моем шаблоне я использую пользовательскую функцию для поиска папки с именемfunctions в каталоге темы,если ее там нет,он создает ее. Затем он создает массив всех файлов .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); } } }
in terms of breaking it up, in my boiler plate I use a custom function to look for a folder called functions in the theme directory, if it is not there it creates it. Then is creates an array of all the .php files it finds in that folder (if any) and runs an include(); on each of them.
That way, each time I need to write some new functionality, I just add a PHP file to the functions folder, and don't have to worry about coding it into the site.
<?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); } } }
-
* @mildfuzz *: Хороший трюк.Я лично не стал бы использовать его для производственного кода,потому что он делает при каждой загрузке страницы то,что мы могли бы легко сделать один раз при запуске сайта.Кроме того,я бы добавил каким-то образом опускать файлы,например,не загружать что-либо,начинающееся с подчеркивания,чтобы я мог все еще хранить незавершенные работы в каталоге темы.В остальном приятно!*@mildfuzz*: Nice trick. I personally wouldn't use it for production code because it does for every page load what we could easily do once when we launch the site. Also, I'd add in some way to omit files, like not loading anything starting with an underscore so I could still store works in progress in the theme directory. Otherwise, nice!
- 5
- 2010-09-06
- MikeSchinkel
-
нравится идея,но я согласен,что это может привести к ненужной загрузке для каждого запроса.Любая идея,есть ли простой способ,чтобы окончательный файлfunctions.php автоматически создавался в кеше с некоторым типом обновления,если/когда добавляются новые файлы или через определенный промежуток времени?love the idea but I agree this might possibly lead to unnecessary loading for each request. Any idea if there would be a simple way to have the final functions.php file being generated automatically cached with some type of update if/when new files are added or at a specific time interval?
- 0
- 2010-09-07
- NetConstructor.com
-
Хорошо,но это ведет к негибкости. Что произойдет,если злоумышленнику удастся вставить туда свой код?А что,если порядок включения важен?Nice but it leads to inflexibilities, also what happens if an attacker manages to drop their code in there? And what if the ordering of includes is important?
- 0
- 2010-09-07
- Tom J Nowell
-
@MikeSchinkel Я просто называю свои рабочие файлыfoo._php,а затем бросаю _php,когда хочу,чтобы он запустился.@MikeSchinkel I just call my working files foo._php, then drop the _php when I want it to run.
- 1
- 2010-09-10
- Mild Fuzz
-
@NetConstructor: Было бы интересно найти какое-нибудь решение для.@NetConstructor: Would be interested in some sollution too.
- 0
- 2011-02-01
- kaiser
-
@kaiser,я полагаю,вы могли бы сделать это с помощью скриптов cron,запускающих функцию,которая запускает указанный выше поиск папок,но записывает результаты в DB/текстовый файл,а затем основывает нагрузки на этой функции.Это потенциально может привести к тому,что незаконченная работа также попадет в нагрузку.@kaiser, I suppose you could do it with cron scripts running a function that run's the above folder search but writes the results to a DB/textfile, then bases the loads on that function. This could potentially lead to unfinished work going into the load also.
- 0
- 2011-02-01
- Mild Fuzz
-
@MildFuzz: Майк просто указал мне на API переходных процессов.Может быть,это могло быть частью какого-то решения ...@MildFuzz: Mike just pointed me at the transients API. Maybe that could get part of some sort of sollution...
- 0
- 2011-02-01
- kaiser
-
на основе решения,изложенного @mildfuzz - какой метод вы,ребята,считаете лучшим для автоматического исключения любого файла или папки (и их подфайлов/папок) из включения в его подход автоматического включения?Я бы подумал,что использовать в качестве префикса подход подчеркивания.Какой правильный код будет лучшим подходом для включения таких возможностей?based on the solution outlined by @mildfuzz - what do you guys believe to be the best method to automatically exclude any file or folder (and its subfiles/folders) from being included within his auto-include approach? My thought would be to use the underscore approach as a prefix. What proper code would be the best approach to include such capabilities?
- 0
- 2012-10-10
- NetConstructor.com
-
вам просто нужно изменить `if (! strpos ($ value,'.php'))`,чтобы включить любую выбранную вами систему.you just need to change `if (!strpos($value, '.php'))` to include whatever system you choose.
- 0
- 2012-10-10
- Mild Fuzz
-
- 2012-10-04
Я управляю сайтом с примерно 50 уникальными настраиваемыми типами страниц на нескольких языках через сетевую установку. Наряду с ТОННОЙ плагинов.
В какой-то момент мы были вынуждены все это разделить. Файл функций с 20-30к строками кода - это совсем не смешно.
Мы решили полностью реорганизовать весь код,чтобы лучше управлять кодовой базой. Структура темы WordPress по умолчанию подходит для небольших сайтов,но не для крупных.
Наш новыйfunctions.php содержит только то,что необходимо для запуска сайта,но ничего,что относится к определенной странице.
Макет темы,который мы используем сейчас,аналогичен шаблону проектирования MCV,но с процедурным стилем кодирования.
Например,наша страница участника:
page-member.php . Отвечает за инициализацию страницы. Вызов правильных функций ajax или аналогичных. Может быть эквивалентно части контроллера в стиле MCV.
functions-member.php . Содержит все функции,относящиеся к этой странице. Это также включено в некоторые другие страницы,которые нуждаются в функциях для наших участников.
content-member.php . Подготавливает данные для HTML. Может быть эквивалентно модели в MCV.
layout-member.php . Часть HTML.
После того,как мы внесли эти изменения,время разработки легко сократилось на 50%,и теперь владелец продукта не может ставить перед нами новые задачи. :)
I manage a site with about 50 unique custom page types in serveral different languages over a network installation. Along with a TON of plugins.
We where forced to split it all up at some point. A functions file with 20-30k lines of code is not funny at all.
We decided to completley refactor all code in order to manage the codebase better. The default wordpress theme structure is good for small sites, but not for bigger sites.
Our new functions.php only contains what is necessary to start the site, but nothing which belongs to a specific page.
The theme layout we use now is similar to the MCV design pattern, but in a procedural coding style.
For example our member page:
page-member.php. Responsible for initializing the page. Calling the correct ajax functions or similar. Could be equivialent to the Controller part in the MCV style.
functions-member.php. Contains all functions related to this page. This is also included in serveral other pages which need functions for our members.
content-member.php. Prepares the data for HTML Could be equivialent to the Model in MCV.
layout-member.php. The HTML part.
Efter we did these changes the development time have easily dropped by 50% and now the product owner have trouble giving us new tasks. :)
-
Чтобы сделать это более полезным,вы можете подумать о том,чтобы показать,как на самом деле работает этот шаблон MVC.To make this more helpful you might consider showing how this MVC pattern really works.
- 7
- 2012-10-05
- kaiser
-
Мне также было бы любопытно увидеть пример вашего подхода,желательно с некоторыми деталями/различными ситуациями.Подход звучит очень интересно.Вы сравнивали загрузку/производительность сервера со стандартной методологией,которую используют другие?если возможно,предоставьте пример наgithub.i would also be currious to see an example of your approach, preferably with some details/various situations. The approach sounds very interresting. Have you compared server load/performance with the standard methodology others use? do provide a github example if at all possible.
- 0
- 2012-10-10
- NetConstructor.com
-
- 2013-10-20
Из файлаfunctions.php дочерней темы:
require_once( get_stylesheet_directory() . '/inc/custom.php' );
From child themes functions.php file:
require_once( get_stylesheet_directory() . '/inc/custom.php' );
-
- 2012-10-04
Вfunctions.php более элегантным способом вызова необходимого файла будет:
require_once locate_template ('/inc/functions/shortcodes.php');
In functions.php, a more elegant way to call a required file would be:
require_once locate_template('/inc/functions/shortcodes.php');
-
[`locate_template ()`] (http://codex.wordpress.org/Function_Reference/locate_template) имеет третий параметр…[`locate_template()`](http://codex.wordpress.org/Function_Reference/locate_template) has a third parameter …
- 4
- 2012-10-04
- fuxia
-
- 2018-08-19
Я объединил @kaiser и ответы @mikeschinkel .
У меня есть все настройки моей темы в папке
/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(); }
I combined @kaiser's and @mikeschinkel's answers.
I have all my customizations to my theme in a
/includes
folder and within that folder I have everything broken out into sub folders.I only want
/includes/admin
and its sub-contents to be included whentrue === is_admin()
If a folder is excluded in
iterator_check_traversal_callback
by returningfalse
then its sub-directories will not be iterated (or passed toiterator_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(); }
Чем больше я настраиваю WordPress,тем больше я начинаю думать о том,следует ли мне организовать этот файл или разбить его на части.
В частности,если у меня есть несколько настраиваемых функций,которые применяются только к области администрирования,а другие - только к моему общедоступному веб-сайту,есть ли какие-либо причины для включения всех функций администратора в их собственный файл или сгруппировать их вместе?/p>
Может ли их разделение на отдельные файлы или группировка ускорить работу веб-сайта WordPress,или WordPress/PHP автоматически пропускает функции с префиксом кодаis_admin?
Как лучше всего работать с большим файлом функций (у меня 1370 строк).