Ошибка "headers already sent" при использовании wp_redirect после формы отправки на фронтенде

14 янв. 2013 г., 23:24:25
Просмотры: 16.6K
Голосов: 2

Я пытаюсь создать форму для отправки постов через фронтенд и получаю следующую ошибку:

Warning: Cannot modify header information - headers already sent by (output started at /home/sadlight/public_html/members/wp-content/themes/default-child/announcement-submit.php:1) in /home/sadlight/public_html/members/wp-includes/pluggable.php on line 876

announcement-submit.php - это мой шаблон, приведенный ниже.

Я пробовал это решение, но безрезультатно.

Также, когда я использую wp_redirect в моем коде ниже, он вставляет ДВА поста вместо одного. Когда я удаляю его, добавляется только один пост. Любая помощь будет очень полезна!

Дополнительная информация: я использую Buddypress с темой по умолчанию Buddypress.

<?php

/*
 * Шаблон: Announcement Submit
  */

$postTitleError = '';
if ( isset( $_POST['submitted'] ) ) {
    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Пожалуйста, введите заголовок.';
        $hasError = true;
    }
}


get_header(); ?>

    <div id="content">
        <div class="padder">

            <form action="" id="primaryPostForm" method="POST">
                <fieldset>
                    <label for="postTitle"><?php _e('Заголовок поста:', 'framework') ?></label>
                    <input type="text" name="postTitle" id="postTitle" class="required" value="<?php if ( isset( $_POST['postTitle'] ) ) echo esc_attr( stripslashes( $_POST['postTitle'] ) ); ?>" />
                </fieldset>
                <fieldset>
                    <?php wp_editor( 'Тестовый контент', 'postcontent'); ?>
                </fieldset>
                <fieldset>
                    <?php wp_nonce_field( 'post_nonce', 'post_nonce_field' ); ?>
                    <input type="hidden" name="submitted" id="submitted" value="true" />
                    <button type="submit"><?php _e('Добавить пост', 'framework') ?></button>
                </fieldset>
            </form>

            <?php if ( $postTitleError != '' ) { ?>
                <span class="error"><?php echo $postTitleError; ?></span>
                <div class="clearfix"></div>
            <?php } ?>

            <?php
                if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
                    if ( trim( $_POST['postTitle'] ) === '' ) {
                        $postTitleError = 'Пожалуйста, введите заголовок.';
                        $hasError = true;
                    }
                    $post_information = array(
                        'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
                        'post_content' => wp_kses_post( $_POST['postcontent'] ),
                        'post_type' => 'post',
                        'post_status' => 'pending'                                      
                    );
                    wp_insert_post( $post_information );                    
                }

                $post_id = wp_insert_post( $post_information );

                if ( $post_id ) {
                    wp_redirect( home_url() );
                    exit;                   
                }
            ?>

        </div><!-- .padder -->
    </div><!-- #content -->

    <?php get_sidebar(); ?>

<?php get_footer(); ?>
2
Комментарии

Проверьте этот ответ http://wordpress.stackexchange.com/a/76993/10413

Anagio Anagio
14 янв. 2013 г. 23:33:11

