WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

Файл темы functions.php в WordPress

Каждый знакомый с WordPress слышал про файл темы (шаблона) functions.php. Однако не все хорошо понимают его назначение, видя в нем лишь файл в котором хранятся различные php функции. В сети, как и у меня на этом сайте, часто предлагается добавлять PHP код в этот файл. Однако не каждый код подойдет для этого файла. Не потому что он не будет работать, а потому что он не подходит по логике использования.

Также при редактировании functions.php новички допускают ошибки из-за которых сайт перестает работать.

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

Возможности functions.php

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

Для примера, следующий код, вставленный в файл темы functions.php расширит возможности темы - включит поддержку миниатюр поста:

function wp_kama_theme_setup(){
	// Поддержка миниатюр
	add_theme_support( 'post-thumbnails' );
}
add_action( 'after_setup_theme', 'wp_kama_theme_setup' );
Миниатюра записи

Другой пример, код заменит текст в подвале админ-панели WordPress, на данные о количестве запросов к базе данных, времени генерации страницы и использовании памяти:

/* 
 * Данные о количестве запросов к базе данных в подвале админки
 */
function wp_usage(){
	printf( ('SQL: %d за %s сек. '), get_num_queries(), timer_stop(0, 3) );
	if ( function_exists('memory_get_usage') ) echo round( memory_get_usage()/1024/1024, 2 ) . ' mb ';
}
add_filter('admin_footer_text', 'wp_usage');

// Если использовать фильтр wp_footer, то эти данные появятся в подвале сайта (шаблона).
// add_filter('wp_footer', 'wp_usage');
query к началу

functions.php против плагинов

"Плагины работают медленнее чем код в файле functions.php", говорят неосведомленные - это не так!

Нет никакой разницы в скорости работы кода, не важно подключается он через плагин или через файл functions.php. Все активные плагины записываются в опцию БД, которая загружается  и считывается в любом случае. А скорость подключения еще одного php файла - это такая мелочь, экономить на которой - все равно, что экономить на спичках имея хороший доход.

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

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

Поэтому, давайте удалим его из functions.php и сделаем из него плагин - это просто!

Чтобы создать плагин нужно создать файл с кодом ниже (название файла может быть любое), добавить его в каталог плагинов wp-content/plugins/ и активировать плагин в админ-панели:

<?php
/**
 * Plugin Name: Здесь любое название плагина
 */

// код плагина

add_filter('admin_footer_text', 'wp_usage');
function wp_usage(){
	printf( ('SQL: %d за %s сек. %s mb'), get_num_queries(), timer_stop(0, 3), round( memory_get_usage()/1024/1024, 2 ) );
}

Если нет желания видеть еще один плагин в админ-панели, то можно использовать Must-Use плагины.

к началу

Для чего на самом деле нужен functions.php

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

Если на каком-либо ресурсе вам предлагают добавить код в файл functions.php, а функция кода не относится к шаблону непосредственно, то не ленитесь сделайте плагин из этого кода и возможно в будущем избежите неожиданной пропажи добавленного ранее функционала.

к началу

Как подгружается functions.php

functions.php подключается во время инициализации текущей темы, после того, как подключены все функции WordPress и все активные плагины. Опишу коротко хронологию загрузки WordPress, где видно, когда подключаются важные файлы:

index.php
	wp-blog-header.php
		wp-load.php
			wp-config.php
				wp-settings.php
					// Подключаются самые базовые функции (подключение к БД $wpdb и система фильтров)
					// Подключаются базовые фильтры

					// SHORTINIT: Остановка загрузки, где есть только самое базовое: if ( SHORTINIT ) return false;

					// подключается вся среда WordPress: базовые функции, фильтры

					// подключаются must-use плагины, затем срабатывает событие:
					do_action( 'muplugins_loaded' );

					// подключаются активированные плагины, затем срабатывает событие:
					do_action( 'plugins_loaded' );

					// устанавливаются глобальные переменные: wp_the_query, wp_query, wp_rewrite, wp, wp_widget_factory, wp_roles ...

					do_action( 'setup_theme' );
					// устанавливается текущая тема
					// подключается файл темы >>>>>>>>>>>> functions.php <<<<<<<<<<<<
					do_action( 'after_setup_theme' );

					// событие, когда среда WP, все плагины и тема полностью подключены, но на экран еще ничего не выведено:
					do_action( 'init' );

					// проверка статуса сайта для мультисайтовой сборки

					// тоже самое что init только после проверки статуса (до этой строки работа PHP может не дойти)
					do_action( 'wp_loaded' );

		wp() // заполняет основной запрос WP и все глобальные переменные связанные с ним

		wp-includes/template-loader.php // подключает нужный файл шаблона

