Вопрос или проблема
Я совершенно новичок в PHP и веб-разработке. Я создал фронтенд-страницу редактирования профиля для пользователей, и все поля обновляются, кроме электронной почты (но всё остальное – это метаданные пользователя). Я потратил на это слишком много времени безуспешно.
Есть много сообщений на эту тему, например, это Как обновить user_email на фронтенде в WP 3.3?, но ни один из предложенных методов не работает у меня. Я использую WP 4.7.3.
Вот это из вышеупомянутого сообщения. Этот способ обновляет электронную почту, но после отправки формы моя страница зависает на неопределенное время:
wp_update_user( array( 'ID' => $current_user->ID, 'user_email' => $_POST['email'] ) );
Я также попробовал этот способ. Он не обновляет электронную почту пользователя и не зависает:
$wpdb->update($wpdb->users, array('user_email' => $_POST['email']), array('ID' => $current_user->ID));
Любые советы будут очень признательны. Я довольно уверен, что проблема заключается только в этом фрагменте кода, но могу включить больше кода, если это поможет.
Отредактировано: обновлён код профиля пользователя. Оказывается, пароль тоже зависает на неопределенное время.
if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {
/* Обновление информации о пользователе. */
// Электронная почта
if (isset( $_POST['email'])) {
// проверяем, действительно ли пользователь обновляет значение
if ($user_email != $_POST['email']) {
// проверяем, свободна ли электронная почта для использования
if (email_exists( $_POST['email'] )){
// Электронная почта уже существует, не обновлять значение.
$error[] = __('Этот email уже используется.', 'profile');
}
else if (!is_email( $_POST['email'] )){
// Неправильный формат электронной почты.
$error[] = __('Email в неправильном формате.', 'profile');
}
else {
wp_update_user( array( 'ID' => $current_user->ID, 'user_email' => $_POST['email'] ) );
//$wpdb->update($wpdb->users, array('user_email' => $_POST['email']), array('ID' => $current_user->ID));
}
}
}
// Пароль
if ( !empty($_POST['pass1'] ) && !empty( $_POST['pass2'] ) ) {
if ( $_POST['pass1'] == $_POST['pass2'] )
wp_update_user( array( 'ID' => $current_user->ID, 'user_pass' => esc_attr( $_POST['pass1'] ) ) );
else {
$error[] = __('Пароли не совпадают.', 'profile');
}
}
// Имя
if ( !empty( $_POST['first-name'] ) ){
update_user_meta( $current_user->ID, 'first_name', esc_attr( $_POST['first-name'] ) );
}
// Фамилия
if ( !empty( $_POST['last-name'] ) )
update_user_meta($current_user->ID, 'last_name', esc_attr( $_POST['last-name'] ) );
// Год рождения
if ( !empty( $_POST['birth_year'] ) ) {
// Убедитесь, что это только цифры
if (!ctype_digit($_POST['birth_year'])){
$error[] = __('Введите год.', 'profile');
}
else
update_user_meta($current_user->ID, 'birth_year', esc_attr( $_POST['birth_year'] ) );
}
// Телефон
if ( !empty( $_POST['phone'] ) ) {
update_user_meta($current_user->ID, 'phone', esc_attr( $_POST['phone'] ) );
}
// Улица
if ( !empty( $_POST['address'] ) )
update_user_meta($current_user->ID, 'street_address', esc_attr( $_POST['address'] ) );
// Город
if ( !empty( $_POST['city'] ) )
update_user_meta($current_user->ID, 'city', esc_attr( $_POST['city'] ) );
// Штат
if ( !empty( $_POST['state'] ) )
update_user_meta($current_user->ID, 'state', esc_attr( $_POST['state'] ) );
// Имя родителя
if ( !empty( $_POST['p_first_name'] ) )
update_user_meta($current_user->ID, 'player_parent_first_name', esc_attr( $_POST['p_first_name'] ) );
// Фамилия родителя
if ( !empty( $_POST['p_last_name'] ) )
update_user_meta($current_user->ID, 'player_parent_last_name', esc_attr( $_POST['p_last_name'] ) );
// Email родителя
if (isset( $_POST['p_email'])) {
// проверяем, действительно ли пользователь обновляет значение
if ($user_email != $_POST['p_email']) {
if (!is_email( $_POST['p_email'] )){
// Неправильный формат электронной почты.
$error[] = __('Email родителя в неправильном формате.', 'profile');
}
else {
$args = array(
'ID' => $current_user->id,
'player_parent_email' => esc_attr( $_POST['p_email'] )
);
wp_update_user( $args );
}
}
}
// Телефон родителя
if ( !empty( $_POST['p_phone'] ) ) {
update_user_meta($current_user->ID, 'player_parent_phone', esc_attr( $_POST['p_phone'] ) );
}
/* Перенаправление, чтобы страница показывала обновленную информацию. */
// Убедитесь, что нет ошибок
if ( count($error) == 0 ) {
echo "redirecting";
// хук действия для плагинов и сохранения дополнительных полей
do_action('edit_user_profile_update', $current_user->ID);
wp_redirect( get_permalink().'?updated=true' );
exit;
}
else {
// вывод ошибок здесь
}
}
Я заставил это работать с использованием $wpdb->update:
$ID = $current_user->ID;
$email = sanitize_email($_POST['email']);
$wpdb->update($wpdb->users, array('user_email' => $email), array('ID' => $ID));
К сожалению, точно не уверен, в чём была проблема с wp_update_user.
Ответ или решение
Чтобы обновить электронную почту пользователя на фронтальной стороне в WordPress версии 4.7.3, важно понять разницу между функциями и подходами, которые вы использовали. Вас интересуют методы wp_update_user()
и непосредственное обновление базы данных через $wpdb
.
Проблема:
Вы упомянули, что wp_update_user()
приводит к зависанию страницы, в то время как $wpdb->update()
выполняет обновление без проблем. Давайте разберем, почему это может происходить, и как правильно использовать каждую из этих функций.
1. Функция wp_update_user()
:
Эта функция является встроенной в WordPress и предназначена для обновления данных профиля пользователя через массив параметров. Основные преимущества:
- Обрабатывает различные проверки, такие как валидация формата email и проверка на уникальность.
- Безопасно взаимодействует с базой данных, используя встроенные методы WordPress.
Однако зависание может происходить из-за нескольких факторов:
- Проблемы с редиректом: Возможно, ваш код зацикливается из-за неправильно настроенного редиректа, особенно если
wp_redirect()
вызывается до завершения всех процессов. - Ошибки валидации: Неправильная обработка ошибок может привести к неопределенному состоянию скрипта.
- Плагины или темы: Они также могут вмешиваться в работу, используя хуки или фильтры.
2. Метод $wpdb->update()
:
Этот подход заключается в непосредственном обновлении записи в таблице wp_users
. Использование $wpdb
позволяет более точно контролировать SQL-запросы, но требует осторожности:
- Необходимо вручную обрабатывать всю валидацию и ошибочные состояния.
- Всегда используйте функции для очистки данных, такие как
sanitize_email()
в вашем коде, чтобы предотвратить SQL-инъекции и другие уязвимости.
Рекомендуемое решение:
-
Диагностика зависания:
- Проверьте, не вызывается ли
wp_redirect()
без выхода из скрипта сexit;
. - Убедитесь, что все хуки обработаны правильно: не создавайте лишние цепочки с
do_action()
.
- Проверьте, не вызывается ли
-
Использование
wp_update_user()
:if (!email_exists($_POST['email'])) { $updated_user_id = wp_update_user(array( 'ID' => $current_user->ID, 'user_email' => sanitize_email($_POST['email']) )); if (is_wp_error($updated_user_id)) { $error[] = __('Не удалось обновить email.', 'profile'); } } else { $error[] = __('Этот email уже используется.', 'profile'); }
-
Ошибки и валидация:
- Добавьте обработку ошибок и валидацию прямо в форму и/или контроллер, чтобы ядро WordPress их понимало.
Заключение:
Выбор между wp_update_user()
и $wpdb->update()
зависит от требований безопасности и удобства. Для типичных сценариев предпочтительным будет использование wp_update_user()
из-за его интеграции с системой WordPress. Однако $wpdb->update()
подходит для случаев, когда требуется избежать встроенных проверок WordPress.
Если вы продолжаете сталкиваться с проблемами, настоятельно рекомендую посмотреть журнал ошибок сервера или использовать инструмент для профилирования скрипта, такой как Query Monitor, чтобы детализировать, почему это происходит.