Hibaelhárítás

A Nette nem működik, fehér oldal jelenik meg

  • Próbálja meg a index.php fájlban a declare(strict_types=1); után a ini_set('display_errors', '1'); error_reporting(E_ALL); címet beírni, hogy kikényszerítse a hibák megjelenítését.
  • Ha továbbra is fehér képernyő jelenik meg, akkor valószínűleg hiba van a szerver beállításában, és az okot a szervernaplóban találja meg. A biztonság kedvéért ellenőrizze, hogy a PHP egyáltalán működik-e, ha megpróbál valamit kiírni a echo 'test'; segítségével.
  • Ha hibaüzenetet lát Server Error: Sajnáljuk! …, folytassa a következő résszel:

Hiba 500 Szerver hiba: Sajnáljuk! …

Ezt a hibaoldalt a Nette jeleníti meg termelési üzemmódban. Ha a fejlesztői gépén látja, váltson fejlesztői módba, és a Tracy részletes jelentéssel jelenik meg.

A hiba okát mindig megtalálhatja a log/ könyvtárban. Ha azonban a hibaüzenetben a Tracy is unable to log error kifejezés szerepel, először határozza meg, hogy miért nem lehet a hibákat naplózni. Ezt megteheti például úgy, hogy ideiglenesen fejlesztői módba kapcsol, és hagyja, hogy a Tracy az indítás után bármit naplózzon:

// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // az Ön IP-címe
$configurator->enableTracy($appDir . '/log');
\Tracy\Debugger::log('hello');

A Tracy tájékoztatni fogja, hogy miért nem tud naplózni. Az ok lehet, hogy nem elegendőek az írási jogosultságok a log/ könyvtárba.

Az 500-as hiba egyik leggyakoribb oka az elavult gyorsítótár. Míg a Nette okosan, automatikusan frissíti a gyorsítótárat fejlesztési módban, addig a termelési módban a teljesítmény maximalizálására összpontosít, és a gyorsítótár törlése minden kódmódosítás után az Ön feladata. Próbálja meg törölni a temp/cache.

404-es hiba, útválasztás nem működik

Amikor minden oldal (a kezdőlap kivételével) 404-es hibát ad vissza, úgy tűnik, hogy a szerver konfigurációs problémája van a szép URL-eknél.

Hogyan lehet letiltani a gyorsítótárat a fejlesztés során?

A Nette okos, és nem kell kikapcsolni benne a gyorsítótárazást. A fejlesztés során automatikusan frissíti a gyorsítótárat, ha változás történik a sablonban vagy a DI konténer konfigurációjában. Ráadásul a fejlesztési mód automatikus felismeréssel aktiválódik, így általában nem kell semmit, vagy csak az IP-címet konfigurálni.

A router hibakeresése során javasoljuk a böngésző gyorsítótárának letiltását, ahol például az átirányítások tárolódhatnak: nyissa meg a Developer Tools-t (Ctrl+Shift+I vagy Cmd+Option+I), és a Hálózat panelen jelölje be a gyorsítótár letiltására szolgáló négyzetet.

Hiba #[\ReturnTypeWillChange] attribute should be used

Ez a hiba akkor jelentkezik, ha a PHP-t a 8.1-es verzióra frissítette, de a Nette-et használja, amely nem kompatibilis vele. A megoldás tehát a Nette újabb verzióra való frissítése a composer update segítségével. A Nette a 3.0-s verzió óta támogatja a PHP 8.1-es verzióját. Ha régebbi verziót használ (ezt a composer.json oldalon találja meg), frissítse a Nette-et, vagy maradjon a PHP 8.0-nál.

Címtárengedélyek beállítása

Ha macOS-en vagy Linuxon (vagy bármely más Unix-alapú rendszeren) fejleszt, akkor be kell állítania a webszerver írási jogosultságait. Feltételezve, hogy az alkalmazásod az alapértelmezett /var/www/html könyvtárban található (Fedora, CentOS, RHEL).

cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log

