Chyba Tracy Creation of dynamic property Tracy\DefaultBarPanel::$cpuUsage is deprecated při update na 2.4
- milanb
- Člen | 64
Ahoj,
snažím se o update Nette z 2.3 na 2.4, jak je popsáno zde: https://doc.nette.org/…tions/to-2-4.
PHP mám 8.2.4.
Updavil jsem toto v composer.json
:
"php": ">= 5.6",
"nette/application": "2.4.*",
"nette/bootstrap": "2.4.*",
"nette/caching": "2.5.*",
"nette/database": "2.4.*",
"nette/di": "2.4.*",
"nette/forms": "2.4.*",
"nette/http": "2.4.*",
"nette/security": "2.4.*",
"nette/finder": "2.4.*",
"nette/mail": "2.4.*",
"nette/robot-loader": "2.4.*",
"nette/safe-stream": "2.4.*",
"nette/utils": "2.4.*",
"latte/latte": "2.4.*",
"tracy/tracy": "2.4.*",
Jiné změny jsmem nedělal.
Pak jsem spustil composer update -W --prefer-stable --prefer-dist
:
nejdřív –dry-run a pak opravdu.
No a pak jsem spustil aplikaci a Tracy mě vypsal stack s chybou:
Creation of dynamic property Tracy\DefaultBarPanel::$cpuUsage is deprecated
Zdrojem je řádek v bootstrap.php
:
$configurator->enableDebugger(__APPDIR__ . '/log');
A nechápu, proč chybu způsobuje řádek 483 v Debugger.php
:
$info->cpuUsage = self::$cpuUsage;
,
když jde o volání mězi třídami uvnitř knihovny Tracy.
Díky za pomoc.
Editoval milanb (1. 3. 20:47)
- milanb
- Člen | 64
Tak jsem udělal downgrade PHP na 8.0.30 a už ta chyba není, ale zase je
jiná:
Ambiguous class Notes resolution; defined in D:\TEMP\_0repos\magnusys\app/..\vendor\nette\component-model\tests\bootstrap.php and in D:\TEMP\_0repos\magnusys\app/..\vendor\nette\di\tests\bootstrap.php.
Způsobuje ji řádek v bootstrap.php
:
$configurator->createRobotLoader()->addDirectory(__APPDIR__)->register();
Jinak jsem zatím v aplikaci nic neměnil, podle návodu na update na 2.4 jsem
nenašel nic, co bych v kódu měl ručně měnit.
Začínám se ztrácet…
Editoval milanb (1. 3. 21:47)
- Marek Bartoš
- Nette Blogger | 1177
Zajímavé, že ti to do teď fungovalo. Robot loader by měl načítat jenom tvé složky, ne vendor.
- milanb
- Člen | 64
Taky mězarzilo, že v tom výpisu chyby je cesta do vendor
a
tests/bootstrap.php
. Ale fungovalo to. Chci jen udělat update
Nette na co možná nejvyšší verzi a dělám to postupně dle návodu.
Jediné, co jsem udělal, je vše v tomto vlákně pospané, a to je pouze
změna composer.json
a pak composer update
. Ani ťuk
víc.
Můžu klidně poslat celý log té chyby.
Editoval milanb (2. 3. 9:16)
- Marek Bartoš
- Nette Blogger | 1177
Ne všechno je v upgrade guides. Dobře napsané aplikace se podle nich a deprecation notices aktualizovat dají, ale s aplikacemi sahající na (nezdokumentované) internals a obecně dělající nestandardní věci narazí na problémy.
Že robotloader načítá vendor má ale jednoduchou příčinu – museli jste si ho tam sami přidat. Sám vendor nenačítá. Nejspíš tedy konstanta __APPDIR__ neukazuje na složku /app, ale /.
Co se týče chyby popsané v úvodu – Nette 2.4 je kompatibilní
s maximálně PHP 8.0, viz https://nette.org/en/maintenance
Chyba se ukazuje uvnitř knihovny jednoduše proto, že používala něco, co
už v novějším PHP nefunguje.
- milanb
- Člen | 64
Tak další malý posun: Změnil jsem všechny dotčené verze na 2.4.* a
spustil update roučně pro všechny tyto komponenty a na nich závislé:
composer update nette/mail nette/security nette/caching nette/database nette/finder nette/forms nette/http nette/utils nette/robot-loader nette/application nette/bootstrap nette/caching nette/di tracy/tracy latte/latte -W
A objevila se jiná chyba:
Cannot use 'Object' as class name as it is reserved
A to už vůbec nechápu, protože v návodu update je uvedeno právě
tohle:
Třídy frameworku teď místo dědění od Nette\Object používají
novou traitu Nette\SmartObject
Tak proč v knihovně nette/utils v2.4.* je použito pořád Nette\Object?
- milanb
- Člen | 64
Marek Bartoš napsal(a):
Ne všechno je v upgrade guides. Dobře napsané aplikace se podle nich a deprecation notices aktualizovat dají, ale s aplikacemi sahající na (nezdokumentované) internals a obecně dělající nestandardní věci narazí na problémy.
Že robotloader načítá vendor má ale jednoduchou příčinu – museli jste si ho tam sami přidat. Sám vendor nenačítá. Nejspíš tedy konstanta __APPDIR__ neukazuje na složku /app, ale /.
Co se týče chyby popsané v úvodu – Nette 2.4 je kompatibilní s maximálně PHP 8.0, viz https://nette.org/en/maintenance
Chyba se ukazuje uvnitř knihovny jednoduše proto, že používala něco, co už v novějším PHP nefunguje.
Díky, to s PHP jsem pochopil a vrátil se na 8.0.30. To s __APPDIR__ je
zavádějící, protože jeho hodnota je skutečně root celé aplikace, ale to
fungovalo již s verzí Nette 2.3. Přesto ale můžu zkusit řádek změnit
na:
$configurator->createRobotLoader()->addDirectory(__APPDIR__ . '/app')->register();
Ale jek píšu v předhozím komentáři, teď už ten problém nevidím, mám problém s Nette\Object v Nette\Utils 2.4.*…
- Marek Bartoš
- Nette Blogger | 1177
Vyžaduj v Composeru verze ^2.4.0
, dovolí to cokoli od 2.4.0,
nižší než 3.0.0. Například nette/utils mají 2.5.* verze.
- milanb
- Člen | 64
Tak teď už bojuju jen z aplikací. Ta samozřejmě fungovala, ale
s verzí Nette 2.5 se dějí věci…
Mám HomepagePresenter
, který začíná takto:
class HomepagePresenter extends Nette\Application\UI\Presenter
{
use BasePresenter;
...
BasePresenter
začíná takto:
public function startUp()
{
parent::startUp();
if (!defined('self::LOGIN_NOT_REQUIRED') && !$this->user->isLoggedIn()) {
$this->redirect('Login:default');
return;
} else {
...
Ta podmínka zjednodušeně říká, že když nejsem přihlášen,
přesměruj na Login.
LoginPresenter
vypadá takto:
class LoginPresenter extends Nette\Application\UI\Presenter
{
use BasePresenter;
use \App\Control\LoginControl;
const LOGIN_NOT_REQUIRED = TRUE;
public function actionDefault() { $this->user->logout(); }
public function renderDefault() { }
}
A LoginControl
vyrábí login formulář. Ale k tomu to nikdy
nedojde, protože dojde k zacyklení. V adrese prohlížeče to skončí
tímto:
http://localhost:59029/login/login/login/login/login/login/login/login/login...
až dojde k chybě Smyčka při přesměrování.
Čím to je? A proč se v adrese vrší ty loginy za sebou?
Neměl bych v takových situacích použít radši jen
$this->forward('Login:default');
, když nepřesměrovávám na
jinou adresu a stále zůstávám v aplikaci?
Děkuji.
Editoval milanb (2. 3. 13:14)
- David Grudl
- Nette Core | 8152
@milanb zkus mi nějak polopaticky vysvětlit, co znamená to
self
v defined('self::LOGIN_NOT_REQUIRED')
a proč?
- milanb
- Člen | 64
OK. V LoginPresenter
určuje hodnota
LOGIN_NOT_REQUIRED
, jestli je požadováno, aby byl člověk pro
danou stránku (presenter) vyžadován. A není vyžadován u registračního
presenteru, kde si uživatel teprve účet vytváří, a u login presenteru,
kde je login dialog, takže ještě přihlášen není. Všechny ostatní
stránky (presentery) potřebují, aby byl user zalogován.
self::
je kvalifikátor sebe sama (třídy). Odkazujete se na
konstantu nebo statickou proměnnou definovanou ve stejné třídě. Klíčové
slovo self se používá k přístupu k statickým členům třídy (statické
proměnné, konstanty a metody) zevnitř třídy.
A protože je ta konstanta definována v LoginPresenter
, který
využívá i metody BasePresenter
a v tom se také provádí ten
test, tak nemusí být konstanta definována (když BasePresenter
je užit v jiné třídě, než LoginPresenter
, takže tam
konstanta nedude), proto:
if (!defined('self::LOGIN_NOT_REQUIRED')
.
P.S. Já ten kód sdědil, nepsal bych to tak, použil bych normální
dědění, a ne use BasePresenter
.
Editoval milanb (2. 3. 15:38)
- David Grudl
- Nette Core | 8152
Mě zaráží, že globální funkce defined()
si má poradit se
self… Nečekal bych, že to vůbec bude fungovat, a jestli jo, mohlo se to
i změnit mezi verzemi PHP, tak bych to asi prověřil.
- milanb
- Člen | 64
Udělal jsem z toho protected proměnnou, ale to nijak nepomoho. Pořád se ten redirect nějak správně neprovede, protože se z toho BasePresenteru nedokážu dostat dál, ani HomePagePresenter, natož LoginPresenter se nedostanou ani do konstruktoru. Chyba je v celé logice a taky to přesměrování nechápu, this je vždy HomePresenter, i kdyžjsempřesměrovsl do Login…
Editoval milanb (2. 3. 17:43)
- milanb
- Člen | 64
Tak nově se zdá být chyba někde tady při konstrukci formu:
$form->addSubmit('login', $l->login)->getControlPrototype()->setClass('btn btn-primary');
To způsobí, že ve vygenerováném form je
<form action="/login/" method="post" id="frm-loginForm">
a to
vůbec nezpůsobí volání
localhost/login
, ale jen ‚/‘ a pak přidá další
action="/login/login/"
atd. další…
Když to v inspektoru ručně upravím na action="/login"
, tak se
dostanu až do submit metody successLoginForm
.
Editoval milanb (2. 3. 18:10)
- David Grudl
- Nette Core | 8152
Že to dělá /login/login/login
nejspíš značí, že se
špatně detekuje base-path. Nedokážu takhle z hlavy poradit co z tím, jen
přemýšlím nahlas.
- m.brecher
- Generous Backer | 765
@milanb
Zkus natvrdo vyloučit redirect z LoginPresenter-u:
místo:
if (!defined('self::LOGIN_NOT_REQUIRED') && !$this->user->isLoggedIn()) {
$this->redirect('Login:default');
}
zkus:
if ($this->name !== 'Login' && !defined('self::LOGIN_NOT_REQUIRED') && !$this->user->isLoggedIn()) {
$this->redirect('Login:default');
}
- milanb
- Člen | 64
David Grudl napsal(a):
Že to dělá
/login/login/login
nejspíš značí, že se špatně detekuje base-path. Nedokážu takhle z hlavy poradit co z tím, jen přemýšlím nahlas.
Asi to tak nějak bude, protože další problém, o kterém jsem zatím
nepsal, je neschopnost načíst cokoliv z <site-root>/www
,
ani CSS, JS, nic. Použité jsou např. takto v šabloně:
¨<link rel="stylesheet" href="{$basePath}/www/less/magnus.css">
.
Jak se basePath
naplní, kdy a kde? Jen dodám, že Apache alias je
nasměrován rovnou do <site-root>/www
, kde načte
index.php
atd.
.htaccess
mám zkopírovaný ze vzorového projektu
nette/web-project
, takže to by mělo být dobře. Přesto ani
přímý přístup k nějakému zdroji nelze načíst, i když ho dám do
adresy prohlížeče, např.
http://localhost:51173/css/less/magnus.css
nebo když na zkoušku
umístím do <site-root>/www
soubory index.html
tak ani http://localhost:51173/index.html
neprojde. Oboje skončí
stejou chybou zobrazenou v Tracy:
Cannot load presenter 'Magnus:Css', class 'App\MagnusModule\Presenters\CssPresenter' was not found.
.
Je nakonec to <site-root>/www/.htaccess
špatně?
Tady je:
Require all granted
# Disable directory listing for security reasons
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
# Enable pretty URLs (removing the need for "index.php" in the URL)
<IfModule mod_rewrite.c>
RewriteEngine On
# Uncomment the next line if you want to set the base URL for rewrites
# RewriteBase /
# Force usage of HTTPS (secure connection). Uncomment if you have SSL setup.
# RewriteCond %{HTTPS} !on
# RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Permit requests to the '.well-known' directory (used for SSL verification and more)
RewriteRule ^\.well-known/.* - [L]
# Block access to hidden files (starting with a dot) and URLs resembling WordPress admin paths
RewriteRule /\.|^\.|^wp- - [F]
# Return 404 for missing files with specific extensions (images, scripts, styles, archives)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \.(pdf|js|mjs|ico|gif|jpg|jpeg|png|webp|avif|svg|css|rar|zip|7z|tar\.gz|map|eot|ttf|otf|woff|woff2)$ - [L]
# Front controller pattern - all requests are routed through index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
# Enable gzip compression for text files
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json application/xml application/rss+xml image/svg+xml
</IfModule>
Díky moc.
Editoval milanb (3. 3. 11:23)
- nightfish
- Člen | 474
@milanb
Píšeš, že Apache je nasměrovaný do <site-root>/www
, a
zároveň že se např. na styly odkazuje přes
{$basePath}/www/less/magnus.css
. Pokud by opravdu platila ta první
část, tak odkaz musí být {$basePath}/less/magnus.css
.
- Nemáš náhodou v
<site-root>
ještě jeden.htaccess
, který by dělal nějaké přesměrovávání/přepisování/podstrkávání do adresářewww
? - Co se stane, když v
<site-root>/www/.htaccess
odkomentuješRewriteBase /
a změníš to naRewriteBase /www/
? (I kdyby to zafungovalo, tak chceš mít spíš správně nastavený Apache než používat tuto berličku…).
- milanb
- Člen | 64
m.brecher napsal(a):
@milanb
Zkus natvrdo vyloučit redirect z LoginPresenter-u:
místo:
if (!defined('self::LOGIN_NOT_REQUIRED') && !$this->user->isLoggedIn()) { $this->redirect('Login:default'); }
zkus:
if ($this->name !== 'Login' && !defined('self::LOGIN_NOT_REQUIRED') && !$this->user->isLoggedIn()) { $this->redirect('Login:default'); }
Ta část s if ($this->name !== 'Login'
by mohla fungovat,
ale problém je, že submit togo login okna vede na
localhost/login/
, tzn. i s tím lomítkem na konci, což asi
.htaccess nějak vyhodnotí tak, že opět zavolá root /
⇒
HomePreseneter
. Problém už začítán tam, že v budování
formu příkaz $form->addSubmit('login', $l->login)
způsobí, že ve vygenerováném form je
<form action="/login/" method="post"
, tzn.i s tím lomítkem
na konci.A to netuším, proč…?
- milanb
- Člen | 64
nightfish napsal(a):
@milanb
Píšeš, že Apache je nasměrovaný do<site-root>/www
, a zároveň že se např. na styly odkazuje přes{$basePath}/www/less/magnus.css
. Pokud by opravdu platila ta první část, tak odkaz musí být{$basePath}/less/magnus.css
.
- Nemáš náhodou v
<site-root>
ještě jeden.htaccess
, který by dělal nějaké přesměrovávání/přepisování/podstrkávání do adresářewww
?- Co se stane, když v
<site-root>/www/.htaccess
odkomentuješRewriteBase /
a změníš to naRewriteBase /www/
? (I kdyby to zafungovalo, tak chceš mít spíš správně nastavený Apache než používat tuto berličku…).
Rozumím, díky za snahu, ale to vede stále na stejný výsledek – error
v Tracy:
Cannot load presenter 'Magnus:Css', class 'App\MagnusModule\Presenters\CssPresenter' was not found.
Teda když to zkouším takto:
http://localhost:51671/less/magnus.css
.
Ale ani změna v šabloně Latte nepomohla a všude, kde je použito
{$basePath}/www/...
, změna na {$basePath}/...
taky ne.
ad. 1) V <site-root>
mám ještě jeden
.htaccess
, ale ten obsahuje jen Require all denied
dle
vzoru v nette/web-project
.
ad. 2) A když jsem odkomentoval RewriteBase /
a změnil to na
RewriteBase /www/
, tak to nepomohlo.
Editoval milanb (3. 3. 11:45)
- nightfish
- Člen | 474
milanb napsal(a):
Rozumím, díky za snahu, ale to vede stále na stejný výsledek – error v Tracy:Cannot load presenter 'Magnus:Css', class 'App\MagnusModule\Presenters\CssPresenter' was not found.
Teda když to zkouším takto:http://localhost:51671/less/magnus.css
.
A soubor <site-root>/www/less/magnum.css
existuje a je
přístupný Apachi? Protože podle pravidel, nastavených ve
www/.htaccess
, se všechny existující (CSS) soubory buď
napřímo zobrazují, nebo se pro ně vrací (Apache) chybová stránka, takže
k předání zpracování do index.php
by vůbec nemělo dojít (a
tedy by se ti pro CSS soubor neměla zobrazit Tracy).
Takže tímto směrem bych se ubíral. Asi by se hodilo zkontrolovat access_log a error_log Apache, jestli tam nenarazíš na něco zajímavého.
- milanb
- Člen | 64
OMG, tak chyba nenačítání těch CSS a JS úplně někde jinde a sice
v lauch.json skriptu pro soupštění v prostředí VS Code.Když to spustím
ručně pomocí php -S localhost:8000 -t ./www
tak se načtou.
Omouvám se, že jsem s tímto zdržoval.
Teď jdu zjistit, co všech shora až sem se tím spravilo…
- milanb
- Člen | 64
Jestli můžu někomu prospět, kdo taky používá VS Code, tak správný
launch.json
vypadá takto:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Built-in web server",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-dxdebug.mode=debug",
"-dxdebug.start_with_request=yes",
"-S",
"localhost:5001"
],
"cwd": "${workspaceRoot}/www/",
"serverReadyAction": {
"pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
}
}
]
}
Port si samozřejmě lze změnit dle libosti. A stiskem F5 se spustí
aplikace s debuggerem a otevře se okno prohlížeče s aplikací.
Ještě jednou děkuji a prosím, můžete toto vlákno zavřít, jestli se to
tu vlastně vůbec tak nějak dělá.
- Marek Bartoš
- Nette Blogger | 1177
Nevím, zda už tě to trklo, tak just in case – php built-in webserver je alternativa k Apache určená pro lokální vývoj. Takže žádná úprava .htaccess se ti nemohla projevit, nepoužívá se.
- Marek Bartoš
- Nette Blogger | 1177
index.php je výchozí umístění. Když nenajde soubor ve www, tak se request nasměruje na něj.
Raději si nastav stejný webserver, který máš na serveru i pro lokální vývoj, aby se ti to chovalo stejně.