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 pliku index.php zaraz po declare(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.

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;
	}
}
wersja: 4.0