Sviluppo Plugin WordPress - Messaggio Headers Already Sent
Sto sviluppando dei plugin WordPress. Quando attivo il mio plugin, ricevo il seguente messaggio:
Il plugin ha generato 293 caratteri di output inaspettato durante l'attivazione. Se noti messaggi "headers already sent", problemi con i feed di syndication o altri problemi, prova a disattivare o rimuovere questo plugin.
Il plugin funziona molto bene ma non capisco perché ricevo questo messaggio. Il mio plugin è: http://wordpress.org/extend/plugins/facebook-send-like-button/

Questo è tipicamente causato da spazi o righe vuote prima del tag di apertura <?php
o dopo il tag di chiusura ?>
.
Consulta questa pagina per vedere alcune soluzioni: Come posso risolvere il problema dell'avviso "Headers already sent"?
AGGIORNAMENTO
Dopo aver esaminato il codice del tuo plugin, ho notato che manca il tag di chiusura PHP. Nell'ultima riga, aggiungi ?>

I file PHP non necessitano del tag di chiusura ?>
. In effetti, un modo per garantire che non causi problemi di Headers already sent
è omettere il tag di chiusura.

Questo era il mio problema. Avevo diverse righe vuote dopo il mio tag di chiusura ?>
.

Non è consigliabile utilizzare un tag di chiusura PHP. È una cattiva pratica che porta ai tipi di problemi menzionati nell'OP, e va contro gli standard di codifica del Core di WP (vedi https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#remove-trailing-spaces)

Suppongo che tu stia ricevendo un errore PHP, che genera output prima che vengano inviati gli header. Se hai abilitato E_NOTICE
, chiamare $_POST['foo']
potrebbe generare un "Notice: variabile non definita" se quella variabile non è impostata.
Migliori pratiche: non dare mai per scontato nulla sulle variabili GET, POST, COOKIE e REQUEST. Controlla sempre prima usando isset()
o empty()
.
if ( isset( $_POST['foo'] ) ) {
$foo = (string) $_POST['foo'];
// applica ulteriori sanitizzazioni qui se necessario
}

All'inizio della tua funzione di attivazione inserisci un ob_start();
e alla fine metti un trigger_error(ob_get_contents(),E_USER_ERROR);
Quindi prova ad attivare il tuo plugin, e potrai vedere cosa sono realmente quei '293 caratteri di output inaspettato generati'. Da quel momento in poi il debug sarà più semplice (rimuovi i caratteri di nuova riga o risolvi alcuni errori).

So che questa è una vecchia domanda e ha già una risposta accettata. Ci sono molte risposte che trattano i potenziali problemi che potrebbero causare errori durante l'attivazione del plugin. Tuttavia, nessuna di queste risposte affronta realmente il problema fondamentale di COME debuggare i problemi durante l'attivazione dei plugin.
Se hai intenzione di sviluppare plugin per WordPress, tanto vale utilizzare gli strumenti giusti per il lavoro. Uno di questi è Debug Bar. Si tratta di un plugin che ti aiuta a debugare i problemi in WordPress. Se sei uno sviluppatore di plugin, dovrebbe far parte del tuo kit di strumenti.
Debug Bar ha diversi add-on - plugin per il plugin, per così dire. Uno di questi è Debug Bar Plugin Activation, che mostra l'errore PHP generato durante l'attivazione del plugin. Una volta che conosci l'errore PHP che causa l'invio degli header, sai esattamente dove guardare per correggerlo. Credimi, sapere qual è l'errore può farti risparmiare un sacco di tempo invece di cercare di capire quale potrebbe essere l'errore.

Non sono sicuro al 100% che questo sia il problema, ma ne sono abbastanza convinto.
Devi utilizzare una callback valida come secondo argomento in register_activation_hook()
:
register_activation_hook(__FILE__,'twl_tablo_olustur');
Da quello che posso vedere, non hai definito da nessuna parte la funzione twl_tablo_olustur()
. Questo spiegherebbe sicuramente l'output inaspettato (errore PHP generato dal tentativo di chiamare una funzione inesistente) e spiegherebbe perché funziona correttamente in tutte le altre circostanze.

