Solução de problemas
- Nette não está funcionando, página branca é exibida
- Error 500 Server Error: Pedimos desculpas! …
- Erro 404, roteamento não funciona
- As alterações nos modelos ou na configuração não são refletidas
- Como desativar o cache durante o desenvolvimento?
- Erro #[\ReturnTypeWillChange] attribute should be used
- Definição de permissões de diretório
- Como mudar ou remover www Diretório do URL?
- Como configurar um servidor para URLs legais?
- Teste se .htaccess está funcionando
- Teste se mod_rewrite estiver habilitado
- Os links são gerados sem https:
- Uso de caracteres { } em JavaScript
- Aviso Presenter::getContext() is deprecated
Nette não está funcionando, página branca é exibida
- Tente colocar
ini_set('display_errors', '1'); error_reporting(E_ALL);
depois dedeclare(strict_types=1);
no arquivoindex.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:
- o arquivo
.htaccess
está localizado no diretório document-root (ou seja, ao lado do arquivoindex.php
) - Apache está processando os arquivos .htaccess
- mod_rewrite está habilitado
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.
Os links são gerados sem https:
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;
}
}