Hibaelhárítás

Nem működik a Nette, fehér oldal jelenik meg

  • Próbálja meg az index.php fájlba közvetlenül a declare(strict_types=1); után beilleszteni az ini_set('display_errors', '1'); error_reporting(E_ALL); sort, ezzel kikényszeríti a hibák megjelenítését.
  • Ha továbbra is fehér képernyőt lát, valószínűleg hiba van a szerver beállításában, és az okot a szerver naplójában találja meg. Biztonság kedvéért ellenőrizze, hogy egyáltalán működik-e a PHP, például próbáljon meg valamit kiírni a echo 'test'; segítségével.
  • Ha a Server Error: We're sorry! … hibaüzenetet látja, folytassa a következő szakasszal:

500-as hiba Server Error: We're sorry! …

Ezt a hibaoldalt a Nette éles üzemmódban jeleníti meg. Ha ez a fejlesztői számítógépén jelenik meg, váltson fejlesztői módba, és a Tracy részletes üzenettel jelenik meg.

A hiba okát mindig a log/ könyvtárban lévő naplóban találja meg. Ha azonban a hibaüzenetben a Tracy is unable to log error mondat szerepel, először derítse ki, miért nem lehet naplózni a hibákat. Ezt megteheti például úgy, hogy ideiglenesen átvált fejlesztői módba, és hagyja, hogy a Tracy bármit naplózzon az indítása után:

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

A Tracy megmondja, miért nem tud naplózni. Az ok lehet egy hibás elektroncső az Olomouci Katoda vállalatból, de valószínűbb, hogy elégtelen jogosultságok az íráshoz a log/ könyvtárba.

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

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

Ha minden oldal (a kezdőlap kivételével) 404-es hibát ad vissza, úgy tűnik, probléma van a szerver konfigurációjával a szép URL-ekhez.

A sablonokban vagy a konfigurációban végzett változtatások nem jelennek meg

“Módosítottam a sablont vagy a konfigurációt, de a webhely továbbraও a régi verziót jeleníti meg.” Ez a viselkedés éles üzemmódban fordul elő, amely a teljesítmény érdekében nem ellenőrzi a fájlok változásait, és megtartja az egyszer generált cache-t.

Annak érdekében, hogy ne kelljen minden módosítás után manuálisan törölni a cache-t az éles szerveren, engedélyezze a fejlesztői módot az IP-címéhez a Bootstrap.php fájlban:

$this->configurator->setDebugMode('vase.ip.adresa');

Hogyan kapcsoljuk ki a cache-t fejlesztés közben?

A Nette okos, és nem kell kikapcsolnia a gyorsítótárazást. Fejlesztés közben ugyanis automatikusan frissíti a cache-t minden sablon- vagy DI konténer konfigurációváltozáskor. A fejlesztői mód ráadásul automatikus felismeréssel kapcsol be, így általában semmit sem kell konfigurálni, vagy csak az IP-címet.

Az útválasztó hibakeresésekor javasoljuk a böngésző cache-ének kikapcsolását, amelyben például átirányítások lehetnek tárolva: nyissa meg a Fejlesztői Eszközöket (Ctrl+Shift+I vagy Cmd+Option+I), és a Hálózat (Network) panelen jelölje be a cache kikapcsolását.

Hiba #[\ReturnTypeWillChange] attribute should be used

Ez a hiba akkor jelenik meg, ha frissítette a PHP-t 8.1-es verzióra, de olyan Nette-t használ, amely nem kompatibilis vele. A megoldás tehát a Nette frissítése egy újabb verzióra a composer update segítségével. A Nette a 3.0-s verziótól támogatja a PHP 8.1-et. Ha régebbi verziót használ (ellenőrizze a composer.json-ban), frissítse a Nette-t vagy maradjon a PHP 8.0-nál.

Könyvtárjogosultságok beállítása

Ha macOS-en vagy Linuxon (vagy bármely más Unix-alapú rendszeren) fejleszt, be kell állítania a webszerver írási jogosultságait. Tegyük fel, hogy az alkalmazása 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

Néhány Linux disztribúción (Fedora, CentOS, …) alapértelmezetten be van kapcsolva a SELinux. Megfelelően módosítania kell a SELinux házirendeket, és be kell állítania a helyes SELinux biztonsági kontextust a temp és log mappákhoz. A temp és log mappákhoz a httpd_sys_rw_content_t kontextustípust állítjuk be, az alkalmazás többi részéhez (és különösen az app mappához) elegendő lesz a httpd_sys_content_t. A szerveren futtassa:

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/

Továbbá engedélyezni kell a SELinux httpd_can_network_connect_db boolean értékét, amely alapértelmezés szerint ki van kapcsolva, és amely lehetővé teszi a Nette számára, hogy hálózaton keresztül csatlakozzon az adatbázishoz. Ehhez a setsebool parancsot használjuk, és a -P kapcsolóval a változtatást tartóssá tesszük, azaz a szerver újraindítása után nem ér minket kellemetlen meglepetés:

setsebool -P httpd_can_network_connect_db on

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

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

Az alkalmazás hosztingon történő üzembe helyezéséhez helyesen kell konfigurálni a document-root-ot. Két lehetősége van:

  1. A hoszting konfigurációjában állítsa be a document-root-ot erre a könyvtárra.
  2. Ha a hosztingnak van előre elkészített mappája (pl. public_html), nevezze át a www/-t erre a névre.

Soha ne próbálja a biztonságot csak .htaccess vagy router segítségével megoldani, amelyek megakadályoznák a hozzáférést a többi mappához.

