Symptom – 500 przy zapisie w Gutenbergu
Piszesz sobie ACF blok, dodajesz funkcję pomocniczą – wszystko śmiga na frontendzie. Wchodzisz do edytora Gutenberga, klikasz „Aktualizuj” i dostajesz:
PHP Fatal error: Cannot redeclare authors_picker_split_bio()
(previously declared in .../authors-picker.php:44)
Strona wraca 500 Internal Server Error, w interfejsie edytora widzisz komunikat „Nie powiodła się aktualizacja”. Frontend? Działa bez zarzutu. Kod? Wygląda poprawnie.
Dlaczego to się dzieje
WordPress renderuje ten sam template bloku ACF wielokrotnie w jednym request:
- Raz – preview w edytorze Gutenberga (przez REST API)
- Drugi raz – server-side render przy zapisie
- Trzeci raz – jeśli używasz InnerBlocks albo powtórzeń
Na frontendzie template ładuje się raz więc nie ma problemu. Ale w Gutenbergu drugi include daje fatal error, bo PHP nie pozwala zadeklarować funkcji o tej samej nazwie dwa razy.
Fix – guard if(!function_exists)
Każdą funkcję pomocniczą definiowaną wewnątrz pliku bloku ACF (typowo lib/blocks/nazwa-bloku.php) trzeba owinąć w guard:
if (!function_exists('my_helper_function')) {
function my_helper_function($arg) {
// logika funkcji
return $result;
}
}
Guard sprawdza czy funkcja już istnieje – jeśli tak, po prostu pomija deklarację. Drugi include tego samego bloku nie wywala się.
Czego nie trzeba tak owijać
Reguła dotyczy tylko nazwanych funkcji globalnych. Nie musisz obwijać:
- Anonymous functions (closures) w
add_action/add_filter - Metod klas (klasy same z siebie mają guard przez
class_exists) - Zmiennych i stałych
Więc taki kod jest bezpieczny bez guarda:
add_filter('the_content', function($content) {
return $content . '<p>dopisek</p>';
});
Prostsza alternatywa – przenieś funkcje poza template
Zamiast obwijać każdą funkcję w guard, można je wyciągnąć z pliku bloku do osobnego pliku helper’a, dołączanego raz przez functions.php:
// functions.php
require_once get_template_directory() . '/lib/helpers/blocks-helpers.php';
// lib/helpers/blocks-helpers.php
function my_helper_function($arg) {
// logika
}
Wtedy template bloku po prostu wywołuje my_helper_function() bez deklarowania. To czystsze rozwiązanie jeśli funkcja jest używana przez więcej niż jeden blok. Dla funkcji ściśle związanych z jednym blokiem – guard w miejscu jest OK.
Jak to złapać zanim wyjdzie na produkcję
Fatal error pojawia się tylko przy zapisie w Gutenbergu, więc łatwo go przeoczyć. Testuj tak:
- Napisz nowy blok albo dodaj funkcję pomocniczą
- Wejdź w edytor strony, na której ten blok jest używany
- Kliknij Aktualizuj – jeśli dostajesz „Nie powiodła się aktualizacja” i w konsoli sieci widać 500, to jest to
- Sprawdź
debug.logWordPressa – tam będzie konkretna nazwa funkcji
Podsumowanie
Jedna prosta reguła: każda nazwana funkcja w pliku bloku ACF idzie w guard if(!function_exists()). Nie zaszkodzi tam gdzie nie trzeba, uratuje tam gdzie trzeba.
Alternatywnie – trzymaj funkcje poza blokami, w osobnych helperach. Ale to wymaga dyscypliny, guard w miejscu jest defensywny i wybacza więcej.



