Как передать переменную JavaScript в PHP в виджете WordPress?
Я потратил много времени на поиск решения, где можно передать значение переменной JavaScript в PHP переменную в том же файле, той же функции (Виджет WordPress, функция Form). Есть ли хороший способ сделать это в 2017 году?
Я пробовал метод ниже. Хотя Ajax часть выводит сообщение об успехе, PHP часть не работает.
repeat.php
<?php
echo $_POST['examplePHP']; //вызовет ошибку undefined index здесь
?>
<script>
jQuery(document).ready(function($){
var exampleJS = "hi!";
$.ajax({
url: ajaxurl, //Я пробовал 'repeat.php' вместо ajaxurl, но не работает
type: 'POST',
data: {
examplePHP: exampleJS
},
success: function( response){
console.log("Успешно!");
},
error: function(error){
console.log("Ошибка");
}
});
});
</script>

Я нашел простой способ передать переменную из JavaScript в переменную PHP. Обратите внимание, что этот метод работает в WordPress версии 4.7.2 и только конкретно для виджетов. Я добавил много комментариев, чтобы объяснить, что делает каждая строка. Если у вас есть лучшее решение, поделитесь с нами!
Решение:
- Создайте скрытое поле ввода для хранения значения из JavaScript, которое вы хотите передать.
- Получите доступ к этому скрытому полю и присвойте его значение переменной PHP.
Демо-виджет:
Я создал демо-виджет, который добавляет слово "ЛЮБЛЮ ТЕБЯ" столько раз, сколько вы нажмете кнопку "Добавить ЛЮБЛЮ ТЕБЯ".
Обратите внимание, что я оставил скрытое поле видимым для лучшего понимания.
Вы можете изменить
type="text"
наtype="hidden"
, чтобы скрыть его.Это демо фокусируется только на функции
form
виджета.Обязательно нажмите кнопку Сохранить, иначе значение скрытого поля не будет сохранено виджетом.
Скриншот демо-виджета:
Исходный код:
wp-text-repeater.php
<?php
/**
* Название плагина: WP Text Repeater
**/
class wp_text_repeater extends WP_Widget {
/**
* Устанавливает название и параметры виджета
*/
public function __construct() {
$widget_ops = array(
'classname' => 'wp_text_repeater',
'description' => 'Виджет, который выводит "ЛЮБЛЮ ТЕБЯ" повторно в зависимости от нажатий кнопки',
);
parent::__construct( 'wp_text_repeater', 'WP Text Repeater Widget', $widget_ops );
}
/**
* Выводит содержимое виджета
*
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
// выводит содержимое виджета
$wp_text_repeater_button = ! empty( $instance['wp_text_repeater_button'] ) ? $instance['wp_text_repeater_button'] : '';
$wp_text_repeater_appendee = ! empty( $instance['wp_text_repeater_appendee'] ) ? $instance['wp_text_repeater_appendee'] : '';
$wp_text_repeater_hidden = ! empty( $instance['wp_text_repeater_hidden'] ) ? $instance['wp_text_repeater_hidden'] : '';
}
/**
* Выводит форму настроек в админке
*
* @param array $instance Параметры виджета
*/
public function form( $instance ) {
// выводит форму настроек в админке
$instance = wp_parse_args( (array) $instance, array( 'wp_text_repeater_button' => '', 'wp_text_repeater_appendee' => '', 'wp_text_repeater_hidden' => ''));
$wp_text_repeater_button = $instance['wp_text_repeater_button'];
$wp_text_repeater_appendee = $instance['wp_text_repeater_appendee'];
$wp_text_repeater_hidden = $instance['wp_text_repeater_hidden'];
$tempHidden = 'wp_text_repeater_hidden';
?>
<!-- Скрытое поле, хранящее количество нажатий кнопки пользователем -->
<input
class="widefat"
id="<?php echo $this->get_field_id($tempHidden); ?>"
name="<?php echo $this->get_field_name($tempHidden); ?>"
type="text"
value="<?php echo esc_attr($$tempHidden);?>"/>
<?php
$max = 0; //Количество нажатий кнопки пользователем
//Если скрытое поле JavaScript на фронтенде имеет значение, присвоить $max это значение.
//Это условие синхронизирует JavaScript и PHP части.
if(strlen($$tempHidden) > 0){
$max = intval($$tempHidden);
}
$counter = 0;
while($counter < $max){ //цикл по количеству нажатий кнопки
?>
<p>ЛЮБЛЮ ТЕБЯ!</p>
<?php
$counter++;
}
$id_prefix = $this->get_field_id(''); //получить префикс ID виджета.
?>
<!-- Сюда можно добавлять весь ваш контент -->
<span id="<?php echo $this->get_field_id('wp_text_repeater_appendee')?>"></span>
<!-- Кнопка, вызывающая jQuery функцию для добавления слова "ЛЮБЛЮ ТЕБЯ" -->
<input style="background-color: #08a538; color:white; height: 27px;"
class="button widefat"
type="button"
id="<?php echo $this->get_field_id('wp_text_repeater_button'); ?>"
value="Добавить ЛЮБЛЮ ТЕБЯ"
onclick="text_repeater.addLove('<?php echo $this->id;?>', '<?php echo $id_prefix;?>'); return false;"
/>
<script>
jQuery(document).ready(function($){
var preIndexID;
var numberOfLove = <?php echo $max; ?>; //получить значение из PHP для синхронизации фронтенда и бэкенда.
text_repeater = {
addLove :function(widget_id, widget_id_string){
preIndexID = widget_id_string; //получить правильный префикс ID виджета.
numberOfLove++;
numberOfLove = numberOfLove.toString(); //конвертировать число в строку для скрытого поля.
$("#" + preIndexID + "wp_text_repeater_hidden").val(numberOfLove); //изменить значение скрытого поля.
$("#" + preIndexID + "wp_text_repeater_appendee").append('<p>ЛЮБЛЮ ТЕБЯ!</p>'); //динамически обновить фронтенд с "ЛЮБЛЮ ТЕБЯ".
}
}
});
</script>
<?php
}
/**
* Обработка параметров виджета при сохранении
*
* @param array $new_instance Новые параметры
* @param array $old_instance Предыдущие параметры
*/
public function update( $new_instance, $old_instance ) {
// обрабатывает параметры виджета для сохранения
$instance = $old_instance;
$instance['wp_text_repeater_button'] = sanitize_text_field($new_instance['wp_text_repeater_button']);
$instance['wp_text_repeater_appendee'] = sanitize_text_field ($new_instance['wp_text_repeater_appendee']);
$instance['wp_text_repeater_hidden'] = sanitize_text_field( $new_instance['wp_text_repeater_hidden'] );
return $instance;
}
}
// регистрация виджета wp_text_repeater
function register_wp_text_repeater_widget() {
register_widget( 'wp_text_repeater' );
}
add_action( 'widgets_init', 'register_wp_text_repeater_widget' );

