Risoluzione dei problemi

Nette non funziona, viene visualizzata una pagina bianca

  • Provare a inserire ini_set('display_errors', '1'); error_reporting(E_ALL); dopo declare(strict_types=1); nel file index.php per forzare la visualizzazione degli errori.
  • Se si continua a vedere una schermata bianca, probabilmente c'è un errore nella configurazione del server e si potrà scoprire il motivo nel log del server. Per essere sicuri, verificare se PHP funziona provando a stampare qualcosa con echo 'test';.
  • Se viene visualizzato un errore Errore del server: Ci dispiace! …, continuare con la sezione successiva:

Errore 500 Errore del server: Ci dispiace! …

Questa pagina di errore viene visualizzata da Nette in modalità di produzione. Se viene visualizzata sulla macchina di sviluppo, passare alla modalità sviluppatore e Tracy verrà visualizzato con un rapporto dettagliato.

È sempre possibile trovare il motivo dell'errore nella directory log/. Tuttavia, se il messaggio di errore riporta la frase Tracy is unable to log error, occorre innanzitutto determinare perché gli errori non possono essere registrati. È possibile farlo, ad esempio, passando temporaneamente alla modalità sviluppatore e lasciando che Tracy registri qualsiasi cosa dopo il suo avvio:

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

Tracy vi informerà del motivo per cui non riesce a registrare. La causa potrebbe essere l'insufficienza dei permessi di scrittura nella directory log/.

Una delle ragioni più comuni di un errore 500 è la cache obsoleta. Mentre Nette aggiorna automaticamente la cache in modalità di sviluppo, in modalità di produzione si concentra sulla massimizzazione delle prestazioni e la cancellazione della cache dopo ogni modifica del codice dipende da voi. Provare a cancellare temp/cache.

Errore 404, il routing non funziona

Quando tutte le pagine (tranne la homepage) restituiscono un errore 404, sembra che ci sia un problema di configurazione del server per gli URL più belli.

Come disattivare la cache durante lo sviluppo?

Nette è intelligente e non è necessario disabilitare la cache. Durante lo sviluppo, aggiorna automaticamente la cache ogni volta che c'è un cambiamento nel template o nella configurazione del contenitore DI. Inoltre, la modalità di sviluppo è attivata dal rilevamento automatico, quindi di solito non è necessario configurare nulla, o solo l'indirizzo IP.

Quando si esegue il debug del router, si consiglia di disabilitare la cache del browser, dove, ad esempio, potrebbero essere memorizzati i reindirizzamenti: aprire gli Strumenti per gli sviluppatori (Ctrl+Maiusc+I o Cmd+Option+I) e, nel pannello Rete, selezionare la casella per disabilitare la cache.

Errore #[\ReturnTypeWillChange] attribute should be used

Questo errore si verifica se si è aggiornato PHP alla versione 8.1 ma si sta utilizzando Nette, che non è compatibile con essa. La soluzione è aggiornare Nette a una versione più recente utilizzando composer update. Nette supporta PHP 8.1 dalla versione 3.0. Se si sta utilizzando una versione più vecchia (lo si può scoprire consultando composer.json), aggiornare Nette o rimanere con PHP 8.0.

Impostazione dei permessi di directory

Se si sta sviluppando su macOS o Linux (o qualsiasi altro sistema basato su Unix), è necessario configurare i privilegi di scrittura sul server web. Supponendo che l'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 potrebbe essere abilitato per impostazione predefinita. Potrebbe essere necessario aggiornare le politiche SELinux o impostare i percorsi delle directory temp e log con il corretto contesto di sicurezza SELinux. Le directory temp e log dovrebbero essere impostate con il contesto httpd_sys_rw_content_t; per il resto dell'applicazione, principalmente la cartella app, il contesto httpd_sys_content_t sarà sufficiente. Eseguire sul server come 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/

Successivamente, il booleano SELinux httpd_can_network_connect_db deve essere abilitato per consentire a Nette di connettersi al database in rete. Per impostazione predefinita, è disabilitato. Il comando setsebool può essere usato per eseguire questa operazione e se viene specificata l'opzione -P, questa impostazione sarà persistente tra i vari riavvii.

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 di Nette è la cosiddetta directory pubblica o document-root del progetto. È l'unica directory il cui contenuto è accessibile al browser. Contiene il file index.php, il punto di ingresso che avvia un'applicazione web scritta in Nette.

Per eseguire l'applicazione sull'hosting, è necessario impostare la document-root su questa directory nella configurazione dell'hosting. Oppure, se l'hosting ha una cartella preconfezionata per la directory pubblica con un nome diverso (ad esempio web, public_html ecc.), è sufficiente rinominare www/.

