Решение проблем
- Nette не работает, отображается белая страница
- Ошибка 500 Ошибка сервера: We're sorry! …
- Ошибка 404, маршрутизация не работает
- Изменения в шаблонах или конфигурации не отражаются
- Как отключить кэш во время разработки?
- Ошибка #[\ReturnTypeWillChange] attribute should be used
- Установка прав доступа к каталогам
- Как изменить или удалить каталог www из URL?
- Как настроить сервер для красивых URL?
- Проверьте, работает ли .htaccess
- Проверьте, включен ли mod_rewrite
- Ссылки генерируются без https:.
- Использование символов { } в JavaScript
- Уведомление Presenter::getContext() is deprecated
Nette не работает, отображается белая страница
- Попробуйте поставить
ini_set('display_errors', '1'); error_reporting(E_ALL);
послеdeclare(strict_types=1);
в файлеindex.php
, чтобы заставить отображать ошибки. - Если вы по-прежнему видите белый экран, вероятно, в настройках
сервера произошла ошибка, и вы обнаружите причину в журнале сервера.
Чтобы убедиться в этом, проверьте, работает ли PHP вообще, попытавшись
напечатать что-нибудь с помощью команды
echo 'test';
. - Если вы увидите ошибку Server Error: We're sorry! …, переходите к следующему разделу:
Ошибка 500 Ошибка сервера: We're sorry! …
Эта страница ошибки отображается Nette в производственном режиме. Если вы видите ее на машине разработки, переключитесь в режим разработчика, и Tracy отобразится с подробным отчетом.
Причину ошибки всегда можно найти в каталоге log/
. Однако если в
сообщении об ошибке появляется фраза Tracy is unable to log error
, сначала
определите, почему ошибки не могут быть занесены в журнал. Это можно
сделать, например, временно переключившись в
режим разработчика и позволив Tracy регистрировать все, что угодно, после
его запуска:
// Bootstrap.php
$configurator->setDebugMode('23.75.345.200'); // ваш IP-адрес
$configurator->enableTracy($rootDir . '/log');
\Tracy\Debugger::log('hello');
Tracy сообщит, почему он не может вести журнал. Причина может
заключаться в недостаточных правах на
запись в каталог log/
.
Одной из наиболее распространенных причин возникновения ошибки
500 является устаревший кэш. Если в режиме разработки Nette автоматически
обновляет кэш, то в рабочем режиме он ориентирован на максимальную
производительность, и очистка кэша после каждой модификации кода
зависит от вас. Попробуйте удалить файл temp/cache
.
Ошибка 404, маршрутизация не работает
Когда все страницы (кроме домашней) выдают ошибку 404, это похоже на проблему конфигурации сервера для красивых URL.
Изменения в шаблонах или конфигурации не отражаются
“Я изменил шаблон или конфигурацию, но на сайте по-прежнему отображается старая версия”. Такое поведение наблюдается в производственном режиме, который по соображениям производительности не проверяет изменения файлов и сохраняет ранее созданный кэш.
Чтобы не очищать вручную кэш на рабочем сервере после каждой
модификации, включите режим разработки для вашего IP-адреса в файле
Bootstrap.php
:
$this->configurator->setDebugMode('your.ip.address');
Как отключить кэш во время разработки?
Nette – умный продукт, и отключать кэширование в нем не нужно. Во время разработки он автоматически обновляет кэш при каждом изменении шаблона или конфигурации DI-контейнера. Более того, режим разработки включается по автоопределению, поэтому обычно не требуется ничего настраивать, или только IP-адрес.
При отладке маршрутизатора рекомендуется отключить кэш браузера, в котором, например, могут храниться редиректы: откройте Developer Tools (Ctrl+Shift+I или Cmd+Option+I) и в панели Network установите флажок на отключение кэша.
Ошибка
#[\ReturnTypeWillChange] attribute should be used
Эта ошибка возникает, если вы обновили PHP до версии 8.1, но используете
Nette, который не совместим с ней. Поэтому решением является обновление
Nette до более новой версии с помощью composer update
. Nette поддерживает PHP
8.1 с версии 3.0. Если вы используете более старую версию (вы можете
узнать это, посмотрев в composer.json
), обновите Nette или оставайтесь с PHP 8.0.
Установка прав доступа к каталогам
Если вы разрабатываете на macOS или Linux (или любой другой системе на базе
Unix), вам необходимо настроить привилегии записи на веб-сервере.
Предположим, что ваше приложение расположено в каталоге по умолчанию
/var/www/html
(Fedora, CentOS, RHEL)
cd /var/www/html/MY_PROJECT
chmod -R a+rw temp log
В некоторых системах Linux (Fedora, CentOS, …) SELinux может быть включен по
умолчанию. Возможно, вам потребуется обновить политики SELinux или
установить пути к каталогам temp
и log
с правильным
контекстом безопасности SELinux. Каталоги temp
и log
должны
быть установлены в контекст httpd_sys_rw_content_t
; для остальной части
приложения — в основном папки app
— контекста httpd_sys_content_t
будет достаточно. Запустите на сервере перечисленные команды от
имени 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/
Далее необходимо включить булево SELinux httpd_can_network_connect_db
, чтобы
разрешить Nette подключаться к базе данных по сети. По умолчанию он
отключен. Для выполнения этой задачи можно использовать команду
setsebool
, и если указана опция -P
, эта настройка будет
сохраняться при всех перезагрузках.
setsebool -P httpd_can_network_connect_db on
Как изменить или удалить каталог
www
из URL?
Директория www/
, используемая в примерах проектов в Nette,
является так называемой публичной директорией или корнем проекта. Это
единственный каталог, содержимое которого доступно браузеру. В нем
находится файл index.php
– точка входа, с которой начинается
веб-приложение, написанное на Nette.
Чтобы запустить приложение на хостинге, необходимо в конфигурации
хостинга установить document-root в эту директорию. Или, если на хостинге
есть готовая папка для публичного каталога с другим именем (например,
web
, public_html
и т.д.), просто переименуйте www/
.
Решение не заключается в том, чтобы запретить доступ ко всем
папкам, кроме www/
, с помощью правил в файле .htaccess
или в
маршрутизаторе. Если ваш хостинг не позволяет устанавливать корень
документа в подкаталог (т. е. создавать каталоги на уровень выше
публичного каталога), вам следует поискать другой хостинг. В противном
случае вы подвергаете себя значительным рискам безопасности. Это все
равно что жить в квартире, где входная дверь не закрывается и всегда
нараспашку.
Как настроить сервер для красивых URL?
Apache: необходимо включить и установить правила mod_rewrite в файле
.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]
Если у вас возникли проблемы, убедитесь, что:
- файл
.htaccess
находится в каталоге document-root (т.е. рядом с файломindex.php
). - Apache обрабатывает файлы .htaccess
- включен mod_rewrite
Если вы устанавливаете приложение в подкаталоге, возможно, вам
придется откомментировать строку для параметра RewriteBase
и
установить его в правильную папку.
nginx: директива try_files
должна использоваться в конфигурации
сервера:
location / {
try_files $uri $uri/ /index.php$is_args$args; # $is_args$args ВАЖНО!
}
Блок location
должен быть определен ровно один раз для каждого
пути к файловой системе в блоке server
. Если в вашей конфигурации
уже есть блок location /
, добавьте директиву try_files
в
существующий блок.
Проверьте, работает ли .htaccess
Самый простой способ проверить, использует ли Apache или игнорирует ваш
файл .htaccess
, – это намеренно нарушить его. Поместите строку
Test
в начало файла и теперь, если вы обновите страницу в браузере,
вы должны увидеть Internal Server Error.
Если вы видите эту ошибку, это хорошо! Это означает, что Apache разбирает
файл .htaccess
и сталкивается с ошибкой, которую мы туда поместили.
Удалите строку Test
.
Если вы не видите Internal Server Error, значит, ваша установка Apache
игнорирует файл .htaccess
. Как правило, Apache игнорирует его из-за
отсутствия директивы конфигурации AllowOverride All
.
Если вы хоститесь сами, это достаточно легко исправить. Откройте ваш
httpd.conf
или apache.conf
в текстовом редакторе, найдите
соответствующий <Directory>
раздел и добавьте/измените
директиву:
<Directory "/var/www/htdocs"> # path to your document root
AllowOverride All
...
Если ваш сайт размещен на другом хостинге, проверьте в панели
управления, можете ли вы включить .htaccess
там. Если нет, обратитесь
к своему хостинг-провайдеру, чтобы он сделал это за вас.
Проверьте, включен ли mod_rewrite
Если вы убедились, что .htaccess
работает, вы можете проверить, включено ли расширение mod_rewrite.
Поместите строку RewriteEngine On
в начало файла .htaccess
и
обновите страницу в браузере. Если вы увидите Internal Server Error, это
означает, что mod_rewrite не включен. Есть несколько способов включить его.
Смотрите на Stack Overflow различные способы, которые можно использовать на
разных установках.
Ссылки генерируются без https:
.
Nette генерирует ссылки с тем же протоколом, который использует текущая
страница. Таким образом, на странице https://foo
генерируются ссылки,
начинающиеся с https:
и наоборот. Если вы находитесь за
HTTPS-стриминговым обратным прокси (например, в Docker), то вам нужно set up a proxy в конфигурации, чтобы
определение протокола работало правильно.
Если вы используете Nginx в качестве прокси, вам нужно настроить перенаправление следующим образом:
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 или имя хоста сервера/контейнера, на котором запущено приложение.
}
Далее необходимо указать IP прокси и, если применимо, IP диапазон вашей локальной сети, где вы запускаете инфраструктуру:
http:
proxy: IP-proxy/IP-range
Использование символов { } в JavaScript
Символы {
и }
используются для записи тегов Latte. Всё
(кроме пробела и кавычек), следующее за символом {
, считается
тегом. Если вам нужно вывести символ {
(часто встречается в
JavaScript), вы можете поставить пробел (или другой пустой символ) сразу
после {
. Таким образом вы избежите интерпретации его
как метки.
Если необходимо вывести эти символы в ситуации, когда они будут
интерпретированы как тег, вы можете использовать специальные теги для
вывода этих символов – {l}
для {
и {r}
для }
.
{is tag}
{ is not tag }
{l}is not tag{r}
Уведомление
Presenter::getContext() is deprecated
Nette, безусловно, первый PHP-фреймворк, который перешел на инъекцию
зависимостей и заставил программистов последовательно использовать
ее, начиная с ведущих. Если ведущему нужна зависимость, он попросит ее. В отличие от
этого, способ, при котором мы передаем весь DI-контейнер классу, а он
напрямую извлекает из него зависимости, считается антипаттерном (он
называется service locator). Этот способ использовался в Nette 0.x до появления
инъекции зависимостей, и его реликтом является метод
Presenter::getContext()
, давно помеченный как deprecated.
Если вы портируете очень старое приложение Nette, вы можете обнаружить,
что оно все еще использует этот метод. Таким образом, начиная с версии
3.1 nette/application
вы столкнетесь с предупреждением
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, начиная с версии
4.0 вы столкнетесь с ошибкой, что метод не существует.
Разумеется, чистым решением является перепроектирование приложения
для передачи зависимостей с помощью инъекции зависимостей. В качестве
обходного пути вы можете добавить свой собственный метод
getContext()
в базовый презентер и обойти сообщение:
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;
}
}