Помните, что код выполняется сверху вниз.
Таким образом, вы не можете получить переменную POST до её отправки через AJAX.
Вот пример, который сработает в вашей настройке:
<?php
if(isset($_POST['examplePHP'])){ //проверяем, существует ли $_POST['examplePHP']
echo $_POST['examplePHP']; // выводим данные
die(); // останавливаем выполнение скрипта.
}
?>
<script>
jQuery(document).ready(function($){
var exampleJS = "Привет!";
$.ajax({
url: window.location, //window.location указывает на текущий URL. при необходимости измените.
type: 'POST',
data: {
examplePHP: exampleJS
},
success: function( response){
console.log("Успешно! Мои POST-данные: "+response);
},
error: function(error){
console.log("Ошибка");
}
});
});
</script>
Сначала мы проверяем существование переменной POST с помощью isset()
. Если она существует, мы выводим содержимое 'examplePHP' и останавливаем выполнение скрипта с помощью die();
.
Если переменная POST отсутствует, это означает, что кто-то просто загружает страницу. В этом случае мы не выводим данные, а продолжаем работу с остальной частью страницы.
Я добавил window.location
, который указывает на текущий URL. А переменная response
содержит выведенные данные.
Поскольку это WordPress Stack Exchange, я рекомендую использовать WordPress AJAX. Подробнее об этом можно прочитать на странице Codex!
