Otwarte na nowe projekty +48 887 255 528 · kontakt[at]kosari.pl

Warning PHP widoczny na stronie WordPress: skąd się bierze i jak go usunąć

Warning PHP widoczny na stronie WordPress, choć serwer działa? Sprawdź 3 przyczyny: włączone błędy, cache i komunikaty zapisane w treści strony.

9 min czytania WordPress
Warning PHP widoczny na stronie WordPress: skąd się bierze i jak go usunąć

Otwierasz stronę i widzisz coś, czego nie powinien zobaczyć żaden odwiedzający: nad treścią wiszą komunikaty błędów PHP, ze ścieżkami katalogów na serwerze i nazwami plików wtyczek. Wygląda to jak poważna awaria, a strona przy tym działa normalnie. Jeśli masz warning PHP widoczny na stronie WordPress, a hosting twierdzi, że wszystko jest w porządku, ten poradnik może oszczędzić Ci godziny grzebania w konfiguracji serwera.

Bo serwer bywa niewinny. Jedna z najmniej oczywistych przyczyn to cztery znaki w komendzie, którą ktoś pobrał treść strony do edycji: 2>&1. Poniżej sprawdzanie krok po kroku – od najczęstszych przyczyn do tej najbardziej podstępnej.

Kontekst: edycja treści z poziomu konsoli

Coraz więcej podstron WordPress powstaje jako czysty HTML zapisany w polu wpisu w bazie, a nie w kreatorze stron. To szybkie, lekkie i wygodne do pracy z poziomu konsoli: treść pobiera się komendą WP-CLI, poprawia lokalnie, sprawdza walidatorem i zapisuje z powrotem.

Wystarczy drobna zmiana kilku akapitów i jeden zły odruch przy pobieraniu, żeby na stronie pojawiły się śmieci – mimo że walidator przeszedł na zielono.

Diagnoza: co sprawdzić po kolei

Komunikat wygląda mniej więcej tak (ścieżki skrócone):

Warning: Undefined array key "SERVER_NAME" in /.../wp-content/plugins/WTYCZKA-KURSOWA/... on line ...
Deprecated: ... in /.../wp-content/plugins/... on line ...

Pierwszy odruch przy takim widoku jest zawsze ten sam: ktoś włączył wyświetlanie błędów na produkcji. I to jest pierwsza rzecz do sprawdzenia.

Przyczyna 1: włączone wyświetlanie błędów

Sprawdź WP_DEBUG i WP_DEBUG_DISPLAY w wp-config.php oraz ustawienie display_errors w PHP. Jeśli wszystko jest wyłączone, a komunikat pojawia się tylko na jednej podstronie, to raczej nie konfiguracja: gdyby problem leżał w PHP, ostrzeżenia z tych samych wtyczek wyskakiwałyby na wielu stronach naraz.

Przyczyna 2: stara wersja w cache

Wyczyść cache strony i przeglądarki. Jeśli komunikat wraca przy każdym odświeżeniu, także w oknie prywatnym, to nie jest zapamiętana kopia sprzed jakiejś awarii.

Przyczyna 3: ostrzeżenie, które nie pasuje do przeglądarki

Ostrzeżenie o brakującym SERVER_NAME jest typowe dla czegoś zupełnie innego: dla uruchomienia WordPressa z konsoli, gdzie nie ma żadnego zapytania HTTP, więc PHP nie zna nazwy serwera.

To pierwszy trop. Taki komunikat nie mógł powstać przy wyświetlaniu strony w przeglądarce. Powstał w konsoli.

Jak rozpoznać, że warning jest treścią strony, a nie błędem PHP

Rozstrzyga jedno spojrzenie w kod źródłowy strony (Ctrl+U). Jeśli cudzysłowy w komunikacie nie są zwykłymi znakami ", tylko typograficznymi cudzysłowami zapisanymi jako encje HTML, a w tekście siedzą twarde spacje  , masz odpowiedź. Tak wygląda tekst, który przeszedł przez filtry treści WordPressa. Żywy warning z PHP wypisuje się surowo, zanim jakikolwiek filtr go dotknie.

