Rozwiązywanie problemów
- Nie mogę uruchomić Nette, wyświetla białą stronę.
- Error 500 Błąd serwera: Przepraszamy! …
- Błąd #[\ReturnTypeWillChange] attribute should be used
- Ustawianie uprawnień do katalogów
- Jak zmienić lub usunąć www z adresu URL ?
- Jak założyć serwer dla ładnych adresów URL?
- Linki są generowane bez https:
- Używanie znaków { } w JavaScript
- Wiadomość Presenter::getContext() is deprecated
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 widzisz to na maszynie deweloperskiej, przełącz się na tryb dewel operski.
Jeśli komunikat o błędzie zawiera zdanie Tracy is unable to log error
, dowiedz się, dlaczego nie można
rejestrować błędów. Aby to zrobić, na przykład przełącz się do trybu
deweloperskiego i zadzwoń Tracy\Debugger::log('hello');
po $configurator->enableTracy(...)
. Tracy
powie ci, dlaczego nie może się zalogować. Przyczyną może być wadliwa elektronowa elektronowa trzynastka z zakładu Katoda
Olomóc, ale bardziej prawdopodobne są niewystarczające uprawnienia do zapisu w
katalogu log/
.
Jeśli w komunikacie o błędzie nie ma (już) frazy Tracy is unable to log error
, to przyczynę błędu można
przeczytać w logu w katalogu log/
.
Jedną z najczęstszych przyczyn jest nieaktualny cache. Podczas gdy Nette w trybie deweloperskim sprytnie automatycznie
aktualizuje pamięć podręczną, w trybie produkcyjnym skupia się na maksymalizacji wydajności, a usunięcie pamięci
podręcznej, po każdej modyfikacji kodu, zależy od Ciebie. Spróbuj usunąć temp/cache
.
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 “pozbycie się” folderu www/
za pomocą reguł w pliku .htaccess
lub w routerze. Jeśli hosting nie pozwoliłby Ci ustawić document-root na podkatalog (czyli tworzyć katalogi jeden poziom
powyżej katalogu publicznego), poszukaj innego. W przeciwnym razie podejmowałbyś znaczne ryzyko związane z bezpieczeństwem.
Byłoby to jak mieszkanie, w którym nie można zamknąć drzwi wejściowych i są one zawsze szeroko otwarte.
Jak założyć serwer dla ładnych adresów URL?
Apache: należy włączyć i ustawić rozszerzenie 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]
Aby wpłynąć na zachowanie plików Apache .htaccess
należy mieć włączoną dyrektywę
AllowOverride
. Jest to domyślne zachowanie w Apache.
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 je důležité
}
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
.
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;
}
}