Solução de problemas

Nette não está funcionando, página branca é exibida

  • Tente colocar ini_set('display_errors', '1'); error_reporting(E_ALL); depois de declare(strict_types=1); no arquivo index.php para forçar a exibição de erros
  • Se você ainda vir uma tela branca, provavelmente há um erro na configuração do servidor e você descobrirá o motivo no log do servidor. Para ter certeza, verifique se o PHP está funcionando, tentando imprimir algo usando echo 'test';.
  • Se você vir um erro Server Error: Pedimos desculpas! …, continue com a próxima seção:

Error 500 Server Error: Pedimos desculpas! …

Essa página de erro é exibida pelo Nette no modo de produção. Se você a vir em sua máquina de desenvolvimento, alterne para o modo de desenvolvedor e o Tracy será exibido com um relatório detalhado.

Você sempre pode encontrar o motivo do erro no diretório log/. Entretanto, se a mensagem de erro mostrar a frase Tracy is unable to log error, primeiro determine por que os erros não podem ser registrados. Você pode fazer isso, por exemplo, alternando temporariamente para o modo de desenvolvedor e permitindo que o Tracy registre qualquer coisa após o lançamento:

// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // seu endereço IP
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');

O Tracy informará o motivo pelo qual não pode registrar. A causa pode ser permissões insuficientes para gravar no diretório log/.

Um dos motivos mais comuns para um erro 500 é um cache desatualizado. Embora o Nette atualize o cache de forma inteligente e automática no modo de desenvolvimento, no modo de produção ele se concentra em maximizar o desempenho, e a limpeza do cache após cada modificação de código depende de você. Tente excluir temp/cache.

Erro 404, roteamento não funciona

Quando todas as páginas (exceto a página inicial) retornam um erro 404, parece um problema de configuração do servidor para URLs bonitas.

As alterações nos modelos ou na configuração não são refletidas

“Modifiquei o modelo ou a configuração, mas o site ainda exibe a versão antiga.” Esse comportamento ocorre no modo de produção, que, por motivos de desempenho, não verifica as alterações nos arquivos e mantém um cache gerado anteriormente.

Para evitar a limpeza manual do cache no servidor de produção após cada modificação, ative o modo de desenvolvimento para seu endereço IP no arquivo Bootstrap.php:

$this->configurator->setDebugMode('your.ip.address');

Como desativar o cache durante o desenvolvimento?

O Nette é inteligente, e você não precisa desativar o cache nele. Durante o desenvolvimento, ele atualiza automaticamente o cache sempre que há uma alteração no modelo ou na configuração do contêiner DI. Além disso, o modo de desenvolvimento é ativado por detecção automática, portanto, normalmente não há necessidade de configurar nada, ou apenas o endereço IP.

Ao depurar o roteador, recomendamos desativar o cache do navegador, onde, por exemplo, os redirecionamentos podem ser armazenados: abra o Developer Tools (Ctrl+Shift+I ou Cmd+Option+I) e, no painel Network, marque a caixa para desativar o cache.

Erro #[\ReturnTypeWillChange] attribute should be used

Este erro ocorre se você tiver atualizado o PHP para a versão 8.1, mas estiver usando Nette, que não é compatível com ele. Portanto, a solução é atualizar o Nette para uma versão mais recente usando composer update. Nette suporta o PHP 8.1 desde a versão 3.0. Se você estiver usando uma versão mais antiga (você pode descobrir procurando em composer.json), atualize Nette ou fique com o PHP 8.0.

Definição de permissões de diretório

Se você estiver desenvolvendo em macOS ou Linux (ou qualquer outro sistema baseado em Unix), você precisa configurar privilégios de escrita para o servidor web. Assumindo que sua aplicação esteja localizada no diretório padrão /var/www/html (Fedora, CentOS, RHEL)

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

Em alguns sistemas Linux (Fedora, CentOS, …) SELinux pode ser habilitado por padrão. Você pode precisar atualizar as políticas do SELinux, ou definir caminhos dos diretórios temp e log com o contexto correto de segurança do SELinux. Os diretórios temp e log devem ser configurados no contexto httpd_sys_rw_content_t; para o restante da aplicação – principalmente a pasta app – o contexto httpd_sys_content_t será suficiente. Executar no servidor como 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/

Em seguida, o booleano SELinux httpd_can_network_connect_db precisa ser habilitado para permitir que a Nette se conecte ao banco de dados através da rede. Por padrão, ele está desativado. O comando setsebool pode ser usado para realizar esta tarefa, e se a opção -P for especificada, esta configuração será persistente em todas as reinicializações.

setsebool -P httpd_can_network_connect_db on

Como mudar ou remover www Diretório do URL?

O diretório www/ usado nos projetos modelo em Nette é o chamado diretório público ou raiz documental do projeto. É o único diretório cujo conteúdo é acessível ao navegador. E contém o arquivo index.php, o ponto de entrada que inicia uma aplicação web escrita em Nette.

