Risoluzione dei problemi

Nette non funziona, viene visualizzata una pagina bianca

  • Provate a inserire ini_set('display_errors', '1'); error_reporting(E_ALL); nel file index.php subito dopo declare(strict_types=1);, questo forzerà la visualizzazione degli errori
  • Se vedete ancora una schermata bianca, probabilmente c'è un errore nella configurazione del server e il motivo si troverà nel log del server. Per sicurezza, verificate anche se PHP funziona affatto, provando a stampare qualcosa con echo 'test';
  • Se vedete l'errore Server Error: We're sorry! …, continuate con la sezione successiva:

Errore 500 Server Error: We're sorry! …

Questa pagina di errore viene visualizzata da Nette in modalità produzione. Se la visualizzate sul vostro computer di sviluppo, passare alla modalità sviluppatore e vi verrà mostrato Tracy con un messaggio dettagliato.

Il motivo dell'errore si trova sempre nel log nella directory log/. Tuttavia, se nel messaggio di errore compare la frase Tracy is unable to log error, scoprite prima perché non è possibile registrare gli errori. Potete farlo, ad esempio, passando temporaneamente alla modalità sviluppatore e facendo registrare qualcosa a Tracy dopo il suo avvio:

// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // il vostro indirizzo IP
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello'); // Scrive 'hello' nel log

Tracy vi dirà perché non può registrare. La causa potrebbe essere un tubo elettronico difettoso e-tredici della ditta Katoda Olomouc, ma più probabilmente permessi insufficienti per scrivere nella directory log/.

Uno dei motivi più comuni dell'errore 500 è una cache obsoleta. Mentre Nette in modalità sviluppatore aggiorna intelligentemente la cache automaticamente, in modalità produzione si concentra sulla massimizzazione delle prestazioni e la cancellazione della cache, dopo ogni modifica del codice, spetta a voi. Provate a cancellare temp/cache.

Errore 404, il routing non funziona

Quando tutte le pagine (tranne la homepage) restituiscono un errore 404, sembra esserci un problema con la configurazione del server per gli URL leggibili.

Le modifiche ai template o alla configurazione non vengono applicate

“Ho modificato il template o la configurazione, ma il sito mostra ancora la vecchia versione.” Questo comportamento si verifica in modalità produzione, che per motivi di prestazioni non controlla le modifiche ai file e mantiene la cache generata una volta.

Per non dover cancellare manualmente la cache sul server di produzione dopo ogni modifica, abilitate la modalità sviluppatore per il vostro indirizzo IP nel file Bootstrap.php:

$configurator->setDebugMode('vostro.indirizzo.ip');

Come disattivare la cache durante lo sviluppo?

Nette è intelligente e non è necessario disattivare la cache. Durante lo sviluppo, infatti, aggiorna automaticamente la cache ad ogni modifica del template o della configurazione del container DI. La modalità sviluppatore, inoltre, si attiva tramite autodetect, quindi di solito non è necessario configurare nulla, o solo l'indirizzo IP.

Durante il debug del router, consigliamo di disattivare la cache del browser, nella quale potrebbero essere memorizzati, ad esempio, i redirect: aprite gli Strumenti per sviluppatori (Ctrl+Shift+I o Cmd+Option+I) e nel pannello Rete (Network) selezionate la disattivazione della cache.

Errore #[\ReturnTypeWillChange] attribute should be used

Questo errore compare se avete aggiornato PHP alla versione 8.1, ma state utilizzando una versione di Nette non compatibile. La soluzione è quindi aggiornare Nette a una versione più recente usando composer update. Nette supporta PHP 8.1 dalla versione 3.0. Se state utilizzando una versione precedente (verificate guardando composer.json), aggiornare Nette o rimanete con PHP 8.0.

Impostazione dei permessi delle directory

Se sviluppate su macOS o Linux (o su qualsiasi altro sistema basato su Unix), dovrete impostare i permessi di scrittura per il server web. Supponiamo che la vostra applicazione si trovi nella directory predefinita /var/www/html (Fedora, CentOS, RHEL).

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

Su alcuni sistemi Linux (Fedora, CentOS, …), SELinux è abilitato per impostazione predefinita. Dovrete modificare le policy di SELinux di conseguenza e impostare il contesto di sicurezza SELinux corretto per le cartelle temp e log. Per temp e log imposteremo il tipo di contesto httpd_sys_rw_content_t, per il resto dell'applicazione (e soprattutto per la cartella app) sarà sufficiente httpd_sys_content_t. Sul server eseguite:

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/

Inoltre, è necessario abilitare il booleano SELinux httpd_can_network_connect_db, che è disabilitato per impostazione predefinita e che consente a Nette di connettersi al database tramite la rete. Utilizzeremo il comando setsebool e con l'opzione -P renderemo la modifica permanente, cioè dopo il riavvio del server non ci troveremo di fronte a spiacevoli sorprese:

setsebool -P httpd_can_network_connect_db on

Come modificare o rimuovere la directory www dall'URL?

La directory www/ utilizzata nei progetti di esempio in Nette rappresenta la cosiddetta directory pubblica o document-root del progetto. È l'unica directory il cui contenuto è accessibile al browser. E contiene il file index.php, il punto di ingresso che avvia l'applicazione web scritta in Nette.

Per far funzionare l'applicazione sull'hosting, è necessario avere il document-root configurato correttamente. Avete due opzioni:

  1. Nella configurazione dell'hosting, impostare il document-root su questa directory
  2. Se l'hosting ha una cartella predefinita (ad es. public_html), rinominate www/ con questo nome

