Solución de problemas
- Nette no funciona, se muestra una página en blanco
- Error 500 Server Error: We're sorry! …
- Error 404, el enrutamiento no funciona
- Los cambios en las plantillas o la configuración no se reflejan
- ¿Cómo desactivar la caché durante el desarrollo?
- Error #[\ReturnTypeWillChange] attribute should be used
- Configuración de permisos de directorio
- ¿Cómo cambiar o eliminar el directorio www de la URL?
- ¿Cómo configurar el servidor para URLs amigables?
- Verificación de que .htaccess funciona
- Verificación de que mod_rewrite está habilitado
- Los enlaces se generan sin https:
- Uso de los caracteres { } en JavaScript
- Mensaje Presenter::getContext() is deprecated
Nette no funciona, se muestra una página en blanco
- Intente insertar
ini_set('display_errors', '1'); error_reporting(E_ALL);
en el archivoindex.php
justo después dedeclare(strict_types=1);
, esto forzará la visualización de errores. - Si sigue viendo una pantalla en blanco, probablemente haya un error en la configuración del servidor y la razón se revelará
en el registro del servidor. Por si acaso, verifique si PHP funciona en absoluto intentando imprimir algo
usando
echo 'test';
- Si ve el error Server Error: We're sorry! …, continúe con la siguiente sección:
Error 500 Server Error: We're sorry! …
Esta página de error la muestra Nette en modo de producción. Si se le muestra en su computadora de desarrollo, cambie al modo de desarrollo y se le mostrará Tracy con un mensaje detallado.
La razón del error siempre se puede encontrar en el registro en el directorio log/
. Sin embargo, si el mensaje de
error muestra la frase Tracy is unable to log error
, primero averigüe por qué no se pueden registrar los errores.
Puede hacerlo, por ejemplo, cambiando temporalmente al modo de
desarrollo y dejando que Tracy registre cualquier cosa después de su inicio:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // su dirección IP
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy le dirá por qué no puede registrar. La causa puede ser un componente defectuoso, pero más probablemente permisos insuficientes para escribir en el directorio log/
.
Una de las razones más comunes del error 500 es una caché obsoleta. Mientras que Nette en modo de desarrollo actualiza
inteligentemente la caché automáticamente, en modo de producción se centra en maximizar el rendimiento y borrar la caché,
después de cada modificación del código, depende de usted. Intente borrar temp/cache
.
Error 404, el enrutamiento no funciona
Cuando todas las páginas (excepto la página de inicio) devuelven un error 404, parece un problema con la configuración del servidor para URLs amigables.
Los cambios en las plantillas o la configuración no se reflejan
“He modificado la plantilla o la configuración, pero el sitio web sigue mostrando la versión antigua.” Este comportamiento ocurre en el modo de producción, que por razones de rendimiento no verifica los cambios en los archivos y mantiene la caché generada una vez.
Para no tener que borrar manualmente la caché en el servidor de producción después de cada modificación, habilite el modo
de desarrollo para su dirección IP en el archivo Bootstrap.php
:
$this->configurator->setDebugMode('su.direccion.ip');
¿Cómo desactivar la caché durante el desarrollo?
Nette es inteligente y no necesita desactivar el almacenamiento en caché. Durante el desarrollo, actualiza automáticamente la caché cada vez que se cambia una plantilla o la configuración del contenedor DI. Además, el modo de desarrollo se activa por autodetección, por lo que generalmente no es necesario configurar nada, o solo la dirección IP.
Al depurar el router, recomendamos desactivar la caché en el navegador, donde pueden almacenarse, por ejemplo, redirecciones: abra las Herramientas de desarrollo (Ctrl+Shift+I o Cmd+Option+I) y en el panel Red (Network) marque la desactivación de la caché.
Error
#[\ReturnTypeWillChange] attribute should be used
Este error aparece si ha actualizado PHP a la versión 8.1, pero está utilizando una versión de Nette que no es compatible
con ella. La solución es, por lo tanto, actualizar Nette a una versión más reciente usando composer update
. Nette
es compatible con PHP 8.1 desde la versión 3.0. Si está utilizando una versión anterior (compruébelo en
composer.json
), actualice Nette o quédese con PHP 8.0.
Configuración de permisos de directorio
Si está desarrollando en macOS o Linux (o cualquier otro sistema basado en Unix), deberá configurar los permisos de
escritura para el servidor web. Supongamos que su aplicación se encuentra en el directorio predeterminado
/var/www/html
(Fedora, CentOS, RHEL).
cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log
En algunos sistemas Linux (Fedora, CentOS, …), SELinux está habilitado de forma predeterminada. Deberá ajustar las
políticas de SELinux en consecuencia y establecer el contexto de seguridad SELinux correcto para las carpetas temp
y
log
. Para temp
y log
estableceremos el tipo de contexto
httpd_sys_rw_content_t
, para el resto de la aplicación (y especialmente para la carpeta app
) será
suficiente httpd_sys_content_t
. Ejecute en el servidor:
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/
Además, es necesario habilitar el booleano de SELinux httpd_can_network_connect_db
, que está desactivado por
defecto y que permite a Nette conectarse a la base de datos a través de la red. Usaremos el comando setsebool
y con
la opción -P
haremos el cambio permanente, es decir, después de reiniciar el servidor no nos encontraremos con una
sorpresa desagradable:
setsebool -P httpd_can_network_connect_db on
¿Cómo cambiar o eliminar el directorio www
de
la URL?
El directorio www/
utilizado en los proyectos de ejemplo en Nette representa el llamado directorio público
o document-root del proyecto. Es el único directorio cuyo contenido es accesible para el navegador. Y contiene el archivo
index.php
, el punto de entrada que inicia la aplicación web escrita en Nette.
Para poner en funcionamiento la aplicación en un hosting, es necesario tener configurado correctamente el document-root. Tiene dos opciones:
- Establecer el document-root en este directorio en la configuración del hosting.
- Si el hosting tiene una carpeta predefinida (por ejemplo,
public_html
), renombrewww/
a este nombre.
Nunca intente resolver la seguridad solo con .htaccess
o el router, que impedirían el acceso a
otras carpetas.
Si el hosting no permitiera establecer el document-root en un subdirectorio (es decir, crear directorios un nivel por encima del directorio público), busque otro. De lo contrario, correría un riesgo de seguridad considerable. Sería como vivir en un apartamento donde la puerta de entrada no se puede cerrar y siempre está abierta.
¿Cómo configurar el servidor para URLs amigables?
Apache: es necesario habilitar y configurar las reglas de mod_rewrite en el archivo .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]
Si encuentra problemas, asegúrese de que:
- el archivo
.htaccess
se encuentra en el directorio document-root (es decir, junto al archivoindex.php
) - Apache procesa los archivos
.htaccess
- mod_rewrite está habilitado
Si está configurando la aplicación en una subcarpeta, es posible que deba descomentar la línea para configurar
RewriteBase
y establecerla en la carpeta correcta.
nginx: es necesario configurar la redirección usando la directiva try_files
dentro del bloque
location /
en la configuración del servidor.
location / {
try_files $uri $uri/ /index.php$is_args$args; # ¡$is_args$args ES IMPORTANTE!
}
El bloque location
para cada ruta del sistema de archivos solo puede aparecer una vez en el bloque
server
. Si ya tiene location /
en la configuración, agregue la directiva try_files
a él.
Verificación de que .htaccess
funciona
La forma más sencilla de probar si Apache usa o ignora su archivo .htaccess
es dañarlo intencionalmente.
Inserte la línea Test
al principio del archivo y ahora, si actualiza la página en el navegador, debería ver
Internal Server Error.
Si ve este error, ¡en realidad es bueno! Significa que Apache está analizando el archivo .htaccess
y encuentra
el error que insertamos allí. Elimine la línea Test
.
Si no aparece Internal Server Error, su configuración de Apache está ignorando el archivo .htaccess
.
Generalmente, Apache lo ignora debido a la falta de la directiva de configuración AllowOverride All
.
Si lo aloja usted mismo, se puede arreglar fácilmente. Abra el archivo httpd.conf
o apache.conf
en
un editor de texto, busque la sección <Directory>
correspondiente y agregue/cambie esta directiva:
<Directory "/var/www/htdocs"> # ruta a su document root
AllowOverride All
...
Si su sitio web está alojado en otro lugar, consulte el panel de control para ver si puede habilitar el archivo
.htaccess
allí. Si no, póngase en contacto con su proveedor de hosting para que lo haga por usted.
Verificación de que mod_rewrite
está habilitado
Si ha verificado que .htaccess
funciona, puede verificar si la
extensión mod_rewrite está habilitada. Inserte la línea RewriteEngine On
al principio del archivo
.htaccess
y actualice la página en el navegador. Si aparece Internal Server Error, significa que
mod_rewrite no está habilitado. Hay varias formas de habilitarlo. Puede encontrar diferentes formas de hacerlo en diversas
configuraciones en Stack Overflow.
Los enlaces se generan sin https:
Nette genera enlaces con el mismo protocolo que tiene la propia página. Es decir, en la página https://foo
genera enlaces que comienzan con https:
y viceversa. Si está detrás de un servidor proxy inverso que elimina HTTPS
(por ejemplo, en Docker), entonces es necesario configurar el
proxy en la configuración para que la detección del protocolo funcione correctamente.
Si utiliza Nginx como proxy, es necesario tener configurada la redirección, por ejemplo, así:
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-aplicacion:80; # IP o hostname del servidor/contenedor donde se ejecuta la aplicación
}
Además, es necesario indicar en la configuración la IP del proxy y, opcionalmente, el rango de IP de su red local donde opera la infraestructura:
http:
proxy: IP-proxy/IP-range
Uso de los caracteres { } en JavaScript
Los caracteres {
y }
se utilizan para escribir etiquetas Latte. Se considera una etiqueta cualquier
cosa que siga al carácter {
con la excepción de un espacio y una comilla. Por lo tanto, si necesita imprimir
directamente el carácter {
(a menudo, por ejemplo, en JavaScript), puede poner un espacio (u otro carácter en
blanco) después del carácter {
. De esta manera evitará la traducción como etiqueta.
Si es necesario imprimir estos caracteres en una situación en la que el texto se entendería como una etiqueta, puede utilizar
etiquetas especiales para imprimir estos caracteres: {l}
para {
y {r}
para
}
.
{es una etiqueta}
{ no es una etiqueta }
{l}no es una etiqueta{r}
Mensaje Presenter::getContext() is deprecated
Nette es, con mucho, el primer framework PHP que pasó a la inyección de dependencia y guió a los programadores a usarla
consistentemente, desde los propios presenters. Si un presenter necesita alguna dependencia, la solicita. Por el contrario, la forma en que
pasamos todo el contenedor DI a la clase, y esta extrae las dependencias directamente de él, se considera un antipatrón (se
llama localizador de servicios). Este método se usaba en Nette 0.x antes de la llegada de la inyección de dependencia y su
remanente es el método Presenter::getContext()
, marcado como obsoleto hace mucho tiempo.
Si está portando una aplicación muy antigua para Nette, puede que todavía use este método. Desde la versión 3.1 de
nette/application
se encontrará con la advertencia
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, desde la versión 4.0 con el
error de que el método no existe.
La solución limpia es, por supuesto, rediseñar la aplicación para que pase las dependencias usando la inyección de
dependencia. Como solución alternativa, puede agregar su propio método getContext()
a su presenter base y así
evitar el mensaje:
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;
}
}