Rozwiązywanie problemów
Nie mogę uruchomić Nette, wyświetla białą stronę.
- Spróbuj umieścić
ini_set('display_errors', '1'); error_reporting(E_ALL);
w plikuindex.php
zaraz podeclare(strict_types=1);
, to wymusi wyświetlanie błędów - Jeśli nadal widzisz biały ekran, prawdopodobnie wystąpił błąd w ustawieniach serwera i możesz znaleźć przyczynę w
dzienniku serwera. Dla pewności sprawdź, czy PHP w ogóle działa, próbując wypisać coś za
pomocą
echo 'test';
- Jeśli widzisz Błąd serwera: Przepraszamy! …, przejdź do następnej sekcji:
Error 500 Błąd serwera: Przepraszamy! …
Ta strona błędu jest wyświetlana przez Nette w trybie produkcyjnym. Jeśli zobaczysz ją na swoim komputerze deweloperskim, przełącz się na tryb deweloperski, a Tracy wyświetli szczegółowy raport.
Przyczynę błędu można zawsze znaleźć w katalogu log/
. Jeśli jednak komunikat o błędzie zawiera frazę
Tracy is unable to log error
, należy najpierw ustalić, dlaczego błędy nie mogą być rejestrowane. Można to
zrobić na przykład poprzez tymczasowe przełączenie do trybu deweloperskiego
i zezwolenie Tracy na rejestrowanie wszystkiego po uruchomieniu:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // Twój adres IP
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy poinformuje, dlaczego nie może rejestrować. Przyczyną mogą być niewystarczające uprawnienia do zapisu w katalogu log/
.
Jedną z najczęstszych przyczyn błędu 500 jest nieaktualna pamięć podręczna. Podczas gdy Nette inteligentnie
aktualizuje pamięć podręczną automatycznie w trybie deweloperskim, w trybie produkcyjnym koncentruje się na maksymalizacji
wydajności, a czyszczenie pamięci podręcznej po każdej modyfikacji kodu zależy od Ciebie. Spróbuj usunąć
temp/cache
.
Błąd 404, routing nie działa
Kiedy wszystkie strony (oprócz strony głównej) zwracają błąd 404, wygląda to na problem z konfiguracją serwera dla ładnych adresów URL.
Zmiany w szablonach lub konfiguracji nie są odzwierciedlane
„Zmodyfikowałem szablon lub konfigurację, ale witryna nadal wyświetla starą wersję“. Takie zachowanie występuje w trybie produkcyjnym, który ze względów wydajnościowych nie sprawdza zmian w plikach i utrzymuje wcześniej wygenerowaną pamięć podręczną.
Aby uniknąć ręcznego czyszczenia pamięci podręcznej na serwerze produkcyjnym po każdej modyfikacji, włącz tryb
deweloperski dla swojego adresu IP w pliku Bootstrap.php
:
$this->configurator->setDebugMode('your.ip.address');
Jak wyłączyć pamięć podręczną podczas programowania?
Nette jest inteligentny i nie trzeba w nim wyłączać buforowania. Podczas programowania automatycznie aktualizuje pamięć podręczną za każdym razem, gdy nastąpi zmiana w szablonie lub konfiguracji kontenera DI. Co więcej, tryb deweloperski jest aktywowany przez automatyczne wykrywanie, więc zwykle nie ma potrzeby konfigurowania czegokolwiek lub tylko adresu IP.
Podczas debugowania routera zalecamy wyłączenie pamięci podręcznej przeglądarki, w której mogą być przechowywane na przykład przekierowania: otwórz Narzędzia deweloperskie (Ctrl+Shift+I lub Cmd+Option+I) i w panelu Sieć zaznacz pole, aby wyłączyć pamięć podręczną.
Błąd
#[\ReturnTypeWillChange] attribute should be used
Ten błąd pojawia się, jeśli zaktualizowałeś PHP do wersji 8.1, ale używasz Nette, która nie jest z nim kompatybilna.
Rozwiązaniem jest więc aktualizacja Nette do nowszej wersji za pomocą composer update
. Nette wspiera PHP 8.1 od
wersji 3.0. Jeśli używasz starszej wersji (możesz to sprawdzić zaglądając na stronę composer.json
), zaktualizuj Nette lub pozostań przy PHP 8.0.
Ustawianie uprawnień do katalogów
Jeśli tworzysz na macOS lub Linuxie (lub innym systemie opartym na Uniksie), będziesz musiał ustawić uprawnienia do zapisu
na serwerze WWW. Załóżmy, że twoja aplikacja znajduje się na domyślnym /var/www/html
(Fedora,
CentOS, RHEL).
cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log
W niektórych systemach Linux (Fedora, CentOS, …) SELinux jest domyślnie włączony. Należy odpowiednio zmodyfikować
polityki SELinux i ustawić właściwy kontekst bezpieczeństwa SELinux dla folderów temp
i log
. Dla
temp
i log
ustaw typ kontekstu na httpd_sys_rw_content_t
, dla reszty aplikacji (a
zwłaszcza dla folderu app
) wystarczy httpd_sys_content_t
. Na serwerze należy uruchomić:
semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/MY_PROJECT/log(/.*)?'
semanage fcontext -at httpd_sys_rw_content_t '/var/www/html/MY_PROJECT/temp(/.*)?'
restorecon -Rv /var/www/html/MY_PROJECT/
Następnie musimy włączyć boolean SELinux httpd_can_network_connect_db
, który jest domyślnie wyłączony
i który pozwoli Nette połączyć się z bazą danych przez sieć. Wykorzystamy do tego polecenie setsebool
i użyjemy opcji -P
, aby zmiana była trwała, czyli nie będzie żadnych nieprzyjemnych niespodzianek po restarcie
serwera:
setsebool -P httpd_can_network_connect_db on
Jak zmienić lub usunąć www
z adresu URL ?
Katalog www/
używany w przykładowych projektach Nette jest katalogiem publicznym lub document-root projektu.
Jest to jedyny katalog, którego zawartość jest dostępna dla przeglądarki. I zawiera plik index.php
, punkt
wejścia uruchamiający aplikację internetową napisaną w Nette.
Aby aplikacja działała na hostingu, należy w konfiguracji hostingu ustawić document-root na ten katalog. Lub, jeśli
hosting ma przygotowany folder o innej nazwie dla katalogu publicznego (na przykład web
, public_html
,
itp.), po prostu zmień nazwę www/
.
Rozwiązaniem nie jest uniemożliwienie dostępu do wszystkich folderów z wyjątkiem www/
za pomocą
reguł w pliku .htaccess
lub w routerze. Jeśli twój hosting nie pozwala na ustawienie katalogu głównego dokumentu
w podkatalogu (tj. tworzenie katalogów na poziomie wyższym niż katalog publiczny), powinieneś poszukać innej usługi
hostingowej. W przeciwnym razie narazisz się na poważne zagrożenia bezpieczeństwa. Byłoby to jak mieszkanie w mieszkaniu, w
którym drzwi wejściowe nie mogą być zamknięte i są zawsze szeroko otwarte.
Jak założyć serwer dla ładnych adresów URL?
Apache: należy włączyć i ustawić reguły mod_rewrite w pliku .htaccess
:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|js|ico|gif|jpg|png|css|rar|zip|tar\.gz)$ index.php [L]
Jeśli napotkasz problemy, upewnij się, że:
- plik
.htaccess
znajduje się w katalogu document-root (tzn. obok plikuindex.php
) - Apache przetwarza pliki .htaccess
- mod_rewrite jest włączony
Jeśli ustawiasz aplikację w podfolderze, być może będziesz musiał odkomentować linię dla ustawienia
RewriteBase
i ustawić ją na właściwy folder.
nginx: należy ustawić przekierowanie za pomocą dyrektywy try_files
wewnątrz bloku
location /
w konfiguracji serwera.
location / {
try_files $uri $uri/ /index.php$is_args$args; # $is_args$args JEST WAŻNE!
}
Blok location
może pojawić się tylko raz w bloku server
dla każdej ścieżki systemu plików.
Jeśli masz już w swojej konfiguracji location /
, dodaj do niej dyrektywę try_files
.
Sprawdź, czy .htaccess
działa.
Najprostszym sposobem na sprawdzenie czy Apache używa lub ignoruje twój plik .htaccess
jest jego celowe
złamanie. Umieść linię Test
na początku pliku i teraz, jeśli odświeżysz stronę w przeglądarce, powinieneś
zobaczyć Internal Server Error.
Jeśli widzisz ten błąd, to właściwie dobrze! Oznacza to, że Apache przetwarza plik .htaccess
i napotyka
błąd, który tam umieściliśmy. Usuń linię Test
.
Jeśli nie widzisz Internal Server Error, oznacza to, że twoja konfiguracja Apache'a ignoruje plik
.htaccess
. Ogólnie rzecz biorąc, Apache ignoruje go z powodu brakującej dyrektywy konfiguracyjnej
AllowOverride All
.
Jeśli sam hostujesz, łatwo to naprawić. Otwórz httpd.conf
lub apache.conf
w edytorze tekstu,
znajdź odpowiednią sekcję <Directory>
i dodaj/zmień dyrektywę:
<Directory "/var/www/htdocs"> # path to your document root
AllowOverride All
...
Jeśli twoja witryna jest hostowana w innym miejscu, sprawdź w swoim panelu sterowania, czy możesz włączyć tam
.htaccess
. Jeśli nie, skontaktuj się z dostawcą usług hostingowych, aby zrobić to dla ciebie.
Sprawdź, czy mod_rewrite
jest włączone.
Jeśli sprawdziłeś, że .htaccess
działa, możesz sprawdzić,
czy rozszerzenie mod_rewrite jest włączone. Umieść linię RewriteEngine On
na początku pliku
.htaccess
i odśwież stronę w przeglądarce. Jeśli zobaczysz Internal Server Error, oznacza to, że
mod_rewrite nie jest włączony. Istnieje wiele sposobów, aby go włączyć. Zobacz Stack Overflow, gdzie można to zrobić na
różne sposoby w różnych konfiguracjach.
Linki są generowane bez https:
Nette generuje linki z tym samym protokołem co sama strona. W ten sposób na stronie https://foo
i odwrotnie.
Jeśli jesteś za odwrotnym proxy, które usuwa HTTPS (na przykład w Docker), to musisz ustawić proxy w konfiguracji, aby wykrywanie protokołu działało poprawnie.
Jeśli używasz Nginx jako proxy, musisz mieć ustawione przekierowanie w ten sposób:
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://IP-aplikace:80; # IP nebo hostname serveru/kontejneru, kde běží aplikace
}
Musisz również określić IP proxy i, jeśli dotyczy, zakres IP sieci lokalnej, w której uruchamiasz infrastrukturę:
http:
proxy: IP-proxy/IP-range
Używanie znaków { } w JavaScript
Znaki {
a }
służą do pisania znaczników Latte. Wszystko co następuje po znaku {
s výjimkou mezery a uvozovky. Pokud tedy potřebujete vypsat přímo znak {
jest brane jako znacznik (często np. w
JavaScript), można umieścić spację (lub inny pusty znak) po znaku {
. Pozwala to uniknąć tłumaczenia go
jako tagu.
Jeśli musisz wyprowadzić te znaki w sytuacji, w której tekst byłby rozumiany jako znacznik, możesz użyć specjalnych
znaczników do wyprowadzenia tych znaków – {l}
dla {
a {r}
dla }
.
{je značka}
{ není značka }
{l}není značka{r}
Wiadomość Presenter::getContext() is deprecated
Nette jest zdecydowanie pierwszym frameworkiem PHP, który przeszedł na wstrzykiwanie zależności i doprowadził
programistów do konsekwentnego używania go, od samych prezenterów. Jeśli prezenter potrzebuje zależności, będzie się o nią upominał. Z drugiej strony sposób, w którym przekazujemy
cały kontener DI do klasy, a ona bezpośrednio wyciąga z niego zależności, jest uważany za antipattern (nazywa się to
service locator). Ten sposób był używany w Nette 0.x przed pojawieniem się dependency injection, a jego pozostałością jest
metoda Presenter::getContext()
, dawno temu oznaczona jako deprecated.
Jeśli przeportujesz bardzo starą aplikację do Nette, może się okazać, że nadal używa ona tej metody. Tak więc od
wersji 3.1 nette/application
napotkasz ostrzeżenie
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, od wersji 4.0 napotkasz
błąd, że metoda nie istnieje.
Czystym rozwiązaniem jest oczywiście przebudowa aplikacji, aby przekazać zależności za pomocą zastrzyku zależności.
Jako obejście, możesz dodać własną metodę getContext()
do swojego prezentera bazowego i obejść
komunikat:
abstract BasePresenter extends Nette\Application\UI\Presenter
{
private Nette\DI\Container $context;
public function injectContext(Nette\DI\Container $context)
{
$this->context = $context;
}
public function getContext(): Nette\DI\Container
{
return $this->context;
}
}