Jeśli komunikat błędu na stronie ma encje i typograficzne cudzysłowy, to nie jest błąd, który właśnie wystąpił. To tekst zapisany w bazie danych jako część treści. Szukanie przyczyny w konfiguracji serwera i w cache to wtedy ślepa uliczka.

Wtedy warto wrócić do komendy, którą pobrano treść do edycji. Typowa wygląda tak:

wp post meta get 123 _kwt_html 2>&1 > strona.html

Przekierowanie 2>&1 skleja dwa strumienie: standardowe wyjście (stdout), w którym leci treść strony, oraz strumień błędów (stderr), w którym lecą ostrzeżenia PHP. WP-CLI przy starcie ładuje cały WordPress ze wszystkimi wtyczkami. Wtyczka uruchomiona bez zapytania HTTP potrafi sypnąć ostrzeżeniem o brakującym SERVER_NAME, inna dorzuca swoje Deprecated. Wszystko to trafia do pliku razem z HTML-em strony.

Jak ostrzeżenia PHP trafiły do treści stronyKomenda WP-CLI wypisuje treść strony na stdout i ostrzeżenia wtyczek na stderr. Przekierowanie 2>&1 skleja oba strumienie w jeden plik, walidator przepuszcza plik, a zapis do bazy publikuje ostrzeżenia na stronie.Droga ostrzeżenia z konsoli na stronęstdoutHTML stronystderrostrzeżenia wtyczek2>&1jeden plikWalidatorshortcody OKStronapokazuje błędyWalidator sprawdzał to, czego się spodziewał: kotwice i shortcody były na miejscu.Nie sprawdzał, czy w pliku nie ma czegoś, czego tam być nie powinno.
Przekierowanie, które przy debugowaniu pomaga, przy pobieraniu danych skleja treść ze śmieciami.

Dlaczego łatwo to przeoczyć przed zapisem? Bo plik wygląda poprawnie. Ostrzeżenia są na samej górze, a edytuje się akapity w środku. Prosty walidator, który liczy shortcody i sprawdza obecność kluczowych kotwic, przechodzi, bo treść strony jest w pliku cała. Problem polega na tym, że w pliku jest coś więcej niż treść.

Nie chcesz takich rzeczy wyłapywać sam? Strony klientów, którymi się opiekujemy, edytujemy narzędziami z wbudowanymi kontrolami, a nie ręcznymi komendami. Zobacz, na czym polega opieka nad stroną WordPress w Kosari.

Rozwiązanie: dwie zmiany, jedna w odruchu, druga w kodzie

1. Pobieranie treści zawsze bez strumienia błędów

Każde pobranie treści z serwera, które potem wraca do bazy, robimy z odrzuceniem stderr. Ostrzeżenia nie znikają, tylko przestają mieszać się z danymi:

wp post meta get 123 _kwt_html 2>/dev/null > strona.html

Jeśli chcesz ostrzeżenia zobaczyć, bo coś debugujesz, kieruj je do osobnego pliku, a nie do tego samego strumienia:

wp post meta get 123 _kwt_html 2>bledy.log > strona.html

Ta sama zasada dotyczy wp option get, wp post get --field=post_content, eksportów bazy i każdej innej komendy, której wynik zapisujesz do pliku albo przekazujesz dalej.

2. Walidator, który szuka śmieci, a nie tylko treści

Sama zasada w głowie działa do pierwszego dnia, w którym ktoś się spieszy. Dlatego dołożyliśmy kontrolę do narzędzia, które zapisuje treść. Przed każdym zapisem sprawdza, czy w HTML-u nie ma typowych fraz z komunikatów PHP, i przerywa zapis przy pierwszym trafieniu:

foreach ( array( 'Warning:', 'Fatal error', 'Undefined array key', 'Deprecated:' ) as $z ) {
    if ( strpos( $html, $z ) !== false ) {
        echo "BŁĄD: śmieć w treści ($z)\n";
        exit( 1 );
    }
}

