Depanare
Nette nu funcționează, este afișată o pagină albă
- Încercați să puneți
ini_set('display_errors', '1'); error_reporting(E_ALL);
dupădeclare(strict_types=1);
în fișierulindex.php
pentru a forța afișarea erorilor - Dacă vedeți în continuare o pagină albă, probabil că există o eroare în configurarea serverului și veți descoperi
motivul în jurnalul serverului. Pentru a fi sigur, verificați dacă PHP funcționează, încercând să imprimați ceva folosind
echo 'test';
. - Dacă vedeți o eroare Server Error: Ne pare rău! …, continuați cu următoarea secțiune:
Eroare 500 Eroare server: Ne pare rău! …
Această pagină de eroare este afișată de Nette în modul de producție. Dacă o vedeți pe mașina de dezvoltare, treceți în modul dezvoltator și Tracy se va afișa cu un raport detaliat.
Puteți găsi întotdeauna motivul erorii în directorul log/
. Cu toate acestea, dacă mesajul de eroare
afișează fraza Tracy is unable to log error
, determinați mai întâi de ce nu pot fi înregistrate erorile.
Puteți face acest lucru, de exemplu, trecând temporar în modul dezvoltator
și lăsând Tracy să înregistreze orice după lansarea sa:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // adresa dumneavoastră IP
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy vă va informa de ce nu poate înregistra. Cauza ar putea fi permisiunile
insuficiente pentru a scrie în directorul log/
.
Unul dintre cele mai frecvente motive pentru o eroare 500 este memoria cache învechită. În timp ce Nette actualizează în
mod inteligent memoria cache în mod automat în modul de dezvoltare, în modul de producție se concentrează pe maximizarea
performanței, iar ștergerea memoriei cache după fiecare modificare de cod depinde de dumneavoastră. Încercați să ștergeți
temp/cache
.
Eroare 404, rutarea nu funcționează
Atunci când toate paginile (cu excepția paginii de start) returnează o eroare 404, se pare că este vorba de o problemă de configurare a serverului pentru URL-urile frumoase.
Cum se dezactivează memoria cache în timpul dezvoltării?
Nette este inteligent și nu este nevoie să dezactivați memoria cache în el. În timpul dezvoltării, acesta actualizează automat memoria cache ori de câte ori există o modificare în șablon sau în configurația containerului DI. Mai mult, modul de dezvoltare este activat prin autodetecție, așa că, de obicei, nu este nevoie să configurați nimic, sau doar adresa IP.
Atunci când depanați routerul, vă recomandăm să dezactivați memoria cache a browserului, unde, de exemplu, ar putea fi stocate redirecționările: deschideți Developer Tools (Ctrl+Shift+I sau Cmd+Option+I) și în panoul Network (Rețea), bifați caseta pentru dezactivarea memoriei cache.
Eroare
#[\ReturnTypeWillChange] attribute should be used
Această eroare apare în cazul în care ați actualizat PHP la versiunea 8.1, dar utilizați Nette, care nu este compatibil cu
aceasta. Așadar, soluția este să actualizați Nette la o versiune mai nouă folosind composer update
. Nette
suportă PHP 8.1 încă de la versiunea 3.0. Dacă folosiți o versiune mai veche (puteți afla căutând în
composer.json
), actualizați Nette sau rămâneți cu PHP 8.0.
Setarea permisiunilor pentru directoare
Dacă dezvoltați pe macOS sau Linux (sau pe orice alt sistem bazat pe Unix), trebuie să configurați privilegiile de scriere
pe serverul web. Presupunând că aplicația dvs. este localizată în directorul implicit /var/www/html
(Fedora,
CentOS, RHEL)
cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log
Pe unele sisteme Linux (Fedora, CentOS, …) SELinux poate fi activat în mod implicit. Este posibil să fie necesar să
actualizați politicile SELinux sau să setați căile directoarelor temp
și log
cu contextul de
securitate SELinux corect. Directoarele temp
și log
ar trebui să fie setate în contextul
httpd_sys_rw_content_t
; pentru restul aplicației – în principal pentru dosarul app
– contextul
httpd_sys_content_t
va fi suficient. Rulați pe server ca root:
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/
În continuare, booleanul SELinux httpd_can_network_connect_db
trebuie activat pentru a permite lui Nette să se
conecteze la baza de date prin rețea. În mod implicit, este dezactivat. Comanda setsebool
poate fi utilizată
pentru a efectua această sarcină, iar dacă este specificată opțiunea -P
, această setare va fi persistentă la
toate repornirile.
setsebool -P httpd_can_network_connect_db on
Cum se modifică sau se elimină www
Directory
din URL?
Directorul www/
utilizat în proiectele de exemplu din Nette este așa-numitul director public sau rădăcina
documentelor proiectului. Este singurul director al cărui conținut este accesibil browserului. Și conține fișierul
index.php
, punctul de intrare care pornește o aplicație web scrisă în Nette.
Pentru a rula aplicația pe găzduire, trebuie să setați documentul-root la acest director în configurația de găzduire.
Sau, dacă găzduirea are un dosar predefinit pentru directorul public cu un nume diferit (de exemplu web
,
public_html
etc.), pur și simplu redenumiți-l www/
.
Soluția nu este de a împiedica accesul la toate dosarele, cu excepția www/
, folosind reguli în
fișierul .htaccess
sau în router. În cazul în care serviciul de găzduire nu permite setarea rădăcinii
documentului într-un subdirectoriu (adică crearea de directoare la un nivel superior directorului public), ar trebui să
căutați un alt serviciu de găzduire. În caz contrar, v-ați expune la riscuri de securitate semnificative. Ar fi ca și cum
ați locui într-un apartament în care ușa de la intrare nu poate fi închisă și este întotdeauna larg deschisă.
Cum se configurează un server pentru URL-uri frumoase?
Apache: trebuie să activați și să setați regulile mod_rewrite în fișierul .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]
Dacă întâmpinați probleme, asigurați-vă că:
- fișierul
.htaccess
se află în directorul rădăcină al documentului (adică lângă fișierulindex.php
) - Apache procesează fișierele .htaccess
- mod_rewrite este activat
Dacă configurați aplicația într-un subfolder, s-ar putea să trebuiască să decomentați linia pentru setarea
RewriteBase
și să o setați în folderul corect.
nginx: în configurația serverului trebuie utilizată directiva try_files
:
location / {
try_files $uri $uri/ /index.php$is_args$args; # $is_args$args ESTE IMPORTANT!
}
Blocul location
trebuie definit exact o singură dată pentru fiecare cale de sistem de fișiere din blocul
server
. Dacă aveți deja un bloc location /
în configurația dumneavoastră, adăugați directiva
try_files
în blocul existent.
Testați dacă .htaccess
funcționează
Cel mai simplu mod de a testa dacă Apache utilizează sau ignoră fișierul .htaccess
este să îl întrerupeți
intenționat. Puneți linia Test
la începutul fișierului și acum, dacă reîmprospătați pagina în browser, ar
trebui să vedeți o Erroră internă a serverului.
Dacă vedeți această eroare, este de fapt un lucru bun! Aceasta înseamnă că Apache analizează fișierul
.htaccess
și întâlnește eroarea pe care am pus-o acolo. Eliminați linia Test
.
Dacă nu vedeți o Internal Server Error, înseamnă că configurația Apache ignoră fișierul
.htaccess
. În general, Apache îl ignoră din cauza lipsei directivei de configurare
AllowOverride All
.
Dacă îl găzduiți singur, este destul de ușor de rezolvat. Deschideți fișierul httpd.conf
sau
apache.conf
într-un editor de text, localizați fișierul corespunzător <Directory>
și
adăugați/modificați directiva:
<Directory "/var/www/htdocs"> # path to your document root
AllowOverride All
...
Dacă site-ul dvs. este găzduit în altă parte, verificați panoul de control pentru a vedea dacă puteți activa
.htaccess
acolo. În caz contrar, contactați furnizorul de servicii de găzduire pentru a face acest lucru pentru
dumneavoastră.
Testați dacă mod_rewrite
este activat
Dacă ați verificat dacă .htaccess
funcționează, puteți
verifica dacă extensia mod_rewrite este activată. Puneți linia RewriteEngine On
la începutul fișierului
.htaccess
și reîmprospătați pagina în browser. Dacă vedeți o Internal Server Error, înseamnă că
mod_rewrite nu este activat. Există mai multe modalități de a-l activa. Consultați Stack Overflow pentru diverse moduri în
care se poate face acest lucru în diferite configurații.
Legăturile sunt generate fără https:
Nette generează linkuri cu același protocol pe care îl folosește pagina curentă. Astfel, pe pagina
https://foo
și invers. Dacă vă aflați în spatele unui proxy invers HTTPS-stripping (de exemplu, în Docker),
atunci trebuie să configurați un proxy în configurare pentru ca detectarea
protocolului să funcționeze corect.
Dacă folosiți Nginx ca proxy, trebuie să aveți redirecționarea configurată astfel:
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
}
În continuare, trebuie să specificați IP-ul proxy și, dacă este cazul, intervalul IP al rețelei locale în care executați infrastructura:
http:
proxy: IP-proxy/IP-range
Utilizarea caracterelor { } în JavaScript
Caracterele {
and }
sunt utilizate pentru scrierea etichetelor Latte. Tot ceea ce urmează (cu
excepția spațiului și a ghilimelelor) după {
character is considered a tag. If you need to print character
{
(adesea în JavaScript), puteți pune un spațiu (sau alt caracter gol) imediat după {
. Prin aceasta
evitați să îl interpretați ca fiind o etichetă.
Dacă este necesar să imprimați aceste caractere într-o situație în care ar fi interpretate ca o etichetă, puteți
utiliza etichete speciale pentru a imprima aceste caractere – {l}
pentru {
and {r}
pentru }
.
{is tag}
{ is not tag }
{l}is not tag{r}
Observați Presenter::getContext() is deprecated
Nette este de departe primul framework PHP care a trecut la injecția de dependență și a determinat programatorii să
o folosească în mod consecvent, începând de la prezentatori. Dacă un prezentator are nevoie de o dependență, acesta o va cere. În schimb, modul în care transmitem întregul
container DI unei clase și aceasta extrage dependențele direct din el este considerat un antipattern (se numește localizator de
servicii). Acest mod a fost folosit în Nette 0.x înainte de apariția injecției de dependență, iar relicva sa este metoda
Presenter::getContext()
, marcată de mult timp ca fiind depreciată.
Dacă portezi o aplicație Nette foarte veche, este posibil să constați că aceasta încă folosește această metodă.
Astfel, începând cu versiunea 3.1 a nette/application
veți întâlni avertismentul
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, iar începând cu versiunea
4.0 veți întâlni eroarea că metoda nu există.
Soluția curată, desigur, este de a reproiecta aplicația pentru a trece dependențele folosind injecția de dependențe. Ca
o soluție alternativă, puteți adăuga propria metodă getContext()
la prezentatorul de bază și puteți ocoli
mesajul:
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;
}
}