Решение проблем
- Nette не работает, отображается белая страница
- Ошибка 500 Server Error: We're sorry! …
- Ошибка 404, не работает маршрутизация
- Изменения в шаблонах или конфигурации не отображаются
- Как отключить кеш во время разработки?
- Ошибка #[\ReturnTypeWillChange] attribute should be used
- Настройка прав доступа к каталогам
- Как изменить или удалить каталог www из URL?
- Как настроить сервер для красивых URL?
- Проверка работы .htaccess
- Проверка включения mod_rewrite
- Ссылки генерируются без https:
- Использование символов { } в JavaScript
- Сообщение Presenter::getContext() is deprecated
Nette не работает, отображается белая страница
- Попробуйте в файл
index.php
сразу послеdeclare(strict_types=1);
вставитьini_set('display_errors', '1'); error_reporting(E_ALL);
, это принудительно включит отображение ошибок. - Если вы по-прежнему видите белый экран, вероятно, проблема в
настройках сервера, и причину можно найти в логе сервера. На всякий
случай проверьте, работает ли вообще PHP, попробовав что-нибудь вывести
с помощью
echo 'test';
- Если вы видите ошибку Server Error: We're sorry! …, перейдите к следующему разделу:
Ошибка 500 Server Error: 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
:
$configurator->setDebugMode('ваш IP-адрес');
Как отключить кеш во время разработки?
Nette умный, и вам не нужно отключать в нем кеширование. Во время разработки он автоматически обновляет кеш при каждом изменении шаблона или конфигурации DI-контейнера. Режим разработки к тому же включается автоопределением, поэтому обычно не нужно ничего настраивать, или только IP-адрес.
При отладке маршрутизатора рекомендуем отключить кеш в браузере, в котором могут быть сохранены, например, перенаправления: откройте Инструменты разработчика (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 и
установить правильный контекст безопасности SELinux для папок temp
и
log
. Для temp
и log
установим тип контекста
httpd_sys_rw_content_t
, для остальной части приложения (и особенно для
папки app
) будет достаточно httpd_sys_content_t
. На сервере
выполните:
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,
представляет собой так называемый публичный каталог или document-root
проекта. Это единственный каталог, содержимое которого доступно
браузеру. И он содержит файл index.php
, входную точку, которая
запускает веб-приложение, написанное на Nette.
Для запуска приложения на хостинге необходимо правильно настроить document-root. У вас есть два варианта:
- В конфигурации хостинга установить document-root на этот каталог.
- Если у хостинга есть предустановленная папка (например,
public_html
), переименуйтеwww/
в это название.
Никогда не пытайтесь решать вопросы безопасности только с
помощью .htaccess
или маршрутизатора, которые бы запрещали доступ к
другим папкам.
Если хостинг не позволяет установить document-root в подкаталог (т.е. создавать каталоги на уровень выше публичного каталога), поищите другой. В противном случае вы подвергнетесь значительному риску безопасности. Это было бы как жить в квартире, где входная дверь не закрывается и всегда нараспашку.
Как настроить сервер для красивых 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 /
в конфигурации сервера.
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"> # путь к вашему document root
AllowOverride All
...
Если ваш сайт размещен в другом месте, посмотрите в панели
управления, можете ли вы там включить файл .htaccess
. Если нет,
обратитесь к своему хостинг-провайдеру, чтобы он сделал это за вас.
Проверка включения mod_rewrite
Если вы убедились, что работает
.htaccess
, вы можете проверить, включено ли расширение mod_rewrite.
Вставьте в начало файла .htaccess
строку RewriteEngine On
и обновите
страницу в браузере. Если отображается Internal Server Error, это означает,
что mod_rewrite не включен. Существует несколько способов его включить.
Различные способы, как это можно сделать в разных настройках, можно
найти на Stack Overflow.
Ссылки генерируются без https:
Nette генерирует ссылки с тем же протоколом, что и сама страница. То есть
на странице https://foo
генерирует ссылки, начинающиеся с https:
,
и наоборот. Если вы находитесь за обратным прокси-сервером, который
удаляет HTTPS (например, в Docker), то необходимо в конфигурации настроить прокси, чтобы
определение протокола работало правильно.
Если вы используете 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}
для }
.
{это тег}
{ это не тег }
{l}это не тег{r}
Сообщение
Presenter::getContext() is deprecated
Nette является, безусловно, первым PHP-фреймворком, который перешел на
внедрение зависимостей и побуждал программистов к его
последовательному использованию, начиная с самих презентеров. Если
презентеру нужна какая-то зависимость, он заявляет о ней. Напротив,
подход, когда в класс передается весь DI-контейнер, и он сам извлекает из
него зависимости, считается антипаттерном (называется service locator). Этот
способ использовался в Nette 0.x еще до появления внедрения зависимостей,
и его пережитком является метод Presenter::getContext()
, давно помеченный
как устаревший (deprecated).
Если вы портируете очень старое приложение для Nette, вы можете
столкнуться с тем, что оно все еще использует этот метод. Начиная с
версии nette/application
3.1, вы столкнетесь с предупреждением
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;
}
}