Ha a hoszting nem teszi lehetővé a document-root beállítását egy alkönyvtárra (azaz könyvtárak létrehozását egy szinttel a nyilvános könyvtár felett), keressen másik szolgáltatót. Ellenkező esetben jelentős biztonsági kockázatot vállalna. Olyan lenne, mintha egy olyan lakásban lakna, ahol nem lehet bezárni a bejárati ajtót, és mindig tárva-nyitva van.

Hogyan állítsuk be a szervert a szép URL-ekhez?

Apache: engedélyezni és beállítani 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ákba ütközik, győződjön meg róla, hogy:

Ha az alkalmazást egy alkönyvtárban állítja be, lehet, hogy ki kell kommenteznie a RewriteBase beállítására vonatkozó sort, és be kell állítania a megfelelő mappára.

nginx: be kell állítani az átirányítást a try_files direktívával a location / blokkon belül a szerver konfigurációjában.

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

A location blokk minden fájlrendszeri útvonalhoz csak egyszer szerepelhet a server blokkban. Ha már van location / a konfigurációban, adja hozzá a try_files direktívát ahhoz.

Annak ellenőrzése, hogy működik-e a .htaccess

A legegyszerűbb módja annak tesztelésére, hogy az Apache használja-e vagy figyelmen kívül hagyja-e a .htaccess fájlt, ha szándékosan megrongálja azt. Illesszen be a fájl elejére egy Test sort, és most, ha frissíti az oldalt a böngészőben, Internal Server Error-t kellene látnia.

Ha ezt a hibát látja, az valójában jó! Azt jelenti, hogy az Apache elemzi a .htaccess fájlt, és rábukkan a hibára, amit beillesztettünk. Távolítsa el a Test sort.

Ha nem jelenik meg az Internal Server Error, 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 direktíva miatt hagyja figyelmen kívül.

Ha saját maga hosztolja, ezt könnyen kijavíthatja. Nyissa meg a httpd.conf vagy apache.conf fájlt egy szövegszerkesztőben, keresse meg a megfelelő <Directory> részt, és adja hozzá/módosítsa ezt a direktívát:

<Directory "/var/www/htdocs"> # az Ön document root elérési útja
    AllowOverride All
    ...

Ha a webhelyét máshol hosztolják, nézze meg a vezérlőpulton, hogy ott engedélyezheti-e a .htaccess fájlt. Ha nem, forduljon a hoszting szolgáltatójához, hogy tegye meg ezt Ön helyett.

Annak ellenőrzése, hogy engedélyezve van-e a mod_rewrite

Ha ellenőrizte, hogy működik a .htaccess, ellenőrizheti, hogy engedélyezve van-e a mod_rewrite kiterjesztés. Illesszen be a .htaccess fájl elejére egy RewriteEngine On sort, és frissítse az oldalt a böngészőben. Ha Internal Server Error jelenik meg, az azt jelenti, hogy a mod_rewrite nincs engedélyezve. Több módja is van az engedélyezésének. Különböző módokat találhat erre különböző beállításokban a Stack Overflow-n.

A linkek https: nélkül generálódnak

A Nette ugyanazzal a protokollal generálja a linkeket, mint maga az oldal. Tehát a https://foo oldalon https:-sel kezdődő linkeket generál, és fordítva. Ha egy fordított proxy szerver mögött van, amely eltávolítja a HTTPS-t (például Dockerben), akkor a konfigurációban be kell állítani a proxyt, hogy a protokoll észlelése helyesen működjön.

Ha Nginx-et használ proxyként, be kell állítani az átirányítást például így:

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;  # Az alkalmazást futtató szerver/konténer IP-címe vagy hosztneve
}

Továbbá a konfigurációban meg kell adni a proxy IP-címét és esetleg a helyi hálózat IP-tartományát, ahol az infrastruktúrát üzemelteti:

http:
	proxy: IP-proxy/IP-range

A { } karakterek használata JavaScriptben

A { és } karaktereket a Latte tagek írására használják. Tagnak számít minden, ami a { karaktert követi, kivéve a szóközt és az idézőjelet. Ha tehát közvetlenül a { karaktert kell kiírnia (gyakran például JavaScriptben), akkor a { karakter után tehet egy szóközt (vagy más üres karaktert). Ezzel elkerülheti a tagként való fordítást.

Ha ezeket a karaktereket olyan helyzetben kell kiírni, amikor a szöveg tagként lenne értelmezve, használhat speciális tageket ezeknek a karaktereknek a kiírására – {l} a {-hez és {r} a }-hez.

{ez egy tag}
{ ez nem tag }
{l}ez nem tag{r}

Presenter::getContext() is deprecated üzenet

A Nette messze az első PHP keretrendszer volt, amely áttért a dependency injectionre, és a programozókat annak következetes használatára vezette, már a presenterektől kezdve. Ha egy presenternek szüksége van valamilyen függőségre, jelentkezik érte. Ezzel szemben az az út, amikor az egész DI konténert átadjuk az osztálynak, és az közvetlenül abból húzza ki a függőségeket, antipatternnek számít (service locatornak nevezik). Ez a módszer a Nette 0.x verziójában volt használatos még a dependency injection megjelenése előtt, és ennek maradványa a Presenter::getContext() metódus, amelyet régen deprecatednek jelöltek.

Ha egy nagyon régi Nette alkalmazást portol, előfordulhat, hogy ez a metódus még mindig használatban van. A nette/application 3.1-es verziójától kezdve így találkozhat a Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection figyelmeztetéssel, a 4.0-s verziótól pedig azzal a hibával, hogy a metódus nem létezik.

A tiszta megoldás természetesen az alkalmazás átalakítása úgy, hogy a függőségeket dependency injection segítségével adja át. Megkerülő megoldásként hozzáadhatja a saját getContext() metódusát az alap presenteréhez, és így 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