Lista jest krótka i celowo prosta. W treści strony marketingowej te frazy praktycznie nie występują, a w komunikatach PHP występują zawsze. Jeśli kiedyś piszesz artykuł o błędach PHP, walidator odmówi zapisu i trzeba będzie dodać wyjątek świadomie. To dobra cena za pewność.

Pobieranie treści przed i po zmianiePrzed: 2>&1, walidator sprawdza tylko obecność treści, ostrzeżenia trafiają na stronę. Po: 2>/dev/null, walidator dodatkowo szuka fraz z komunikatów PHP i przerywa zapis.PRZEDPobranie: 2>&1Plik: HTML + ostrzeżenia PHPWalidator: czy treść jest cała?Wynik walidatora: OKOdwiedzający widzi ścieżkii komunikaty błędówPOPobranie: 2>/dev/nullPlik: sam HTMLWalidator: treść cała i bezWarning, Fatal, DeprecatedŚmieć w pliku = zapisprzerwany przed bazą
Druga warstwa ochrony działa nawet wtedy, gdy ktoś zapomni o pierwszej.

3. Opcjonalnie: ucisz ostrzeżenie u źródła

Ostrzeżenie o SERVER_NAME w konsoli jest nieszkodliwe, ale zaśmieca każdą komendę WP-CLI. Na części stron, którymi się opiekujemy, mamy mały mu-plugin, który ustawia tę zmienną tylko przy uruchomieniu z konsoli. Przykład takiego pliku:

<?php
// wp-content/mu-plugins/0-cli-server-name.php
if ( defined( 'WP_CLI' ) && WP_CLI && empty( $_SERVER['SERVER_NAME'] ) ) {
    $_SERVER['SERVER_NAME'] = 'twojadomena.pl';
}

To jednak leczenie objawu. Jutro ostrzeżenie wyrzuci inna wtyczka, z innego powodu. Zasada „pobieram bez stderr” i walidator zostają niezależnie od tego.

Efekt

Po usunięciu komunikatów z treści strona wraca do normalnego wyglądu, bez żadnych zmian w konfiguracji serwera – bo ta była w porządku. Walidator w narzędziu do zapisu sprawia, że ten sam błąd nie przejdzie drugi raz, niezależnie od tego, kto i jak się spieszy. Na stronach, którymi się opiekujemy, treść zapisujemy wyłącznie przez takie narzędzie.

Jak sprawdzić to u siebie

  1. Przejrzyj własne skrypty i notatki z komendami: grep -rn "2>&1" ~/skrypty. Każde trafienie, w którym wynik trafia do pliku z danymi, zamień na 2>/dev/null albo osobny plik błędów.
  2. Jeśli widzisz warning PHP na stronie, otwórz kod źródłowy (Ctrl+U) i spójrz na cudzysłowy. Encje i typograficzne cudzysłowy oznaczają, że komunikat jest zapisany w treści.
  3. Przeszukaj bazę pod kątem zapisanych komunikatów: wp db query "SELECT ID FROM wp_posts WHERE post_content LIKE '%Warning:%'". To samo zrób dla tabeli wp_postmeta, jeśli treść trzymasz w polach dodatkowych.
  4. Sprawdź, czy komunikat jest tylko na jednej podstronie, czy na wszystkich. Jedna podstrona to prawie zawsze treść, wszystkie to raczej konfiguracja PHP.
  5. Upewnij się, że na produkcji WP_DEBUG_DISPLAY jest wyłączone, a błędy lądują w logu, nie na ekranie.
  6. Jeśli masz walidator przed zapisem, dopisz do niego sprawdzanie, czego w treści być nie może, a nie tylko tego, co w niej być musi.

Najważniejsza lekcja