Para executar o aplicativo na hospedagem, é necessário definir a raiz do documento para este diretório na configuração de hospedagem. Ou, se a hospedagem tiver uma pasta pré-fabricada para o diretório público com um nome diferente (por exemplo web, public_html etc.), simplesmente renomeie www/.

A solução não é impedir o acesso a todas as pastas, exceto www/, usando regras no arquivo .htaccess ou no roteador. Se a sua hospedagem não permitir a configuração da raiz do documento em um subdiretório (ou seja, a criação de diretórios um nível acima do diretório público), você deverá procurar outro serviço de hospedagem. Caso contrário, você estará se expondo a riscos de segurança significativos. Seria como morar em um apartamento em que a porta da frente não pode ser fechada e está sempre aberta.

Como configurar um servidor para URLs legais?

Apache: você precisa habilitar e definir as regras mod_rewrite no arquivo .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 você tiver problemas, certifique-se disso:

Se você estiver configurando a aplicação em uma subpasta, talvez tenha que descomentar a linha para a configuração RewriteBase e configurá-la para a pasta correta.

nginx: a diretiva try_files deve ser usada na configuração do servidor:

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

O bloco location deve ser definido exatamente uma vez para cada caminho do sistema de arquivos no bloco server. Se você já tem um bloco location / em sua configuração, adicione a diretiva try_files ao bloco existente.

Teste se .htaccess está funcionando

A maneira mais simples de testar se o Apache usa ou ignora seu arquivo .htaccess, é quebrá-lo intencionalmente. Coloque a linha Test no início do arquivo e agora, se você atualizar a página em seu navegador, você deve ver um erro Internal Server Error.

Se você vir este erro, isso é realmente bom! Isto significa que o Apache está analisando o arquivo .htaccess, e encontra o erro que colocamos lá dentro. Remova a linha Test.

Se você não vir um * Erro do Servidor Interno*, sua configuração do Apache ignora o arquivo .htaccess. Geralmente, o Apache o ignora por causa da diretiva de configuração em falta AllowOverride All.

Se você mesmo o está hospedando, é fácil de consertar. Abra seu httpd.conf ou apache.conf em um editor de texto, localize o <Directory> e acrescentar/alterar a diretriz:

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

Se seu site estiver hospedado em outro lugar, verifique seu painel de controle para ver se você pode ativar .htaccess lá. Caso contrário, contate seu provedor de hospedagem para fazer isso por você.

Teste se mod_rewrite estiver habilitado

Se você tiver verificado que .htaccess funciona, você pode verificar se a extensão mod_rewrite está habilitada. Coloque a linha RewriteEngine On no início do arquivo .htaccess e atualize a página em seu navegador. Se você vir um erro Internal Server Error, significa que o mod_rewrite não está habilitado. Há várias maneiras de habilitá-lo. Veja Stack Overflow para várias maneiras de fazer isso em diferentes configurações.

Nette gera links com o mesmo protocolo que a página atual está usando. Assim, na página https://foo e vice-versa. Se você estiver atrás de um proxy reverso HTTPS (por exemplo, no Docker), então você precisa configurar um proxy em configuração para que a detecção do protocolo funcione corretamente.

Se você usa o Nginx como um proxy, você precisa ter um redirecionamento configurado desta forma:

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
}

Em seguida, você precisa especificar o proxy IP e, se aplicável, a faixa IP de sua rede local onde você administra a infra-estrutura:

http:
	proxy: IP-proxy/IP-range

Uso de caracteres { } em JavaScript

Os caracteres { and } são usados para escrever etiquetas Latte. Tudo (exceto espaço e aspas) seguindo o { character is considered a tag. If you need to print character { (freqüentemente em JavaScript), você pode colocar um espaço (ou outro caractere vazio) logo após {. Com isto você evita interpretá-lo como uma tag.

Se for necessário imprimir estes caracteres em uma situação em que eles seriam interpretados como uma tag, você pode utilizar tags especiais para imprimir estes caracteres – {l} para { and {r} para }.

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

Aviso Presenter::getContext() is deprecated

Nette é de longe a primeira estrutura PHP que mudou para injeção de dependência e levou os programadores a usá-la de forma consistente, a começar pelos apresentadores. Se um apresentador precisar de uma dependência, ele a solicitará. Em contraste, a forma como passamos todo o recipiente DI para uma classe e ele puxa as dependências diretamente dele é considerado um antipadrão (é chamado de localizador de serviços). Esta forma era usada em Nette 0.x antes do advento da injeção de dependência, e sua relíquia é o método Presenter::getContext(), há muito marcado como depreciado.

Se você portar uma aplicação Nette muito antiga, você pode descobrir que ela ainda usa este método. Portanto, desde a versão 3.1 de nette/application você encontrará o aviso Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection, desde a versão 4.0 você encontrará o erro de que o método não existe.

A solução limpa, naturalmente, é redesenhar a aplicação para passar dependências usando injeção de dependência. Como alternativa, você pode adicionar seu próprio método getContext() ao seu apresentador base e contornar a mensagem:

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;
	}
}
versão: 4.0