Ricevo spesso questi messaggi quando sto visualizzando i messaggi di debug di plugin/temi, specialmente quando stampo contenuti prima che wp_header venga chiamato.
Se stai emettendo qualsiasi carattere, credo (potrei sbagliarmi) che ci sia una dichiarazione implicita di header, quindi quando avviene la normale chiamata header() ottieni l'errore poiché non possono esserci due dichiarazioni di header.
Puoi usare ob_start() per bufferizzare l'output, il che dovrebbe rimuovere l'errore - dai un'occhiata ai commenti qui: http://php.net/manual/en/function.header.php

Analizzando l'ultima revisione del plugin (381724), il problema è Troppi spazi
ogni volta che vuoi creare questa struttura:
function blabla(){
<= spazio
qualcosa...
}
nel tuo codice usa TAB e non spazi.
Ecco il tuo codice dove ho sostituito tutti gli spazi con tab e non ricevo alcun messaggio all'attivazione:
<?php
/*
Plugin Name: Facebook Send Button By Teknoblogo.com
Plugin URI: http://www.teknoblogo.com/facebook-gonder-butonu-eklenti
Description: Aggiunge i pulsanti "Invia" e "Mi piace" di Facebook ai tuoi articoli! Autore: <a href="http://www.teknoblogo.com">teknoblogo.com</a>
Version: 1.3
Author: Eray Alakese
Author URI: http://www.teknoblogo.com
License: GPL2
*/
wp_register_script('fgb_script', "http://connect.facebook.net/en_US/all.js#xfbml=1");
wp_enqueue_script('fgb_script');
function fgb_ayarlari_yap()
{
add_option('fgb_yer', 'u');
add_option('fgb_buton', 'snl');
add_option('fgb_manual', 'hayir');
}
register_activation_hook( __FILE__, 'fgb_ayarlari_yap' );
function fgb_ayarlari_sil()
{
delete_option('fgb_yer');
delete_option('fgb_buton');
delete_option('fgb_manual');
}
register_deactivation_hook( __FILE__, 'fgb_ayarlari_sil' );
function fgb_ekle($content)
{
$fgb_yer = get_option('fgb_yer');
$fgb_buton_opt = get_option('fgb_buton');
$fgb_manual = get_option('fgb_manual');
$fgb_perma = rawurlencode(get_permalink());
$fgb_send_button = "<fb:send href=\"$fgb_perma\" font=\"\"></fb:send>";
$fgb_like_button = "<fb:like href=\"$fgb_perma\" send=\"false\" width=\"450\" show_faces=\"true\" font=\"\"></fb:like>";
$fgb_snl_button = "<fb:like href=\"$fgb_perma\" send=\"true\" width=\"450\" show_faces=\"true\" font=\"\"></fb:like>";
if($fgb_buton_opt == "send")
{
$fgb_buton = $fgb_send_button;
}
elseif($fgb_buton_opt == "like")
{
$fgb_buton = $fgb_like_button;
}
elseif($fgb_buton_opt == "snl")
{
$fgb_buton = $fgb_snl_button;
}
else
{
echo "Tipo di pulsante non riconosciuto!";
}
if ($fgb_manual=="hayir"){
if ($fgb_yer == "u")
{
$content = $fgb_buton."<br />".$content;
}
elseif ($fgb_yer == "a")
{
$content = $content."<br />".$fgb_buton;
}
return $content;
}
elseif($fgb_manual=="evet"){
echo $fgb_buton;
}
}
if (get_option('fgb_manual')=="hayir"){ add_filter( "the_content", "fgb_ekle" ); }
add_action('admin_menu', 'fgb_admin_menu');
function fgb_admin_menu() {
add_options_page('Facebook Send Button', 'Facebook Send Button', 'manage_options', 'fgb', 'fgb_admin_options');
}
function fgb_admin_options() {
if (!current_user_can('manage_options')) {
wp_die( __('Non hai i permessi sufficienti per accedere a questa pagina.') );
}
echo '<div class="wrap">';
?>
<h2>Facebook Pulsanti Invia & Mi Piace</h2>
<?
if($_POST["fgb_gonder"])
{
echo "<h3>salvato</h3>";
update_option('fgb_yer', $_POST["fgb_yer"]);
update_option('fgb_buton', $_POST["fgb_buton"]);
update_option('fgb_manual', $_POST["fgb_manual"]);
$fgb_admin_yer = get_option('fgb_yer');
$fgb_admin_buton = get_option('fgb_buton');
$fgb_admin_manual = get_option('fgb_manual');
}
?>
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="POST">
Mostra pulsanti Facebook <select name="fgb_yer">
<option value="u" <?php if($fgb_admin_yer == "u"){echo "SELECTED";}?>>prima del contenuto</option>
<option value="a" <?php if($fgb_admin_yer == "a"){echo "SELECTED";}?>>dopo il contenuto</option>
</select> e voglio <select name="fgb_buton">
<option value="snl" <?php if($fgb_admin_buton=="snl"){echo "SELECTED";}?>>pulsanti invia e mi piace insieme</option>
<option value="send" <?php if($fgb_admin_buton=="send"){echo "SELECTED";}?>>solo pulsante invia</option>
<option value="like" <?php if($fgb_admin_buton=="like"){echo "SELECTED";}?>>solo pulsante mi piace</option>
</select> . <br />
<input type="radio" value="hayir" name="fgb_manual" <?php if($fgb_admin_manual=="hayir"){echo "CHECKED";}?> /> inserisci i pulsanti per me, AUTOMATICAMENTE <br />
<input type="radio" value="evet" name="fgb_manual" <?php if($fgb_admin_manual=="evet"){echo "CHECKED";}?> /> posso inserirli io, MANUALMENTE <br />
<input type="submit" class="button-primary" name="fgb_gonder" value="<?php _e('Salva modifiche') ?>" />
</form>
<br />Se usi l'<strong>inserimento manuale</strong> , devi aggiungere questo codice al tuo tema :
<strong><?php if(function_exists('fgb_ekle')) { fgb_ekle(); }?></strong>
<hr />
<em>Se ti piace questo plugin, per favore <a href="http://wordpress.org/extend/plugins/facebook-send-like-button/">votalo</a> .
Autore : <a href="http://www.teknoblogo.com">Eray Alakese</a>
Puoi <a href="mailto:info@teknoblogo.com">scrivermi</a> per segnalare bug, grazie.</em>
<?php
echo '</div>';
}

Non dovrebbe avere nulla a che fare con quello. Spazi e tabulazioni all'interno delle tue funzioni sono accettabili e non producono questo errore.

all'interno di una funzione hai ragione, ma se la funzione produce direttamente un output, ad esempio: function blabla(){?> <input> <?php code... ?> output something <?php code.. }
allora non è questo il caso.

@MatthewMuro: se lasci lo spazio all'interno di una funzione va bene, ma se lasci qualsiasi spazio bianco/interruzione di riga dopo i tag di chiusura php ?>
otterrai l'errore header already send
perché quegli spazi bianchi extra verranno stampati quando il motore php li analizzerà.

Rimuovi il tag di chiusura PHP ( ?> ) alla fine di ogni file e anche tutti gli spazi vuoti dopo il tag di chiusura PHP ( ?> ).
Quando attivi il plugin, verifica semplicemente se la tabella esiste già o meno.
Ho risolto il problema con il seguente codice:
if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
$sql = "CREATE TABLE {$table_name}(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(250),
email VARCHAR(250),
PRIMARY KEY (id)
);";
dbDelta($sql);
}