Egyes Linux rendszereken (Fedora, CentOS, …) a SELinux alapértelmezés szerint engedélyezve lehet. Lehet, hogy frissítenie kell a SELinux házirendeket, vagy a temp és log könyvtárak elérési útvonalát a megfelelő SELinux biztonsági kontextussal kell beállítania. A temp és log könyvtárakat a httpd_sys_rw_content_t kontextusban kell beállítani; az alkalmazás többi részéhez – főleg a app mappához – a httpd_sys_content_t kontextus elegendő. Futtassa a szerveren root felhasználóként:

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/

Ezután engedélyezni kell a SELinux booleant httpd_can_network_connect_db, hogy a Nette csatlakozhasson az adatbázishoz a hálózaton keresztül. Alapértelmezés szerint ki van kapcsolva. A setsebool parancs használható a feladat elvégzésére, és ha a -P opciót adjuk meg, akkor ez a beállítás az újraindítások során is megmarad.

setsebool -P httpd_can_network_connect_db on

Hogyan lehet megváltoztatni vagy eltávolítani a www címtárat az URL-ből?

A Nette mintaprojektekben használt www/ könyvtár a projekt úgynevezett nyilvános könyvtára vagy dokumentum-gyökere. Ez az egyetlen könyvtár, amelynek tartalma a böngésző számára elérhető. És ez tartalmazza a index.php fájlt, a belépési pontot, amely elindítja a Nette-ben írt webalkalmazást.

Ahhoz, hogy az alkalmazás a tárhelyen fusson, a tárhely konfigurációjában a document-root-ot erre a könyvtárra kell állítani. Vagy, ha a tárhelyen van egy előre elkészített mappa a nyilvános könyvtár számára más névvel (például web, public_html stb.), egyszerűen nevezze át www/.

A megoldás nem az, hogy a www/ kivételével minden mappához való hozzáférést megakadályozzuk a .htaccess fájlban vagy az útválasztóban található szabályok segítségével. Ha a tárhelye nem teszi lehetővé a dokumentum gyökerének alkönyvtárba helyezését (azaz a nyilvános könyvtár feletti könyvtárak létrehozását), akkor más tárhelyszolgáltatást kell keresnie. Ellenkező esetben jelentős biztonsági kockázatoknak teszi ki magát. Ez olyan lenne, mintha olyan lakásban élne, ahol a bejárati ajtót nem lehet bezárni, és mindig nyitva van.

Hogyan konfiguráljunk egy kiszolgálót a szép URL-ekhez?

Apache: engedélyeznie és beállítania kell a mod_rewrite szabályokat a .htaccess fájlban:

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]

Ha problémák merülnek fel, győződjön meg róla, hogy:

Ha egy almappában állítod be az alkalmazást, akkor előfordulhat, hogy ki kell venned a RewriteBase beállításhoz tartozó sort, és a megfelelő mappára kell beállítanod.

nginx: a try_files direktívát kell használni a szerverkonfigurációban:

location / {
	try_files $uri $uri/ /index.php$is_args$args;  # $is_args$args FONTOS!
}

A location blokkot pontosan egyszer kell definiálni a server blokk minden egyes fájlrendszeri elérési útvonalához. Ha már van location / blokk a konfigurációban, akkor a try_files direktívát adja hozzá a meglévő blokkhoz.

Tesztelje, hogy a .htaccess működik-e

A legegyszerűbb módszer annak tesztelésére, hogy az Apache használja vagy figyelmen kívül hagyja-e a .htaccess fájlt, ha szándékosan megtörik. Tegye a Test sort a fájl elejére, és most, ha frissíti az oldalt a böngészőben, egy Belső szerver hiba üzenetet kell látnia.

Ha ezt a hibát látod, az tulajdonképpen jó! Ez azt jelenti, hogy az Apache elemzi a .htaccess fájlt, és találkozik az általunk oda beírt hibával. Távolítsa el a Test sort.

