Pierwszy wpis w tej kategorii. Pierwszy opisywany przeze mnie bug. Przyznaję, nie jest on żadnych wysokich lotów – nie mniej jednak tak jak zawsze z tego typu lub cięższymi sprawami dzieliłem się bezpośrednio z danymi osobami, tak teraz postanowiłem je pisać. Może dlatego, że mam gdzie.
Sprawa jest na tyle nieskomplikowana, że dłużej dociekałem przyczyny, niż ją naprawiałem. Błąd wykryłem przypadkiem, dzięki użytkownikom mojego forum. Wiem, że znany był on wcześniej, a nawet niektórzy próbowali go naprawiać, ale jednoznacznego rozwiązania nie widziałem nigdzie. Na czym polega bug? Na tym, że w przypadku jeśli PHP wspomagane jest obsługą CGI z wyłączonym zlib.output_compression w czasie edycji wpisów w shoutboxie jest wysyłany tekst przed wysłaniem nagłówków powodujący błąd skryptu. Problem ten dotyczy wersji 1.12.5, z tego co wiem podobne problemy były zauważane w wersjach 1.9.x.
Jak wygląda to od strony technicznej? W phpBB by Przemo takie akcje jak edycja, czy usuwanie wpisów z shoutboxa są wykonywane w pliku shoutbox_view.php. W momencie kiedy w Panelu Administracyjnym ustawimy, aby skrypt korzystał z kompresji gzip w pliku w zależności od typu przeglądarki ustawiane jest standardowe buforowanie wyjścia, wysyłany nagłówek szyfrowania treści strony, wyliczana suma kontrolnej i w końcu kompresowanie lub po prostu ustawienie buforowania wyjścia z atrybutem kompresji gzipa.
// Gecko
@ob_start('ob_gzhandler');
// Opera
$do_gzip_compress = TRUE;
@ob_start();
@ob_implicit_flush(0);
@header('Content-Encoding: gzip');
$gzip_contents = @ob_get_contents();
@ob_end_clean();
$gzip_size = strlen($gzip_contents);
$gzip_crc = @crc32($gzip_contents);
$gzip_contents = @gzcompress($gzip_contents, 9);
$gzip_contents = substr($gzip_contents, 0, strlen($gzip_contents) - 4);
echo "x1fx8bx08x00x00x00x00x00";
echo $gzip_contents;
echo pack('V', $gzip_crc);
echo pack('V', $gzip_size);
W tym drugim przypadku dotyczącym przeglądarek opartych na silniku Gecko każda próba edycji jakiegokolwiek wpisu kończy się wyświetleniem białej strony, w przypadku pierwszym dotyczącym Opery edycja jest możliwa, ale zamiast listowania wiadomości otrzymujemy ciąg skompresowanych danych, w postaci różnorodnych znaków. Co najdziwniejsze przynajmniej na Internet Explorerze w wersji siódmej wszystko działa dobrze ;]
Jak już napisałem prawie na początku problem stwarza fakt, że przy podanej wcześniej przeze mnie konfiguracji parsera PHP wysyłanie tekstu przed wysłaniem nagłówków powoduje automatyczne zatrzymanie i zerowanie zawartości sparsowanego pliku. Jeśli posiadamy własny serwer lub po prostu mamy możliwość konfiguracji naszego konta np. poprzez zmianę php.ini sprawa jest stosunkowo prosta. Możemy dla przykładu ustawić zlib.output_compression i zlib.output_compression_level na 1. Na przykład poprzez użycie PHP w wersji co najmniej 4.3:
ini_set('zlib.output_compression', true);
ini_set('zlib.output_compression_level', '1');
Natomiast jeśli nie mamy takich możliwości konfiguracyjnych wystarczy, że znajdziemy poniższy kod.
$do_gzip_compress = FALSE;
if ( $board_config['gzip_compress'] && !@headers_sent() )
{
$phpver = phpversion();
$useragent = (isset($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) ? $HTTP_SERVER_VARS['HTTP_USER_AGENT'] : getenv('HTTP_USER_AGENT');
$is_ob_gzhandler_started = false;
if ( @ini_get('zlib.output_compression') && (int)@ini_get('zlib.output_compression') != 0 && strtolower(@ini_get('zlib.output_compression')) != 'off' )
{
$is_ob_gzhandler_started = true;
}
else if ( @ini_get('output_handler') && strtolower(@ini_get('output_handler'))=='ob_gzhandler' )
{
$is_ob_gzhandler_started = true;
}
if ( $phpver>= '4.0.4pl1' && ( strstr($useragent,'compatible') || strstr($useragent,'Gecko') ) )
{
if ( extension_loaded('zlib') && !$is_ob_gzhandler_started )
{
@ob_start('ob_gzhandler');
}
}
else if ( $phpver> '4.0' )
{
if ( strstr($HTTP_SERVER_VARS['HTTP_ACCEPT_ENCODING'], 'gzip') )
{
if ( extension_loaded('zlib') && !$is_ob_gzhandler_started )
{
$do_gzip_compress = TRUE;
@ob_start();
@ob_implicit_flush(0);
@header('Content-Encoding: gzip');
}
}
}
}
I przeniesiemy go powyżej następującego kodu.
// ShoutBox auth
$is_jr_admin = ($userdata['user_jr']) ? true : false;
$is_mod = ($userdata['user_level'] == MOD) ? true : false;
W takim wypadku niezbędne do kompresji gzip nagłówki zostaną wysłane przed wyświetleniem tekstu i wszelkie związane z tą przypadłością błędy zostaną zaniechane.
Zapraszam do zapoznania się także z powiązanymi artykułami:
Wpis ten został opublikowany dnia:
piątek, 7 Wrzesień 2007 o godzinie 0:29
w działach Bugtrack, PHP, phpBB.
Możesz śledzić rozwój tematu, w tym odpowiedzi dla tego artykułu poprzez kanał informacyjny RSS 2.0.
Możesz także zostawić swój komentarz lub trackbackować ze swojej własnej strony.
Ty to masz łeb ;) Do głowy by mi nie przyszło w jaki sposób rozwiązać ten problem :D
Życzę dalszych sukcesów!
Pozdrawiam, dziki!
Ja umieszczalem rozne shoutboxy ktore chodzily raz lepiej a raz gorzej. W koncy trafilem na cos super i od 3 lat uzywam na swoich strona http://www.tag-world.com ma wiele opcji lacznie z administrowaniem wlasnych uzytkownkow ktorzy moga sie do mnie zapisywac. Bardzo dobry panel i do tego za free. Polecam tym ktorzy chca aby ich strona byla ciekawsza.
Brawo, naprawdę brawo. Działa teraz bez problemu!
Miło mi, że mogłem pomóc :D Zapraszam na przyszłość.
ej bys powiedzial jak to zrobic ?? bo chcem sprawdzic czy na mojej stronce tez da sie zmienic i zeby to zablokowac jak tak .
Ale co mam Ci wytłumaczyć? Opis jak poprawić błąd w phpBB by Przemo opisałem powyżej we wpisie ;] Wystarczy go przeczytać.
No ale ja do końca tego nie rozumiem, co dokładnie i jak mam wyedytować w jakim pliku dla mojego skryptu phpbb przemo ?
Plik shoutbox_view.php. Masz napisane prawie na samym końcu co, przed co i dlaczego trzeba zamienić, żeby błąd nie występował (włącznie z samym kodem).
Wielkie dzieki, poprawiony skrypcik dziala bez problemow :)
Chylę czoła. Chciałbym mieć taki łeb. Pozdrawiam i dzięki za pomoc.