Процесс загрузки WordPress, и functions.php в частности, хорошо показан на этом рисунке:

Порядок загрузки ядра WordPress
Схема загрузки WordPress
к началу

Ошибки в functions.php при вставке кода

Неоднократно встречал вопросы об ошибках, вроде: "После установки кода в файл functions.php сайт перестал работать - белый экран. Что делать?". Я и сам с подобным сталкивался когда-то.

Для меня некоторые решения этой проблемы, долгое время, оставались загадкой — вроде ничего не делал, и даже танца с бубном не было, но - раз и все заработало. Почему так происходит? Давайте рассмотрим возможные ситуации из-за которых может "ломаться" сайт и их объяснение:

  1. Вставляете готовый код — сайт перестает работать.

  2. Редактируете functions.php — сайт перестает работать.

Чаще всего, дело в открывающем и закрывающем тегах PHP <?php и  ?>. Обычно, если вставляемый код имеет в начале и в конце эти теги, то их нужно удалить. Также, файл functions.php не должен выводить на экран никакой текст (HTML код или другой контент). Вывод текста допускается только внутри функции, которые в дальнейшем будут использоваться в шаблоне или которые прикрепляются к хукам (подробнее см. ниже).

Нельзя допускать никаких символов до <?php или после ?>, в том числе невидимые символы (перенос строки), потому что functions.php подключается до установки http заголовков (в таких заголовках передаются различные данные, например, что это html документ; что кодировка utf-8 другое). По правилам PHP, контент должен выводится на экран после того, как отправлены заголовки. А все что за пределами <?php и ?> это и есть контент - текст выводимый на экран, даже невидимый символ \n. Поэтому такой текст вызывает ошибку.

к началу

Чтобы не было ошибок, учитывайте 4 момента:

#1 Правильная вложенность

Пример, у нас была такая структура:

<?php
........здесь код.........
?>

Если Вы добавили php код так, то это вызовет ошибку или, что еще хуже, белый экран, когда показ ошибок отключен:

<?php
........здесь код.........
   <?php
   ...... здесь добавленный код ........
   ?>
........здесь код.........
?>

Правильно так:

<?php
........здесь код.........

   ........ здесь добавленный код ........

........здесь код.........
?>

#2 Никаких переносов строк, пробелов, текста до <?php и после ?>

Такой код вызовет ошибку:

<?php
 ...... здесь код ........
?>
<?php
 ...... здесь добавленный код ........
?>

А этот нет:

<?php
 ...... здесь код ........
?><?php
 ...... здесь добавленный код ........
?>

Логичнее его записать так:

<?php
 ...... здесь код ........

 ...... здесь добавленный код ........
?>

Бывает что перенос строки ставят в самом конце functions.php, вот тогда это становится настоящей проблемой, потому что все казалось бы правильно, но сайт не работает. На самом деле после ?> или  до <?php присутствуют невидимый символ переноса строки \n. Выглядит такая ошибка, крайне безобидно, вот так:

<?php
... начало файла ...
  ...... здесь код ........
... конец файла ...
?>
здесь пустая строчка

По этой причине многие разработчики вообще удаляют закрывающий тег ?>, это допустимо для PHP:

<?php
... начало файла ...
  ...... здесь код ........
... конец файла ...
к началу

#3 Использование <?php и ?> внутри PHP функции

Если в functions.php присутствует функция, то внутри этой функции можно использовать теги <?php и ?>, например, для того, чтобы визуально выделить HTML код внутри функции:

<?php
... начало файла ...

function function_name(){
	?>
		 <div>это html код</div>
	<?php 
}

... конец файла ...
?>

Дело в том, что в этом случае функция только лишь регистрируется и не выполняет никаких действий. Все что внутри функции (между { }) не работает пока эта функция не будет вызвана, а вызываются такие функции обычно из шаблона или через фильтры, уже после того как отправлены HTTP заголовки. Поэтому в данном примере, мы можем игнорировать переносы строк и использовать ?> и <?php как угодно.

к началу

#4 Кодировка

Еще одна заметка касательно файла functions.php: устанавливайте файлу кодировку UTF-8 (UTF-8 без BOM). Иначе, если функции в файле будет текст на кириллице, то он выведется непонятными символами: кракозябрами, каракулями - называйте как хотите.