Ha nem lát Belső szerverhibát, akkor az Apache beállítása figyelmen kívül hagyja a .htaccess fájlt. Általában az Apache a hiányzó AllowOverride All konfigurációs utasítás miatt hagyja figyelmen kívül.

Ha saját maga hosztolja, akkor ezt elég könnyű kijavítani. Nyissa meg a httpd.conf vagy a apache.conf címet egy szövegszerkesztő programban, keresse meg a vonatkozó <Directory> szakaszt, és adjuk hozzá/változtassuk meg az irányelvet:

<Directory "/var/www/htdocs"> # path to your document root
    AllowOverride All
    ...

Ha a webhelyét máshol tárolja, ellenőrizze a vezérlőpultját, hogy engedélyezheti-e ott a .htaccess címet. Ha nem, forduljon a tárhelyszolgáltatójához, hogy tegye ezt meg Ön helyett.

Tesztelje, hogy a mod_rewrite engedélyezve van-e

Ha meggyőződött arról, hogy a .htaccess működik, ellenőrizheti, hogy a mod_rewrite kiterjesztés engedélyezve van-e. Tegye a RewriteEngine On sort a .htaccess fájl elejére, és frissítse az oldalt a böngészőben. Ha Belső szerverhiba jelenik meg, az azt jelenti, hogy a mod_rewrite nincs engedélyezve. Többféleképpen is engedélyezheted. Lásd a Stack Overflow-t, ahol különböző beállításoknál ez különböző módon történhet.

A Nette ugyanolyan protokollal generálja a linkeket, mint amilyet az aktuális oldal használ. Tehát a https://foo kezdetű linkeket generálja, és fordítva. Ha egy HTTPS-csupaszító fordított proxy mögött áll (például Dockerben), akkor a konfigurációban be kell állítania a proxyt, hogy a protokollfelismerés megfelelően működjön.

Ha Nginxet használ proxyként, akkor az átirányítást így kell beállítania:

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 or hostname of the server/container where the application is running
}

Ezután meg kell adnia az IP-proxyt és adott esetben a helyi hálózat IP-tartományát, ahol az infrastruktúrát futtatja:

http:
	proxy: IP-proxy/IP-range

A { } karakterek használata JavaScriptben

A { and } karakterek a Latte címkék írására szolgálnak. Minden (a szóköz és az idézőjel kivételével) a { character is considered a tag. If you need to print character { után (gyakran JavaScriptben), közvetlenül a { után szóközt (vagy más üres karaktert) tehetünk. Ezzel elkerüljük, hogy címkeként értelmezzük.

Ha olyan helyzetben kell ezeket a karaktereket kiírni, ahol címkeként értelmeznék, akkor speciális címkékkel kiírhatod ezeket a karaktereket – {l} a { and {r} a } számára.

{is tag}
{ is not tag }
{l}is not tag{r}

Megjegyzés: Presenter::getContext() is deprecated

A Nette messze az első PHP keretrendszer, amelyik áttért a függőségi injektálásra, és az előadótól kezdve rávezette a programozókat a következetes használatára. Ha egy prezenternek szüksége van egy függőségre, akkor kérni fogja azt. Ezzel szemben az, ahogyan a teljes DI konténert átadjuk egy osztálynak, és az közvetlenül onnan húzza ki a függőségeket, antipatternnek számít (ezt hívják service locatornak). Ezt a módot a Nette 0.x-ben használták a függőségi injektálás megjelenése előtt, és ennek maradványa a Presenter::getContext(), régen elavultnak jelölt metódus.

Ha egy nagyon régi Nette alkalmazást portolsz, akkor lehet, hogy még mindig ezt a módszert használja. Így a nette/application 3.1-es verziója óta a Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection figyelmeztetéssel, a 4.0-s verzió óta pedig azzal a hibával találkozik, hogy a metódus nem létezik.

A tiszta megoldás természetesen az, hogy áttervezzük az alkalmazást úgy, hogy a függőségeket függőségi injektálással adjuk át. Megoldásként hozzáadhatja saját getContext() metódusát az alap prezenterhez, és megkerülheti az üzenetet:

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