Спасибо за ваш ответ. Это исправило ошибку, но не добавило запись. :(

Josh Josh
15 янв. 2013 г. 00:11:21
Все ответы на вопрос 3
3

Как отметил Отто, вы отправляете данные в браузер перед вызовом wp_redirect().

  • get_header() выводит HTML <head> страницы
  • Вы выводите всю форму на страницу перед её обработкой.

Чтобы исправить проблему "headers already sent", вам нужно переместить всю обработку формы из нижней части страницы в её начало. Если вам нужно вызвать wp_redirect(), этот вызов должен быть сделан до вывода чего-либо - HTML или другого содержимого - на страницу.

Что касается дублирования записи, у вас дважды вызывается wp_insert_post() в коде:

if ( isset( $_POST['submitted'] ) && isset( $_POST['post_nonce_field'] ) && wp_verify_nonce( $_POST['post_nonce_field'], 'post_nonce' ) ) {
    if ( trim( $_POST['postTitle'] ) === '' ) {
        $postTitleError = 'Пожалуйста, введите заголовок.';
        $hasError = true;
    }
    $post_information = array(
        'post_title' => wp_strip_all_tags( $_POST['postTitle'] ),
        'post_content' => wp_kses_post( $_POST['postcontent'] ),
        'post_type' => 'post',
        'post_status' => 'pending'                                      
    );
    wp_insert_post( $post_information );                    
}

$post_id = wp_insert_post( $post_information );

Таким образом, вы пытаетесь вставить запись при каждой загрузке страницы, но если ничего не отправлено, переменная $post_information не будет установлена и ничего не вставится. Однако при отправке формы вы создаёте новую запись как внутри проверки условия, так и за её пределами.

15 янв. 2013 г. 00:33:29
Комментарии

Кроме того, лучше перенести всю обработку формы в файл функций и подключиться к какому-нибудь хуку, например template_redirect, где вы уверены, что ничего еще не было отправлено в браузер.

Mateusz Hajdziony Mateusz Hajdziony
15 янв. 2013 г. 00:40:20

Спасибо! Это именно то, что я бы предпочел сделать для разделения логики. Однако последний час я пытаюсь лучше понять, как использовать template_redirect или что он вообще делает. Я в замешательстве.

Josh Josh
15 янв. 2013 г. 01:59:37

Что ж, я разделил обработку. И это сработало! Я сделаю имена $_POST уникальными, чтобы они не конфликтовали с чем-либо еще.

Josh Josh
15 янв. 2013 г. 02:10:53
4

заголовки уже отправлены (вывод начат в /home/sadlight/public_html/members/wp-content/themes/default-child/announcement-submit.php:1)

Сообщение об ошибке точно указывает на проблему.

Файл "announcement-submit.php" - это место, где возникла проблема.

Цифра "1" указывает на номер строки с ошибкой.

Это означает, что у вас есть что-то перед начальной строкой <?php, что вызывает вывод. Возможно, это пустая строка. Или, возможно, BOM UTF-8.

Откройте файл в простом текстовом редакторе. Ничего сложного. Например, в Блокноте или VIM. Убедитесь, что перед открывающим тегом PHP ничего нет. Сохраните файл. Или в настройках сохранения вашего редактора убедитесь, что не установлена опция сохранения BOM (маркера порядка байтов) в начале файла.

14 янв. 2013 г. 23:29:34
Комментарии

Это не просто пробел перед открывающим тегом <?php, тут весь get_header и разметка, которая выводится перед строкой wp_redirect в середине шаблона.

Milo Milo
14 янв. 2013 г. 23:32:15

Спасибо за ответ. Я попробовал ваш совет, используя просто блокнот. Я даже убедился, что Notepad++ (мой редактор кода) сохраняет в UTF-8 без BOM. Перезагрузил файл... и теперь получаю эту ошибку: Warning: Cannot modify header information - headers already sent by (output started at /home/sadlight/public_html/members/wp-content/plugins/buddypress/bp-themes/bp-default/header.php:2) in /home/sadlight/public_html/members/wp-includes/pluggable.php on line 876 .... Строка 2 в header.php это <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>

Josh Josh
14 янв. 2013 г. 23:59:00

@Milo Я удалил все пробелы, которые мог, там где это было логично... между строками и после строк. Та же ошибка.

Josh Josh
15 янв. 2013 г. 00:00:34

Перед начальной строкой php не должно быть абсолютно ничего. Ни пробела, ни текста, ни кода.

Otto Otto
15 янв. 2013 г. 06:36:12
0

Это может иметь несколько причин. Заголовки могут быть отправлены только в том случае, если перед ними нет никакого вывода. Под выводом я подразумеваю любой вывод. То есть не должно быть пробелов перед открывающими тегами PHP, никаких echo, никаких символов BOM.

По сути, это сообщение об ошибке точно указывает, где начался вывод, а значит, именно там происходит одна из вышеперечисленных проблем.

Для полного списка вещей, которые следует проверить, а также способов предотвратить эту ошибку, ознакомьтесь с этим полезным постом на Stack Overflow.

15 янв. 2013 г. 00:15:27