Pięciominutowa instalacja daje działającą stronę. Nie daje stanowiska programisty. W 2026 solidna konfiguracja WordPressa to lokalny stos, który da się odtworzyć, pipeline lintu zgodny z core, bezpieczny debug bez błędów na froncie oraz tooling bloków, który buduje te same assety, które testujesz.
Ten przewodnik to checklista, której używamy przy nowym repozytorium motywu lub wtyczki: typ środowiska, wp-env, @wordpress/scripts, stałe debug oraz cienka warstwa hardeningu w wp-config.php i mu-plugins. Na projektach dla klientów z Warszawy i Trójmiasta ten sam .wp-env.json w gicie kończy spory “u mnie działa”.
Jak postawić lokalny WordPress na wp-env
Ręczne instalacje Apache i PHP rozjeżdżają się. Jedna maszyna ma PHP 8.2, druga jeszcze 8.1, a buildy bloków padają dopiero na CI. Oficjalna ścieżka to wp-env: kontenery Docker z WordPressem, MySQL i opcjonalnymi narzędziami, sterowane z .wp-env.json w korzeniu projektu.
Instalacja raz globalnie albo jako zależność projektu:
npm install --save-dev @wordpress/env
npx wp-env startMinimalna konfiguracja dla rozwijanej wtyczki:
{
"core": "WordPress/WordPress#6.7",
"plugins": [ "." ],
"config": {
"WP_DEBUG": true,
"WP_DEBUG_LOG": true,
"WP_DEBUG_DISPLAY": false,
"SCRIPT_DEBUG": true
}
}Dlaczego to wygrywa z generycznym stosem przy pracy nad wtyczkami:
- Wersja core jest pinowana w gicie, więc “działa u mnie” przestaje być argumentem.
wp-env run clidaje WP-CLI w tych samych kontenerach, które widzi przeglądarka.- Testy i skrypty e2e w
@wordpress/scriptszakładają ten układ.
Połącz to z dokumentacją środowiska edytora bloków, gdy potrzebujesz notatek o Node, create-block i zalecanych rozszerzeniach edytora.
Przy klasycznych motywach PHP możesz trzymać hostowy PHP do jednorazowych skryptów, ale samą stronę trzymaj w wp-env, żeby media, cron i rewrite zachowywały się jak na stagingu.
Przydatne komendy dnia:
npx wp-env run cli wp plugin list
npx wp-env run cli wp cache flush
npx wp-env logs
npx wp-env stopWłasną domenę mapuj w hosts tylko gdy projekt wymaga cookie lub SSO, których localhost psuje. W przeciwnym razie domyślny URL wystarczy i upraszcza certyfikaty.
Gdy ktoś klonuje repo, onboarding ma mieć trzy linie: zainstaluj Docker, npm install, npx wp-env start. Dłuższa instrukcja zwykle oznacza, że środowisko uciekło w nieudokumentowane pakiety hosta.
Na projektach WooCommerce z polskimi bramkami (Przelewy24, PayU) lokalny stack musi umieć odtwarzać callbacki webhooków. Zamiast ręcznie podmieniać URL w panelu bramki, trzymaj osobny wpis w .wp-env.json z pluginami płatności i mapowaniem portów, a w ticketach opisuj, który endpoint CI odtwarza. To ta sama dyscyplina co pinowanie wersji core: mniej zgadywania przy regresji koszyka.
WP_ENVIRONMENT_TYPE i stałe bezpieczeństwa w wp-config
Od WordPress 5.5 WP_ENVIRONMENT_TYPE jest przełącznikiem, który powinna czytać każda wtyczka. Zdefiniuj go wcześnie w wp-config.php:
define( 'WP_ENVIRONMENT_TYPE', 'local' ); // local | development | staging | productionPotem rozgałęziaj zachowanie bez własnych stałych:
if ( wp_get_environment_type() === 'production' ) {
// Cache włączony, gadatliwe logi wyłączone.
} else {
define( 'SCRIPT_DEBUG', true );
}Stałe hardeningu w każdym boilerplate produkcyjnym:
define( 'DISALLOW_FILE_EDIT', true );
define( 'FORCE_SSL_ADMIN', true );
define( 'WP_POST_REVISIONS', 5 );
define( 'AUTOMATIC_UPDATER_DISABLED', true ); // gdy deploy sam aktualizuje coreDISALLOW_FILE_MODS włączaj tylko gdy całe drzewo jest niemutowalne, a aktualizacje wchodzą przez CI. Na hostingu zarządzanym, który nadal łata wtyczki z dashboardu, ta stała będzie walczyć z hostem.
Klucze i sole nie są ozdobą. Po kompromitacji je rotuj; każda sesja kończy się od razu. Rotację trzymaj w runbooku wdrożeń, nie na karteczce.
W praktyce agencji w Polsce staging często siedzi na osobnej subdomenie z Basic Auth. Ustaw tam WP_ENVIRONMENT_TYPE na staging, nie local, żeby wtyczki pocztowe i cache nie zachowywały się jak na laptopie developera. Produkcja dostaje production dopiero w pipeline deployu, nigdy przez ręczną edycję pliku na serwerze “na chwilę”.
Jak skonfigurować lint w @wordpress/scripts
Linting to sposób, by zostać zgodnym z Gutenbergem bez zapamiętywania każdej reguły ESLint. Pakiet @wordpress/scripts owija webpack, Babel, ESLint, Stylelint, Jest i Playwright za znanymi skryptami npm.
Typowa powierzchnia package.json dla wtyczki blokowej:
{
"scripts": {
"start": "wp-scripts start",
"build": "wp-scripts build",
"lint:js": "wp-scripts lint-js",
"lint:css": "wp-scripts lint-css",
"lint:pkg-json": "wp-scripts lint-pkg-json",
"format": "wp-scripts format",
"packages-update": "wp-scripts packages-update"
}
}Uruchamiaj npm run lint:js w CI na każdym pull request. Formatuj Prettierem przez wp-scripts format, żeby diff dotyczył logiki, nie cudzysłowów.
PHP nadal potrzebuje własnej bramki. Zainstaluj WordPress Coding Standards (WPCS) przez Composer i odpal PHPCS na motywach i wtyczkach. Nie oczekuj, że @wordpress/scripts to zastąpi; obejmuje połowę JS i CSS.
Praktyczna kolejność CI, która łapie większość regresji:
composer phpcs(albo własny wrapper PHPCS)npm run lint:jsinpm run lint:cssnpm run build, żeby zepsuty webpack padł przed review- Opcjonalnie:
wp-env start, potem PHPUnit wtyczki albo Playwright ze skryptów
Ignoruj wygenerowany build/ w review gita, chyba że projekt świadomie commit’tuje skompilowane assety na host bez Node. Preferuj build w CI albo na deployu. EditorConfig plus domyślny Prettier z pakietu scripts usuwa wojny o wcięcia z pull requestów.
Jeśli legacy motyw nadal serwuje skrypty admina z ery jQuery, wprowadź @wordpress/scripts najpierw dla nowych bloków zamiast przepisywać każde enqueue pierwszego dnia. Mieszane stosy są w porządku; mieszane reguły nie. Jedna konfiguracja ESLint na katalog pakietu.
Gdy klient prosi o “mały widget” w Elementorze, a jednocześnie budujesz bloki pod Gutenberg, trzymaj lint w osobnych pakietach npm: jeden katalog blocks/, drugi legacy-admin/. Wspólny root z jednym .eslintrc na dwa światy kończy się wyjątkami i wyłączonymi regułami, które potem wracają jako regresje w review.
Jak włączyć WP_DEBUG bez pokazywania błędów
Nigdy nie pokazuj błędów PHP odwiedzającym. Loguj je.
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true ); // domyślnie wp-content/debug.log
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );Lepiej: skieruj WP_DEBUG_LOG poza document root i zablokuj HTTP do ewentualnego debug.log w wp-content. Na produkcji zostawiaj WP_DEBUG na false, chyba że jesteś w środku incydentu. SAVEQUERIES włączaj tylko na krótkie sesje profilowania; kosztuje pamięć i nie powinien zostawać na noc.
Uzupełnij stałe narzędziami, które pokazują co się stało:
- Query Monitor na hooki, HTTP i wolne zapytania w admin barze
- Xdebug podpięty do kontenera PHP wp-env, gdy potrzebujesz krokowania
- DevTools przeglądarki z
SCRIPT_DEBUG, żeby ładować niemainifikowane skrypty core przy konflikcie
Gdy staging pokazuje biały ekran, sprawdź debug.log, log hosta i wp-env logs (lokalnie) zanim dołożysz kolejną wtyczkę “debug”. Większość awarii produkcyjnych z misconfigu to jeden fatal w logu, nie brakująca funkcja.
Odtwórz błąd na wyrzutkowym wp-env z tym samym zestawem wtyczek, zanim ruszysz stałe na produkcji. Jeśli problem widać tylko przy object cache albo CDN, zapisz to w tickecie; lokalny Docker nie wymyśli Redis, dopóki nie dodasz go do konfiguracji env.
Jak tworzyć bloki WordPress przez create-block
Interaktywne bloki nie są już bocznym projektem. Domyślna ścieżka:
- Szkieletuj przez
npx @wordpress/create-block my-block --variant dynamic(albo static, zależnie od strategii renderu) - Rozwijaj na wp-env, żeby rejestracja
block.jsontrafiała w prawdziwy admin - Używaj
npm startdo watch inpm run builddo assetów produkcyjnych - Rejestruj blok z PHP przez
register_block_type( __DIR__ . '/build' ), gdy metadata siedzi wblock.json
Trzymaj skrypty edytora i frontu osobno w block.json, żeby nie wysyłać Reacta edytora każdemu odwiedzającemu. Preferuj viewScript / viewStyle dla interakcji frontu zamiast jednego worka.
W motywach, które nadal enqueue’ują klasyczne assety, migruj nowe interaktywne kawałki do bloków przyrostowo. Hybrydowy motyw może wysyłać patterny i kilka custom bloków, a resztę szablonów zostawić w PHP. To normalne w 2026; pełny rewrite Site Editora to decyzja produktowa, nie wymóg toolingu.
Gdy zależności dryfują, npx wp-scripts packages-update odświeża pakiety @wordpress/* w toolchainie scripts. Pinuj majory w package-lock.json i review’uj lockfile w PR tak samo jak aktualizacje Composer.
Wyłączenie emoji i XML-RPC przez mu-plugin
Nie potrzebujesz wtyczki “wyłącz wszystko” z katalogu. Mały must-use trzyma reguły w kontroli wersji:
<?php
/**
* Plugin Name: Lean core
*/
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'xmlrpc_enabled', '__return_false' );XML-RPC wyłączaj tylko gdy wiesz, że żaden zdalny klient go nie potrzebuje. Skrypty emoji wyłączaj, gdy kontrolujesz ikony marki i chcesz mniej requestów na froncie. RSS zostaw na stronach contentowych; wizytówki mogą wyłączyć feedy świadomym hookiem, nie losowym snippem z forum.
Jak skonfigurować Composer 2 do zarządzania wtyczkami i zależnościami WordPressa
Composer 2 zarządza pakietami PHP, wtyczkami, motywami oraz narzędziami deweloperskimi w sposób deterministyczny w całym zespole inżynierskim. W profesjonalnym środowisku WordPress zależności nigdy nie powinny trafiać do repozytorium gita jako anonimowe archiwa zip pobierane ręcznie z oficjalnego katalogu wtyczek. Zastosowanie Composera pozwala precyzyjnie deklarować wersje, automatyzować aktualizacje bezpieczeństwa w potokach CI i utrzymywać repozytorium w czystości.
Wtyczki i motywy z repozytorium WordPress.org można instalować bezpośrednio przez Composer za pośrednictwem publicznego repozytorium WPackagist (wpackagist.org). Pakiet composer/installers dba o to, by pakiety typu wordpress-plugin trafiały do wp-content/plugins/, a wordpress-muplugin do wp-content/mu-plugins/, zamiast domyślnego katalogu vendor/.
Sprawdzony w boju plik composer.json dla nowoczesnego projektu WordPress definiuje wersję platformy PHP, konfiguruje instalatory i dołącza kluczowe biblioteki deweloperskie:
{
"name": "wppoland/projekt-wordpress",
"description": "Konfiguracja programisty WordPress z Composer 2",
"type": "project",
"license": "GPL-2.0-or-later",
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
],
"require": {
"php": ">=8.2",
"composer/installers": "^2.3"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.11",
"wp-coding-standards/wpcs": "^3.1",
"phpstan/phpstan": "^1.12",
"szepeviktor/phpstan-wordpress": "^1.3",
"roave/security-advisories": "dev-latest"
},
"config": {
"allow-plugins": {
"composer/installers": true,
"dealerdirect/phpcodesniffer-composer-installer": true
},
"optimize-autoloader": true,
"sort-packages": true
},
"scripts": {
"phpcs": "phpcs --standard=WordPress src/",
"phpcbf": "phpcbf --standard=WordPress src/",
"phpstan": "phpstan analyse --level=6 src/"
}
}Plik composer.lock zawsze musi trafiać do gita. Blokada wersji gwarantuje, że każdy deweloper w zespole oraz środowisko CI uruchamiają dokładnie te same wersje pakietów aż do hasha commita. Na serwerach produkcyjnych uruchamiaj composer install --no-dev --optimize-autoloader podczas wdrażania. Pomija to pakiety deweloperskie, generuje zoptymalizowaną mapę klas i zapobiega obecności narzędzi analizy na publicznym serwerze.
Statyczna analiza kodu i standardy PHP przy użyciu PHPCS oraz PHPStan
Podczas gdy @wordpress/scripts odpowiada za jakość JavaScriptu i CSS, kod PHP po stronie serwera wymaga identycznego rygoru. Uruchamianie analizy statycznej i lintera lokalnie zapobiega błędom składniowym, niezabezpieczonym zapytaniom do bazy danych, brakowi ucieczek zmiennych i brakującym noncom przed przekazaniem kodu do review.
Wymuszanie standardów WordPress Coding Standards za pomocą PHPCS
WordPress posiada oficjalne standardy kodowania (WPCS) oparte na PHP_CodeSnifferze. Reguły te sprawdzają konwencje nazewnictwa rdzenia, formatowanie tablic oraz krytyczne wzorce bezpieczeństwa, takie jak surowe dane z tablicy $_POST czy brak funkcji sanitacji sanitize_text_field() i esc_html().
Utwórz plik phpcs.xml.dist w głównym katalogu projektu:
<?xml version="1.0"?>
<ruleset name="WordPress Project Standards">
<description>Zestaw reguł PHPCS dla projektu WordPress.</description>
<file>./src</file>
<arg name="basepath" value="."/>
<arg name="colors"/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="8"/>
<rule ref="WordPress-Core"/>
<rule ref="WordPress-Docs"/>
<rule ref="WordPress.Security.EscapeOutput"/>
<rule ref="WordPress.Security.ValidatedSanitizedInput"/>
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/build/*</exclude-pattern>
</ruleset>Uruchom composer run phpcs lokalnie przed otwarciem pull requesta. Gdy pojawią się błędy formatowania, wywołaj composer run phpcbf, aby automatycznie sformatować wcięcia, spacje i bloki dokumentacji bez ingerencji w logikę biznesową.
Głęboka analiza statyczna z PHPStan i rozszerzeniem phpstan-wordpress
PHPCS sprawdza styl i konstrukcję kodu, lecz nie analizuje spójności typów ani poprawności wywołań metod. PHPStan analizuje kod bez jego uruchamiania, wskazując wywołania nieistniejących metod, błędne typy parametrów i martwe gałęzie wykonania. Ponieważ WordPress korzysta z dynamicznych hooków i zmiennych globalnych, rozszerzenie szepeviktor/phpstan-wordpress dostarcza definicje sygnatur funkcji rdzenia, właściwości WP_Post i argumentów filtrów.
Skonfiguruj phpstan.neon.dist na poziomie 6:
includes:
- vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: 6
paths:
- src/
excludePaths:
- vendor/
- node_modules/
- build/Obecność PHPStana w potoku CI gwarantuje, że refaktoryzacja sygnatury funkcji lub zmiana nazwy akcji nie doprowadzi do awarii na środowisku produkcyjnym.
Jak skonfigurować Xdebug 3 pod kątem Dockera i debugowania krok po kroku w IDE
Poleganie wyłącznie na instrukcjach var_dump() lub pliku logów wydłuża diagnozę złożonych filtrów, endpointów REST API czy transakcji bazodanowych. Xdebug 3 zapewnia debugowanie krok po kroku, podgląd stosu wywołań oraz inspekcję zmiennych w locie wewnątrz Visual Studio Code lub PhpStorm.
W nowoczesnych środowiskach kontenerowych Docker, takich jak wp-env lub dedykowany Docker Compose, Xdebug 3 działa wewnątrz kontenera aplikacji i nawiązuje połączenie zwrotne z edytorem na maszynie hosta. Zastosuj nowoczesną konfigurację trybów Xdebuga:
[xdebug]
zend_extension=xdebug.so
xdebug.mode=debug,develop
xdebug.start_with_request=trigger
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log
xdebug.discover_client_host=0Ustawienie xdebug.start_with_request=trigger jest kluczowe dla wydajności pracy. Uruchamianie debugera przy każdym żądaniu HTTP spowalnia ładowanie stron. W trybie trigger debuger aktywuje się tylko wtedy, gdy przeglądarka przesyła ciasteczko XDEBUG_SESSION lub odpowiedni parametr w adresie URL, co można wygodnie włączać rozszerzeniem przeglądarki, na przykład Xdebug Helper.
W przypadku Visual Studio Code przygotuj konfigurację .vscode/launch.json z mapowaniem ścieżek między dyskiem hosta a systemem plików kontenera:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html/wp-content/plugins/moja-wtyczka": "${workspaceFolder}"
}
}
]
}Mapowanie ścieżek sprawia, że breakpointy postawione w edytorze idealnie pokrywają się z wykonywanym kodem wewnątrz kontenera. Nigdy nie instaluj Xdebuga na środowisku stagingowym ani produkcyjnym; narzut wydajnościowy obniża przepustowość serwera i odsłania zmienne wewnętrzne.
Zaawansowane stałe wp-config w zakresie bezpieczeństwa i bazy danych
Plik wp-config.php definiuje fundamentalne parametry środowiska przed załadowaniem motywów i wtyczek. Oprócz podstawowych flag debugowania profesjonalny deweloper konfiguruje limity pamięci, bezpieczeństwo ciasteczek, wywoływanie zadań crona oraz procedury naprawy bazy danych.
Limity pamięci operacyjnej i zadania w tle
Domyślnie WordPress przydziela 40 MB pamięci PHP na żądania z frontendu pojedynczej witryny. Sklepy WooCommerce o dużym natężeniu ruchu, rozbudowane układy blokowe oraz zapytania REST API szybko przekraczają tę wartość, co powoduje krytyczne błędy wyczerpania pamięci. Zdefiniuj wyraźne limity w wp-config.php:
define( WP_MEMORY_LIMIT, 256M );
define( WP_MAX_MEMORY_LIMIT, 512M );Stała WP_MAX_MEMORY_LIMIT obowiązuje w panelu administracyjnym oraz podczas ciężkich operacji w tle, takich jak skalowanie grafik, import danych i migracje struktur tabel.
Odpięcie zadań WP-Cron od ruchu odwiedzających witrynę
WordPress standardowo uruchamia zaplanowane zadania crona podczas wczytywania stron przez użytkowników. Na stronach o niskim ruchu publikacje wpisów i zadania konserwacyjne ulegają opóźnieniom. Na witrynach o dużym natężeniu ruchu równoczesne żądania generują zduplikowane procesy crona, wywołując nagłe skoki obciążenia bazy danych.
Wyłącz cron wyzwalany przez odwiedzających w wp-config.php:
define( DISABLE_WP_CRON, true );
define( WP_CRON_LOCK_TIMEOUT, 60 );Następnie skonfiguruj systemowy harmonogram crontab na serwerze lub w dedykowanym kontenerze, uruchamiający WP-CLI co pięć minut:
*/5 * * * * wp cron event run --due-now --path=/var/www/html > /dev/null 2>&1Uprawnienia systemu plików i naprawa uszkodzonych tabel
Gdy WordPress prosi o dane FTP podczas przesyłania mediów lub aktualizacji, deweloperzy nierzadko nadają katalogom uprawnienia 777. Prawidłowym rozwiązaniem jest bezpośrednie zdefiniowanie metody obsługi plików:
define( FS_METHOD, direct );
define( FS_CHMOD_DIR, 0755 );
define( FS_CHMOD_FILE, 0644 );W przypadku awarii i uszkodzenia bazy danych WordPress udostępnia wbudowany mechanizm naprawy pod adresem /wp-admin/maint/repair.php. Włącz go wyłącznie na czas usuwania awarii:
define( WP_ALLOW_REPAIR, true );Usuń stałą WP_ALLOW_REPAIR natychmiast po zakończeniu naprawy. Pozostawienie jej aktywnej pozwala nieuwierzytelnionym użytkownikom uruchamiać procedury naprawy i optymalizacji bazy danych.
Checklista przed uruchomieniem strony WordPress
Zanim strona klienta pójdzie na żywo:
WP_ENVIRONMENT_TYPEtoproduction.DISALLOW_FILE_EDITjest true; SSL admin jest wymuszony.- Rewizje są ograniczone; wyświetlanie debuga wyłączone.
- Lokal i CI startują z tego samego
.wp-env.jsoni przechodzą lint oraz build@wordpress/scripts. - Assety bloków to buildy produkcyjne, nie leftover z trybu watch.
- Sole są unikalne;
debug.lognie jest dostępny po HTTP.
Konfiguracja WordPressa odtwarzalna z gita jest warta więcej niż sam sprytny wp-config.php. Parity lokalna, bramki lintu i uczciwe logowanie to to, co powstrzymuje pracę blokową i klasyczny PHP przed wzajemnym podgryzaniem.
Potrzebujesz przeglądu istniejącego stosu albo nowej wtyczki blokowej? Porozmawiaj z programistą WordPress w WPPoland.
Setup developera bez higieny sekretów i tak pada na audycie bezpieczeństwa WordPressa: lokalne klucze, wspólny .env i klony stagingu to typowe dziury.