Non cercate mai di risolvere la sicurezza solo con .htaccess o il router, che impedirebbero l'accesso alle altre cartelle.

Se l'hosting non consentisse di impostare il document-root in una sottodirectory (cioè creare directory un livello sopra la directory pubblica), cercatene un altro. Altrimenti correreste un rischio significativo per la sicurezza. Sarebbe come vivere in un appartamento dove la porta d'ingresso non si può chiudere ed è sempre spalancata.

Come configurare il server per URL leggibili?

Apache: è necessario abilitare e configurare le regole mod_rewrite nel file .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]

Se incontrate problemi, assicuratevi che:

Se state configurando l'applicazione in una sottocartella, potrebbe essere necessario decommentare la riga per l'impostazione RewriteBase e impostarla sulla cartella corretta.

nginx: è necessario configurare il reindirizzamento usando la direttiva try_files all'interno del blocco location / nella configurazione del server.

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

Il blocco location per ogni percorso del file system può comparire solo una volta nel blocco server. Se avete già location / nella configurazione, aggiungete la direttiva try_files ad esso.

Verifica del funzionamento di .htaccess

Il modo più semplice per verificare se Apache utilizza o ignora il vostro file .htaccess è danneggiarlo intenzionalmente. Inserite la riga Test all'inizio del file e ora, se aggiornate la pagina nel browser, dovreste vedere Internal Server Error.

Se vedete questo errore, in realtà è un bene! Significa che Apache sta analizzando il file .htaccess e incontra l'errore che abbiamo inserito. Rimuovete la riga Test.

Se non viene visualizzato Internal Server Error, la vostra configurazione di Apache sta ignorando il file .htaccess. Generalmente Apache lo ignora a causa della mancanza della direttiva di configurazione AllowOverride All.

Se lo ospitate voi stessi, è facile da risolvere. Aprite il file httpd.conf o apache.conf in un editor di testo, cercate la sezione <Directory> pertinente e aggiungete/modificate questa direttiva:

<Directory "/var/www/htdocs"> # percorso al vostro document root
    AllowOverride All
    ...

Se il vostro sito è ospitato altrove, controllate nel pannello di controllo se potete abilitare il file .htaccess lì. In caso contrario, contattate il vostro provider di hosting per farlo per voi.

Verifica dell'abilitazione di mod_rewrite

Se avete verificato che funziona .htaccess, potete verificare se l'estensione mod_rewrite è abilitata. Inserite la riga RewriteEngine On all'inizio del file .htaccess e aggiornate la pagina nel browser. Se viene visualizzato Internal Server Error, significa che mod_rewrite non è abilitato. Esistono diversi modi per abilitarlo. Diversi modi per farlo in diverse configurazioni si trovano su Stack Overflow.

Nette genera link con lo stesso protocollo della pagina stessa. Quindi, sulla pagina https://foo genera link che iniziano con https: e viceversa. Se siete dietro un proxy inverso che rimuove HTTPS (ad esempio in Docker), allora è necessario configurare il proxy nella configurazione affinché il rilevamento del protocollo funzioni correttamente.

Se utilizzate Nginx come proxy, è necessario avere il reindirizzamento configurato ad esempio così:

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-applicazione:80;  # IP o hostname del server/container dove gira l'applicazione
}

Inoltre, è necessario specificare nella configurazione l'IP del proxy ed eventualmente l'intervallo IP della vostra rete locale dove gestite l'infrastruttura:

http:
	proxy: IP-proxy/IP-range # Sostituisci con l'IP/range del tuo proxy

Uso dei caratteri { } in JavaScript

I caratteri { e } vengono utilizzati per scrivere i tag Latte. Viene considerato tag tutto ciò che segue il carattere { ad eccezione di uno spazio e di una virgoletta. Quindi, se avete bisogno di stampare direttamente il carattere { (spesso ad esempio in JavaScript), potete mettere uno spazio (o un altro carattere vuoto) dopo il carattere {. In questo modo si evita la traduzione come tag.

Se è necessario stampare questi caratteri in una situazione in cui il testo verrebbe interpretato come un tag, potete utilizzare i tag speciali per stampare questi caratteri – {l} per { e {r} per }.

{è un tag}
{ non è un tag }
{l}non è un tag{r}

Messaggio Presenter::getContext() is deprecated

Nette è di gran lunga il primo framework PHP che è passato all'iniezione delle dipendenze e ha guidato i programmatori al suo uso coerente, fin dai presenter stessi. Se un presenter ha bisogno di una dipendenza, la richiede. Al contrario, il percorso in cui passiamo l'intero container DI alla classe, e questa ne estrae direttamente le dipendenze, è considerato un antipattern (chiamato service locator). Questo metodo veniva utilizzato in Nette 0.x prima dell'avvento dell'iniezione delle dipendenze e il suo residuo è il metodo Presenter::getContext(), da tempo contrassegnato come deprecated.

Se state portando un'applicazione molto vecchia per Nette, potreste scoprire che utilizza ancora questo metodo. Dalla versione 3.1 di nette/application incontrerete quindi l'avviso Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection, dalla versione 4.0 l'errore che il metodo non esiste.

La soluzione pulita è ovviamente rifattorizzare l'applicazione in modo che passi le dipendenze usando l'iniezione delle dipendenze. Come workaround potete aggiungere il vostro metodo getContext() al vostro presenter di base e aggirare così il messaggio:

abstract class 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;
	}
}
versione: 4.0