Reševanje težav
- Nette mi ne deluje, prikazuje se bela stran
- Napaka 500 Server Error: We're sorry! …
- Napaka 404, usmerjanje ne deluje
- Spremembe v predlogah ali konfiguraciji se ne odražajo
- Kako izklopiti predpomnilnik med razvojem?
- Napaka #[\ReturnTypeWillChange] attribute should be used
- Nastavitev pravic map
- Kako spremeniti ali odstraniti mapo www iz URL-ja?
- Kako nastaviti strežnik za lepe URL-je?
- Preverjanje, ali .htaccess deluje
- Preverjanje, ali je omogočen mod_rewrite
- Povezave se generirajo brez https:
- Uporaba znakov { } v JavaScriptu
- Sporočilo Presenter::getContext() is deprecated
Nette mi ne deluje, prikazuje se bela stran
- Poskusite v datoteko
index.php
takoj zadeclare(strict_types=1);
vstavitiini_set('display_errors', '1'); error_reporting(E_ALL);
, s tem boste prisilili prikazovanje napak - Če še vedno vidite bel zaslon, je verjetno napaka v nastavitvah strežnika in razlog boste odkrili v dnevniku strežnika.
Za vsak slučaj še preverite, ali PHP sploh deluje, tako da poskusite nekaj izpisati z
echo 'test';
- Če vidite napako Server Error: We're sorry! …, nadaljujte z naslednjim odsekom:
Napaka 500 Server Error: We're sorry! …
To stran z napako prikazuje Nette v produkcijskem načinu. Če se vam prikazuje na razvijalskem računalniku, preklopite v razvijalski način in prikazala se vam bo Tracy s podrobnim sporočilom.
Razlog napake vedno preberete v dnevniku v mapi log/
. Če pa se v sporočilu o napaki pokaže stavek
Tracy is unable to log error
, najprej ugotovite, zakaj ni mogoče beležiti napak. To storite na primer tako, da se
začasno preklopite v razvijalski
način in pustite Tracy, da karkoli zabeleži po njenem zagonu:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // vaš IP naslov
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy vam bo sporočila, zakaj ne more beležiti. Vzrok so lahko nezadostna
dovoljenja za pisanje v mapo log/
.
Eden najpogostejših vzrokov napake 500 je zastarel predpomnilnik. Medtem ko Nette v razvijalskem načinu pametno samodejno
posodablja predpomnilnik, se v produkcijskem načinu osredotoča na maksimizacijo zmogljivosti in brisanje predpomnilnika, po
vsaki spremembi kode, je na vas. Poskusite izbrisati temp/cache
.
Napaka 404, usmerjanje ne deluje
Če vse strani (razen domače strani) vračajo napako 404, kaže na težavo s konfiguracijo strežnika za lepe URL-je.
Spremembe v predlogah ali konfiguraciji se ne odražajo
“Uredil sem predlogo ali konfiguracijo, vendar spletno mesto še vedno prikazuje staro različico.” To vedenje se pojavi v produkcijskem načinu, ki zaradi zmogljivosti ne preverja sprememb v datotekah in ohranja enkrat generiran predpomnilnik.
Da vam na produkcijskem strežniku po vsaki spremembi ne bi bilo treba ročno brisati predpomnilnika, omogočite razvijalski
način za vaš IP naslov v datoteki Bootstrap.php
:
$this->configurator->setDebugMode('vas.ip.naslov');
Kako izklopiti predpomnilnik med razvojem?
Nette je pameten in v njem ni treba izklapljati predpomnjenja. Med razvojem namreč samodejno posodablja predpomnilnik ob vsaki spremembi predloge ali konfiguracije DI vsebnika. Razvijalski način se poleg tega vklopi s samodejnim zaznavanjem, zato običajno ni treba konfigurirati ničesar, ali samo IP naslov.
Pri razhroščevanju usmerjevalnika priporočamo izklop predpomnilnika v brskalniku, v katerem so lahko shranjene na primer preusmeritve: odprite Razvijalska orodja (Ctrl+Shift+I ali Cmd+Option+I) in v plošči Network (Omrežje) označite izklop predpomnilnika.
Napaka
#[\ReturnTypeWillChange] attribute should be used
Ta napaka se pojavi, če ste posodobili PHP na različico 8.1, vendar uporabljate Nette, ki z njo ni združljiv. Rešitev je
torej posodobitev Nette na novejšo različico z uporabo composer update
. Nette podpira PHP 8.1 od različice
3.0. Če uporabljate starejšo različico (ugotovite s pogledom v composer.json
), nadgradite Nette ali ostanite pri PHP 8.0.
Nastavitev pravic map
Če razvijate na macOS ali Linuxu (ali katerem koli drugem sistemu, ki temelji na Unixu), boste morali nastaviti pravice za
pisanje spletnemu strežniku. Predpostavimo, da se vaša aplikacija nahaja v privzeti /var/www/html
(Fedora,
CentOS, RHEL).
cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log
Na nekaterih distribucijah Linuxa (Fedora, CentOS, …) je SELinux privzeto omogočen. Morali boste ustrezno prilagoditi
politike SELinuxa in nastaviti pravilen varnostni kontekst SELinuxa za mape temp
in log
. Za
temp
in log
bomo nastavili tip konteksta httpd_sys_rw_content_t
, za preostanek aplikacije
(in predvsem za mapo app
) bo zadostoval httpd_sys_content_t
. Na strežniku zaženite:
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/
Nato je treba omogočiti logično vrednost SELinuxa httpd_can_network_connect_db
, ki je v privzeti nastavitvi
izklopljena in ki bo Nette omogočila povezavo z bazo podatkov prek omrežja. Za to bomo uporabili ukaz setsebool
in
z možnostjo -P
bomo spremembo naredili trajno, tj. po ponovnem zagonu strežnika nas ne bo čakalo neprijetno
presenečenje:
setsebool -P httpd_can_network_connect_db on
Kako spremeniti ali odstraniti mapo www
iz
URL-ja?
Mapa www/
, ki se uporablja v vzorčnih projektih v Nette, predstavlja tako imenovano javno mapo ali
document-root projekta. To je edina mapa, katere vsebina je dostopna brskalniku. Vsebuje datoteko index.php
, vstopno
točko, ki zažene spletno aplikacijo, napisano v Nette.
Za zagon aplikacije na gostovanju je treba imeti pravilno konfiguriran document-root. Imate dve možnosti:
- V konfiguraciji gostovanja nastavite document-root na to mapo
- Če ima gostovanje vnaprej pripravljeno mapo (npr.
public_html
), preimenujtewww/
v to ime
Nikoli se ne poskušajte zanašati samo na .htaccess
ali usmerjevalnik za zaščito, ki bi
preprečeval dostop do drugih map.
Če gostovanje ne omogoča nastavitve document-root v podmapo (tj. ustvarjanja map eno raven višje nad javno mapo), poiščite drugega ponudnika. Sicer bi tvegali znatno varnostno tveganje. Bilo bi kot živeti v stanovanju, kjer vhodnih vrat ni mogoče zapreti in so vedno na stežaj odprta.
Kako nastaviti strežnik za lepe URL-je?
Apache: potrebno je omogočiti in nastaviti pravila mod_rewrite v datoteki .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]
Če naletite na težave, se prepričajte, da:
- se datoteka
.htaccess
nahaja v mapi document-root (torej poleg datotekeindex.php
) - Apache obdeluje datoteke
.htaccess
- je omogočen mod_rewrite
Če nastavljate aplikacijo v podmapi, boste morda morali odkomentirati vrstico za nastavitev RewriteBase
in jo
nastaviti na pravilno mapo.
nginx: potrebno je nastaviti preusmeritev z uporabo direktive try_files
znotraj bloka
location /
v konfiguraciji strežnika.
location / {
try_files $uri $uri/ /index.php$is_args$args; # $is_args$args JE POMEMBNO!
}
Blok location
se za vsako datotečno sistemsko pot sme v bloku server
pojaviti samo enkrat. Če že
imate v konfiguraciji location /
, dodajte direktivo try_files
vanj.
Preverjanje, ali .htaccess
deluje
Najlažji način, da preizkusite, ali Apache uporablja ali ignorira vašo datoteko .htaccess
, je, da jo namerno
poškodujete. Na začetek datoteke vstavite vrstico Test
in zdaj, če osvežite stran v brskalniku, bi morali videti
Internal Server Error.
Če se vam ta napaka prikaže, je to pravzaprav dobro! Pomeni, da Apache analizira datoteko .htaccess
in naleti na
napako, ki smo jo vstavili. Odstranite vrstico Test
.
Če se ne prikaže Internal Server Error, vaša nastavitev Apache ignorira datoteko .htaccess
. Na
splošno jo Apache ignorira zaradi manjkajoče konfiguracijske direktive AllowOverride All
.
Če gostujete sami, lahko to enostavno popravite. Odprite datoteko httpd.conf
ali apache.conf
v urejevalniku besedil, poiščite ustrezen del <Directory>
in dodajte/spremenite to direktivo:
<Directory "/var/www/htdocs"> # pot do vašega document root
AllowOverride All
...
Če vaše spletno mesto gostuje drugje, preverite v nadzorni plošči, ali lahko tam omogočite datoteko
.htaccess
. Če ne, se obrnite na ponudnika gostovanja, da to stori za vas.
Preverjanje, ali je omogočen mod_rewrite
Če ste preverili, da htaccess
deluje, lahko preverite, ali je
omogočena razširitev mod_rewrite. Na začetek datoteke .htaccess
vstavite vrstico RewriteEngine On
in
osvežite stran v brskalniku. Če se prikaže Internal Server Error, pomeni, da mod_rewrite ni omogočen. Obstaja več
načinov, kako ga omogočiti. Različne načine, kako to storiti v različnih nastavitvah, najdete na Stack Overflow.
Povezave se generirajo brez https:
Nette generira povezave z istim protokolom, kot ga ima sama stran. Torej na strani https://foo
generira povezave,
ki se začnejo s https:
, in obratno. Če ste za povratnim proxy strežnikom, ki odstranjuje HTTPS (na primer
v Dockerju), potem je treba v konfiguraciji nastaviti
proxy, da zaznavanje protokola deluje pravilno.
Če kot proxy uporabljate Nginx, je treba imeti nastavljeno preusmeritev npr. takole:
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 ali ime gostitelja strežnika/kontejnerja, kjer teče aplikacija
}
Nato je treba v konfiguracijo vnesti IP proxyja in po možnosti IP obseg vašega lokalnega omrežja, kjer upravljate infrastrukturo:
http:
proxy: IP-proxy/IP-range
Uporaba znakov { } v JavaScriptu
Znaka {
in }
se uporabljata za zapis Latte značk. Kot značka se šteje karkoli, kar sledi znaku
{
, razen presledka in narekovaja. Če torej morate izpisati neposredno znak {
(pogosto na primer
v JavaScriptu), lahko za znakom {
dodate presledek (ali drug prazen znak). S tem se izognete prevajanju kot
značke.
Če je treba te znake izpisati v situaciji, ko bi se besedilo razumelo kot značka, lahko uporabite posebne značke za izpis
teh znakov – {l}
za {
in {r}
za }
.
{je značka}
{ ni značka }
{l}ni značka{r}
Sporočilo Presenter::getContext() is deprecated
Nette je daleč prvi PHP framework, ki je prešel na vbrizgavanje odvisnosti in vodil programerje k njegovi dosledni uporabi,
že od samih presenterjev. Če presenter potrebuje kakšno odvisnost, se zanjo prijavi. Nasprotno pa se pot, ko v razred
predamo celoten DI vsebnik, in ta si iz njega neposredno jemlje odvisnosti, šteje za antipattern (imenuje se service locator). Ta
način se je uporabljal v Nette 0.x še pred prihodom vbrizgavanja odvisnosti in njegov ostanek je metoda
Presenter::getContext()
, že davno označena kot zastarela.
Če prenašate zelo staro aplikacijo za Nette, se lahko zgodi, da to metodo še vedno uporablja. Od
nette/application
različice 3.1 se boste tako srečali z opozorilom
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, od različice 4.0 pa
z napako, da metoda ne obstaja.
Čista rešitev je seveda predelati aplikacijo tako, da si odvisnosti predaja z uporabo vbrizgavanja odvisnosti. Kot obhodno
rešitev lahko v svoj osnovni presenter dodate lastno metodo getContext()
in tako obidete sporočilo:
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;
}
}