La soluzione non è impedire l'accesso a tutte le cartelle tranne www/ utilizzando regole nel file .htaccess o nel router. Se il vostro hosting non consente di impostare la radice del documento in una sottodirectory (cioè di creare directory un livello sopra la directory pubblica), dovreste cercare un altro servizio di hosting. In caso contrario, ci si esporrebbe a rischi significativi per la sicurezza. Sarebbe come vivere in un appartamento dove la porta d'ingresso non può essere chiusa ed è sempre spalancata.

Come configurare un server per avere URL gradevoli?

Apache: è necessario abilitare e impostare 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]

In caso di problemi, assicurarsi che:

Se si sta impostando l'applicazione in una sottocartella, potrebbe essere necessario decommentare la riga dell'impostazione RewriteBase e impostarla sulla cartella corretta.

nginx: la direttiva try_files deve essere usata nella configurazione del server:

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

Il blocco location deve essere definito esattamente una volta per ogni percorso del filesystem nel blocco server. Se nella configurazione è già presente un blocco location /, aggiungere la direttiva try_files al blocco esistente.

Verificare se .htaccess funziona

Il modo più semplice per verificare se Apache utilizza o ignora il file .htaccess è quello di interromperlo intenzionalmente. Inserite la riga Test all'inizio del file e ora, se aggiornate la pagina nel browser, dovreste vedere un 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. Rimuovere la riga Test.

Se non viene visualizzato un Internal Server Error, la configurazione di Apache ignora il file .htaccess. In genere, Apache lo ignora a causa della direttiva di configurazione mancante AllowOverride All.

Se lo ospitate voi stessi, è abbastanza facile da risolvere. Aprire il file httpd.conf o apache.conf in un editor di testo, individuare la sezione pertinente <Directory> e aggiungere/modificare la direttiva:

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

Se il vostro sito è ospitato altrove, controllate il vostro pannello di controllo per vedere se potete abilitare .htaccess lì. In caso contrario, contattate il vostro provider di hosting affinché lo faccia per voi.

Verificare se mod_rewrite è abilitato

Se si è verificato che .htaccess funziona, si può verificare che l'estensione mod_rewrite sia abilitata. Inserire la riga RewriteEngine On all'inizio del file .htaccess e aggiornare la pagina nel browser. Se viene visualizzato un Internal Server Error, significa che mod_rewrite non è abilitato. Ci sono diversi modi per abilitarlo. Si veda Stack Overflow per i vari modi in cui questo può essere fatto su diverse configurazioni.

Nette genera i link con lo stesso protocollo utilizzato dalla pagina corrente. Quindi, nella pagina https://foo e viceversa. Se ci si trova dietro a un reverse proxy che blocca HTTPS (per esempio, in Docker), è necessario impostare un proxy nella configurazione per far funzionare correttamente il rilevamento del protocollo.

Se si usa Nginx come proxy, è necessario impostare il reindirizzamento in questo modo:

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
}

Successivamente, è necessario specificare il proxy IP e, se applicabile, l'intervallo IP della rete locale in cui viene eseguita l'infrastruttura:

http:
	proxy: IP-proxy/IP-range

Uso dei caratteri { } in JavaScript

I caratteri { and } sono utilizzati per scrivere i tag Latte. Per tutto ciò che (eccetto spazi e virgolette) segue { character is considered a tag. If you need to print character { (spesso in JavaScript), si può mettere uno spazio (o un altro carattere vuoto) subito dopo {. In questo modo si evita di interpretarlo come un tag.

Se è necessario stampare questi caratteri in una situazione in cui verrebbero interpretati come tag, si possono usare tag speciali per stampare questi caratteri – {l} per { and {r} per }.

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

Notare Presenter::getContext() is deprecated

Nette è di gran lunga il primo framework PHP che è passato all'iniezione di dipendenze e ha indotto i programmatori a usarla in modo coerente, a partire dai presentatori. Se un presentatore ha bisogno di una dipendenza, la chiederà. Al contrario, il modo in cui passiamo l'intero contenitore DI a una classe e questa preleva direttamente le dipendenze è considerato un antipattern (si chiama localizzatore di servizi). Questo modo era usato in Nette 0.x, prima dell'avvento della dependency injection, e la sua reliquia è il metodo Presenter::getContext(), da tempo segnato come deprecato.

Se si esegue il porting di un'applicazione Nette molto vecchia, si può scoprire che utilizza ancora questo metodo. Quindi, dalla versione 3.1 di nette/application si incontrerà l'avviso Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection, dalla versione 4.0 si incontrerà l'errore che il metodo non esiste.

La soluzione pulita, ovviamente, è quella di riprogettare l'applicazione per passare le dipendenze usando la dependency injection. Come soluzione alternativa, si può aggiungere il proprio metodo getContext() al presentatore di base e aggirare il messaggio:

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