2>&1 jest dobrym odruchem przy debugowaniu i złym przy pobieraniu danych. Ważniejsza lekcja dotyczy jednak walidatorów: walidator, który sprawdza tylko, czy jest to, czego się spodziewasz, przepuści wszystko, czego się nie spodziewasz. Dobra kontrola patrzy na wynik oczami odbiorcy, a nie na to, czy komenda zakończyła się kodem 0. Taką samą zasadę stosujemy dziś w innych narzędziach: kontrole siedzą w kodzie, a nie w pamięci osoby, która akurat pracuje. Szerzej opisaliśmy to przy okazji blokad groźnych komend w Claude Code.

FAQ

Dlaczego na stronie WordPress widać komunikaty Warning, skoro debugowanie jest wyłączone?

Są dwie możliwości. Albo ustawienia wyświetlania błędów są włączone gdzieś, gdzie ich nie szukasz (plik .user.ini, panel hostingu), albo komunikat jest zapisany w treści strony. Ten drugi przypadek rozpoznasz po tym, że występuje tylko na jednej podstronie i ma typograficzne cudzysłowy w kodzie źródłowym.

Czym różni się stdout od stderr?

To dwa osobne strumienie wyjścia programu. Stdout niesie wynik, czyli dane, które chcesz dostać. Stderr niesie komunikaty o błędach i ostrzeżenia. Przekierowanie 2>&1 łączy je w jeden, więc wynik i ostrzeżenia lądują w tym samym miejscu.

Skąd ostrzeżenie Undefined array key SERVER_NAME w WP-CLI?

WP-CLI uruchamia WordPress bez zapytania HTTP, więc PHP nie ustawia zmiennej SERVER_NAME. Wtyczki, które jej używają bez sprawdzenia, sypią ostrzeżeniem. Jest nieszkodliwe dla działania strony, ale zaśmieca wynik komend.

Czy wystarczy wyłączyć wyświetlanie błędów, żeby problem zniknął?

Nie, jeśli komunikat jest zapisany w treści. Wyłączenie wyświetlania błędów ukrywa tylko błędy, które dzieją się na żywo. Tekst zapisany w bazie trzeba usunąć z bazy albo przywrócić treść z kopii.

Czy komunikaty błędów na stronie to zagrożenie bezpieczeństwa?

Mogą nim być. Ścieżki katalogów, nazwy wtyczek i ich plików to informacje, które ułatwiają atakującemu dobranie metody. Dlatego na produkcji błędy powinny trafiać do logu, a nie na ekran, a zapisane w treści komunikaty warto usunąć jak najszybciej.

Jak bezpiecznie edytować treść WordPressa z konsoli?

Pobieraj treść bez stderr, zrób kopię przed zapisem, uruchom walidator, który sprawdza zarówno obecność treści, jak i brak śmieci, a po zapisie obejrzyj stronę w przeglądarce. Sam kod wyjścia komendy niczego nie dowodzi.

Widzisz na swojej stronie komunikaty błędów? Napisz do nas

Jeśli na Twojej stronie pojawiają się ostrzeżenia PHP, ścieżki serwera albo dziwne fragmenty tekstu, a nie wiesz, czy to awaria, czy zapisana w bazie pozostałość, sprawdzimy to i posprzątamy. Na co dzień opiekujemy się stronami WordPress, sklepami i platformami kursowymi, a każdą zmianę robimy z kopią i kontrolą wyniku. Zobacz, co obejmuje opieka WordPress w Kosari.

Napisz do nas – sprawdzimy, skąd biorą się błędy na Twojej stronie

Grzegorz Rówiński · Kosari

Buduję strony, sklepy i platformy kursowe, automatyzuję procesy i wdrażam AI w firmach. Ten wpis powstał z realnego wdrożenia, nie z teorii.

Napisz do mnie →

Przeczytaj też

Masz podobny problem i nie chcesz go debugować sam?

Napisz krótko co się dzieje. Odpowiadamy konkretnie, bez zobowiązań - powiemy z czego to najpewniej wynika i ile kosztuje naprawa.

Napisz do nas

Wolisz porozmawiać? Zadzwoń: +48 887 255 528

Zadzwoń +48 887 255 528