Вирішення проблем
- 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
:
$this->configurator->setDebugMode('ваша.ip.адреса');
Як вимкнути кеш під час розробки?
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
та встановити правильний контекст безпеки 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-додатку:80; # IP або ім'я хоста сервера/контейнера, де працює додаток
}
Далі потрібно вказати в конфігурації IP-адресу проксі та, можливо, діапазон IP-адрес вашої локальної мережі, де ви керуєте інфраструктурою:
http:
proxy: IP-проксі/IP-діапазон
Використання символів { } у JavaScript
Символи {
та }
використовуються для запису тегів Latte.
Тегом вважається все, що йде за символом {
, за винятком пробілу
та лапок. Тому, якщо вам потрібно вивести безпосередньо символ {
(часто, наприклад, у JavaScript), ви можете поставити пробіл (або інший
порожній символ) після символу {
. Це дозволить уникнути його
інтерпретації як тегу.
Якщо необхідно вивести ці символи в ситуації, коли текст міг би бути
сприйнятий як тег, ви можете використовувати спеціальні теги для
виведення цих символів – {l}
для {
та {r}
для
}
.
{є тегом}
{ не є тегом }
{l}не є тегом{r}
Повідомлення
Presenter::getContext() is deprecated
Nette є першим PHP-фреймворком, який перейшов на dependency injection і спонукав
програмістів до його послідовного використання, починаючи з самих
presenter'ів. Якщо presenter'у потрібна якась залежність, він заявляє про неї. Навпаки,
підхід, коли в клас передається весь DI-контейнер, а клас сам витягує з
нього залежності, вважається антипатерном (називається service locator). Цей
спосіб використовувався в Nette 0.x ще до появи dependency injection, і його залишком
є метод Presenter::getContext()
, давно позначений як застарілий (deprecated).
Якщо ви портуєте дуже стару програму для Nette, ви можете зіткнутися з
тим, що вона все ще використовує цей метод. Починаючи з nette/application
версії 3.1, ви зіткнетеся з попередженням
Nette\Application\UI\Presenter::getContext() is deprecated, use dependency injection
, а з версії 4.0 – з
помилкою, що метод не існує.
Чистим рішенням, звичайно, є переробка програми таким чином, щоб
залежності передавалися за допомогою dependency injection. Як обхідний шлях, ви
можете додати власний метод getContext()
до свого базового presenter'а і
таким чином обійти повідомлення:
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;
}
}