Http://smartpotolki.ru/

Глянцевые потолки http://smartpotolki.ru/ лучшие предложения по продаже натяжных потолков в Самаре.

smartpotolki.ru

Файл темы functions.php в WordPress 49 комментариев
Полезные 1 Вопросы 1 Все
  • Колян

    Начинающим разработчикам - самое то!

    Ответить2.4 года назад #
  • Катерина cайт: melodiyadushi.ru

    Только, что пережила стресс изза белого экрана!!! хорошо ума хватило не выйти из админки smile пробовала в редакторе вставить код из заново скачанной этой же темы - не помогало, заменила фанкшин.пхп на хостинге - не помогло, тогда я удалила совсем папку темы с хоста и активировалась другая тема, после этого уже из консоли залила заново ту же тему, которую убила smile и счастье есть!!! почти ничего не потерялось, кроме кнопок соц сетей, которые куда-то в тему были вставлены.
    Прочитала вашу статью и поняла, что не так сделала smile спасибо!!! буду ещё аккуратнее smile
    и для кнопок какой-нибудь плагин найду smile
    у меня, кстати, вот эти теги были у кода шорткода вот так:
    и всё сломалось!

    Ответить2 года назад #
  • Ivan cайт: v-svetlograde.ru
    @

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

    Ответить1.4 года назад #
  • Dasha

    Подскажите, пожалуйста: пишу тему с нуля, восползовавшись рекомендациями из этой статьи добавила в functions.php строку add_theme_support('post-thumbnails');, поле "Задать миниатюру" появилось, но когда кликаешь по ссылке, открывшееся окно с медиафайлами грузится, но ничего не происходит. Добавила новое изображение, перейдя по другой вкладке этого окна - изображение на панели "Задать миниатюру" не появилось. И редактировать изображение в этом окне(Миниатюра записи) нельзя - просто белый фон окна. Проверку на существование функции делала (if ( function_exists('add_theme_support') )) - тот же результат. Заранее спасибо)

    • campusboy1751 cайт: wp-plus.ru

      Привет. У меня такое бывало, когда пользовался слабым хостингом, а точнее хостинг выделял мало памяти (32Мб, да-да, такое когда-то было). Попробуйте на всякий случай прописать в wp-config.php (корень сайта) строку:

      define('WP_MEMORY_LIMIT', '32M');

      А лучше 64M там указать.

    • Kama4477

      У вас изображения вообще в папку uploads загружаются? Промежуточные размеры создаются? Может на хосте GD или Imagick библиотеки нет?

      • Dasha

        Я на локале делаю. В библиотеку грузятся.

        • Dasha

          Проблема решилась переустановкой WordPress. После добавления строки в конфиги - появилась fatalerror, ругался, на class-wp-roles.php, а именно на строку с final class WP_Post_Type.

  • Паша

    Здравствуйте!
    Нужно ли что-то прописывать в functions.php чтобы работали плагины?
    Я натянул верстку на вордпресс, и захотел установить плагин (слайдер), но он не заработал, я предполагаю, что он не может подключить свои библиотеки и стили.
    Как быть?

  • Сер

    нельзя показать наглядно о чем речь? неужели не понятно что без скринов с экрана ВСЕГО монитора ничего не понятно

    • Kama4477

      Извините. Если вы про пример использования, то это не суть статьи... Поэтому обрезки такие... Суть в тексте, а не скринах. Скрины - это только примеры их вообще можно опустить...

      1
  • Александр

    Добрый день!

    Не могу разобраться в схеме подгрузки functions.php. Есть задача использовать переменную объявленную в functions.php в теле шаблона. Если обращаться к ней из файла index.php то всё в порядке, но если использовать конструкцию:
    get_template_part( 'part') и обращаться к переменной внутри 'part' то она уже не работает. Подозреваю, что функция get_template_part() выполняется раньше чем подгружается functions.php и на этот момент переменная просто еще не объявлена (кстати а где должна быть об этом ошибка?).

    Возможно объявление переменных в functions.php в целом плохая идея и можно делать это как то по другому?

    Заранее спасибо.

    • campusboy1751 cайт: wp-plus.ru

      Привет! Изучи тему видимости переменных в PHP и всё поймешь. Быстрое решение - используй в get_template_part( 'part') в самом начале

      <?php global $my_var; ?>

Здравствуйте, !

Ваш комментарий