Вопрос или проблема
get_option() не возвращает ожидаемое значение из плагина
Я пытаюсь создать свой первый плагин, и пока все было хорошо, за исключением одной маленькой раздражающей вещи. У меня настроены поля, обновляющие данные, и они выглядят нормально в моей базе данных:
mfwp_settings | a:1:{i:test;s:3:"response";}
Но когда я хочу вывести значение для ‘test’ в своей административной панели, оно возвращается пустым или NULL. Оно выводится нормально на фронтенде, но в плагине не удается извлечь данные, используя следующее:
$mfwp_opt = get_option('mfwp_settings')['test'];
Снова, вышеуказанное работает нормально в обычном PHP на фронтенде. Поэтому я могу только предположить, что проблема связана с отсутствующим ‘путем’ и/или ‘включениями’ в главном PHP плагина.
Так что… нужен ли мне специальный путь, который нужно указать в главном PHP плагина?
Я указал ABPATH на случай, если это то, что нужно, но безуспешно:
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
Я думал, что мог бы скопировать и настроить функцию ‘get_option’ и использовать ее в своем плагине, но это кажется ненужным. Поэтому любая помощь будет оценена!
Редактировать
Чтобы быть более ясным, я привел ниже PHP, с которым работаю. Все в PHP работает нормально, КРОМЕ того, что он не может вызвать get_option
или извлечь данные через $wpdb
.
<?php
// Инициализация глобальных переменных
global $wpdb;
// ПЫТАЛСЯ вызвать нормально через get_option, но не получилось
$test = get_option( 'mfwp_settings' );
// ПЫТАЛСЯ вызвать через SQL, но возвращается NULL
$get_settings = $wpdb->get_results ( "
SELECT *
FROM $wpdb->wp_options
WHERE option_name = mfwp_settings
LIMIT 1
" );
$field1 = get_option( mfwp_settings );
// Создание опции в меню администратора
add_action('admin_menu', function () {
add_options_page(
// ИЗМЕНИТЕ
'Мой Первый WordPress Плагин', // заголовок браузера
// ИЗМЕНИТЕ
'MFWP', // текст меню
// ОСТАВИТЬ
'manage_options', // требует возможности **ОСТАВИТЬ как manage_options**
// ИЗМЕНИТЕ
'mfwp_admin', // слаг для ссылки
// ИЗМЕНИТЕ
'mfwp_options_page' // обратный вызов для тела меню
);
}
);
// Обратный вызов и создание тела - ИЗМЕНИТЕ префикс
function mfwp_options_page() {
//ob_start(); ?>
<div class="wrap">
<h2>Опции Мого Первого Плагина WordPress</h2>
<form method="post" action="options.php">
<?php
settings_fields( 'mfwp_settings_group' );
?>
<h4><?php _e('Место для полей плагина', 'mfwp_domain'); ?></h4>
<p><?php echo $field1 . ' тестер<br />'; echo var_dump($get_settings);?>
<label class="description" for="mfwp_settings"><?php _e('Это описание метки', 'mfwp_domain'); ?></label>
<input class="regular-text" id="mfwp_settings" name="mfwp_settings" type="" value="<?php echo $test; ?>">
</p>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e('Сохранить опцию', 'mfwp_domain'); ?>">
</p>
</form>
</div>
<?php
//echo ob_get_clean();
}
function mfwp_register_settings() {
$args = array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field', // Очистка данных
'default' => NULL,
);
register_setting('mfwp_settings_group', 'mfwp_settings', $args);
}
add_action('admin_init', 'mfwp_register_settings');
Похоже, что ваши сериализованные настройки повреждены. Я создал опцию mfwp_settings
со значением array( 'test' => 'response' )
. Когда я смотрю на это в базе данных, значение хранится как сериализованный массив и выглядит так:
a:1:{s:4:"test";s:8:"response";}
Вот простая функция отладки, которая успешно возвращает ожидаемое значение response
для test
:
add_action( 'init', 'wpse_option_test' );
function wpse_option_test() {
// Пример данных. В сериализованном виде это будет выглядеть так: a:1:{s:4:"test";s:8:"response";}
$settings_value = array( 'test' => 'response' );
add_option( 'mfwp_settings' );
update_option( 'mfwp_settings', $settings_value );
$mfwp_settings = get_option( 'mfwp_settings' )['test'];
// Вывод значения для отладки. Результат: string(8) "response"
exit ( var_dump( $mfwp_settings ) );
}
Чтобы работать с плагинами WordPress, вам нужно полагаться на хуки (фильтры и действия). В данный момент вы пытаетесь выполнить какую-то функцию WordPress в сыром PHP файле, так что в большинстве случаев WordPress может вообще не быть инициализирован.
Таким образом, в вашем примере кода $test = get_option( 'mfwp_settings' );
должно работать, но вам нужно поместить это внутрь функции mfwp_options_page
, если вы хотите использовать это там.
Но еще лучше было бы структурировать ваш код в классы, вместо того чтобы держать все в одном файле.
Мой образец для плагинов выглядит так:
У меня структура файлов такая
- assets
- - js
- - css
- includes
- - class-your-plugin.php
- views
- your-plugin.php
Папка assets с JS и CSS, я думаю, ясна, views – это папка для… ну… файлов представлений, а includes – для PHP классов. (Согласно стандартам кодирования WordPress, вы должны начинать название файлов с классов с class-).
your-plugin.php прост:
<?php
/*
Название плагина: Название вашего плагина
URL плагина: URL вашего плагина
Версия: 1.0.0
Автор: Ваше имя
URL автора: URL на вашу страницу
Описание: Описание плагина
Текстовый домен: your-plugin
Путь домена: /languages
*/
// Прекратить выполнение, если вызван напрямую.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
include_once dirname( __FILE__ ) . '/includes/class-my-plugin.php';
$my_plugin = My_Plugin::get_instance();
Как видите, здесь вы только вызываете экземпляр вашего плагина, вы можете делать здесь больше, но для начала этого должно быть достаточно.
А class-your-plugin.php выглядит так:
<?php
class Your_Plugin
{
/**
* Синглтон Your_Plugin
*
* @var Your_Plugin
*/
protected static $_instance = null;
/**
* Путь к your-plugin (например, /public_html/wp-content/plugins/your-plugin)
*
* @var string
*/
protected $basedir = null;
/**
* URL к your-plugin (например, http://example.com/wp-content/plugins/your-plugin)
*
* @var string
*/
protected $baseurl = null;
/**
* Конструктор объекта
*
* Защищенный конструктор позволяет создать только один экземпляр этого класса.
*
* @since 1.0
* @return Your_Plugin
*/
protected function __construct() {
$this->basedir = dirname( dirname( __FILE__ ) );
$this->baseurl = plugin_dir_url( dirname( __FILE__ ) );
add_action( 'init', array( $this,'init' ) );
add_action( 'admin_init', array( $this, 'mfwp_register_settings' ) );
}
/**
* Синглтон
*
* Создает, если NULL, и возвращает экземпляр Your_Plugin
*
* @since 1.0
* @return Your_Plugin
*/
public static function get_instance() {
if( self::$_instance === null ) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Возвращает путь basedir
*
* @since 1.0
* @return string Путь basedir (например, /public_html/wp-content/plugins/your-plugin)
*/
public function get_basedir() {
return $this->basedir;
}
/**
* Возвращает базовый URL плагина
*
* @since 1.0
* @return string Путь basedir (например, http://example.com/wp-content/plugins/your-plugin)
*/
public function get_baseurl() {
return $this->baseurl;
}
/**
* Общая функция инициализации
*
* Эта функция выполняется как на фронтенде, так и в wp-admin
*
* @since 1.0
* @return void
*/
public function init() {
}
public function mfwp_register_settings() {
}
}
Теперь вы можете полагаться на хуки и строить на их основе.
Ответ или решение
Проблема, с которой вы столкнулись, связана с тем, что значение, получаемое из функции get_option()
, не соответствует ожиданиям. Давайте разберемся с вашей проблемой и предложим решение.
Первоначально вы привели пример, где ваше значение было сохранено в базе данных в сереализованном виде как a:1:{i:test;s:3:"response";}
. Однако, правильный вид для массива должен выглядеть как a:1:{s:4:"test";s:8:"response";}
. Из-за этого значения вы не можете получить данные с помощью get_option()
.
1. Измените сохранение опции
Убедитесь, что вы корректно сохраняете опции. Используйте следующий механизм для обновления опции:
$settings_value = array( 'test' => 'response' );
update_option( 'mfwp_settings', $settings_value );
2. Подходящее место для вызова get_option()
Вы должны убедиться, что вызов get_option()
происходит в правильном месте, где все необходимые функции WordPress уже инициализированы. Для этого переместите вызов get_option()
в вашу функцию обратного вызова mfwp_options_page
.
Пример:
function mfwp_options_page() {
// Получаем опцию внутри функции
$mfwp_settings = get_option('mfwp_settings');
$field1 = isset($mfwp_settings['test']) ? $mfwp_settings['test'] : ''; // Защита от доступа к несуществующему индексу
echo '<div class="wrap">';
echo '<h2>Мои параметры плагина</h2>';
echo '<form method="post" action="options.php">';
settings_fields('mfwp_settings_group');
echo '<h4>' . __('Placeholder for Plugin Fields', 'mfwp_domain') . '</h4>';
echo '<p>' . esc_html($field1) . ' tester<br /></p>';
echo '<label class="description" for="mfwp_settings">' . __('Это описание метки', 'mfwp_domain') . '</label>';
echo '<input class="regular-text" id="mfwp_settings" name="mfwp_settings[test]" type="text" value="' . esc_attr($field1) . '" />';
echo '<p class="submit"><input type="submit" class="button-primary" value="' . __('Сохранить параметр', 'mfwp_domain') . '" /></p>';
echo '</form>';
echo '</div>';
}
3. Регистрация параметров
Ваша функция mfwp_register_settings
должна быть выставлена правильно для регистрации вашего параметра:
function mfwp_register_settings() {
register_setting('mfwp_settings_group', 'mfwp_settings');
}
4. Проверка правильности внедрения
Убедитесь, что ваш код использует WordPress Hooks корректно. Например:
add_action('admin_init', 'mfwp_register_settings');
add_action('admin_menu', function () {
add_options_page('Мой первый плагин WordPress', 'MFWP', 'manage_options', 'mfwp_admin', 'mfwp_options_page');
});
5. Структурирование кода
Рекомендуется структурировать код в объекты и классы, чтобы облегчить управление плагином и улучшить читаемость. Попробуйте использовать подход классов для реализации функций вашего плагина.
Заключение
Следуя вышеизложенным шагам, вы сможете корректно получать значения опций через get_option()
, а также отображать их на вашей странице администратора. Убедитесь, что вы избегаете ошибок получения данных и всегда проверяете наличие данных, прежде чем их использовать.