Kompatibilita Nette s PHP 7
- d@rkWolf
- Člen | 167
Zdravím, od jaké verze je Nette kompatibilní s PHP 7? Mám projekt na Nette 2.2.7, který bude třeba upravit na PHP 7 a zkoumám, jestli je vhodnější pokusit se Composerem někam posunout verzi Nette případně dalších součástí(především kdyby/Doctrine), nebo se pokusit odstranit chyby ručně. S touhle verzí to při pokusu o spuštění padá na Tracy při vývoji a na provozu na doctrine/annotations.
Před nějakou dobou jsem zkoušel posunout to na nejnovější Nette 2.4 a to moc dobře nedopadlo kvůli tomu, že původní autor používal konstrukce, které byly deprecated už v 2.3 ne-li dřív a ve 2.4 jsou odstraněné. Pokud bych se ale mohl dostat do provozuschopného stavu s nějakou verzi 2.3.x, bylo by to akceptovatelné. Bohužel vše přepsat do aktuální podoby je teď časově úplně mimo. :-(
- Pavel Kravčík
- Člen | 1196
Migrace 2.2 → 2.3, 2.3 → 2.4.
Můžeš si vypnout zobrazování deprecated chyb, pokud to spěchá a vyřešit déle.
https://doc.nette.org/…tions/to-2-3
Editoval Pavel Kravčík (18. 5. 2017 15:19)
- Jan Tvrdík
- Nette guru | 2595
Pro kompatibilitu s PHP 7 by mělo stačit jenom aktualizovat na nejnovější setinkovou verzi Nette 2.2.x, což je rok stará 2.2.13.
Přejít následně na verzi 2.3.x a 2.4.x je nicméně důrazně doporučeno.
- David Grudl
- Nette Core | 8227
Nejnovější vydání Nette 2.3 a 2.4 jsou kompatibilní s PHP 7.1, Nette 2.1 a 2.2 s PHP 7.0.
- d@rkWolf
- Člen | 167
Po boji s composerem se mi nakonec podařilo aktualizovat na 2.2.13, pak vyhodit set_magic_quotes_runtime z Dibi, jenže pak jsem skončil na Doctrine entitě – Kdyby/Doctrine by mělo být podle v2.3.1
Kdyby\Doctrine\MemberAccessException
Cannot read an undeclared property App\StructurePizza::$Id.
Když to z šablony povyhazuju, dojdu to ke stejné chybě při generování proxy pro entitu:
Cannot read an undeclared property Kdyby\GeneratedProxy\__CG__\App\ContentTypeStructurePizza::$Id.
Nevím, jestli to způsobuje to php7, nebo je problém někde jinde, vyskakuje to při vykreslování menu v šabloně:
<?php
<li n:foreach="$mainMenu as $menuItem" n:class="$id == $menuItem->id ? active,isset($parentItem) && $parentItem->parent == $menuItem->id ? active"><a href="/{$menuItem->slug}">{$menuItem}</a></li>
?>
což se krmí z frontbasepresenteru:
<?php
$this->template->mainMenu = $this->structurePizzaRepository->menuChildren($this->context->parameters['langs'][$this->lang]['header']);
?>
A pokud si tady nechám vyflusnout obsah toho $this->template->mainMenu, shodí mi to Tracy nekonečným cyklem, místo aby to vrátilo cca 7 záznamů.
v repository
<?php
public function menuChildren($parent){
$qb = $this->structurePizza->createQueryBuilder('s');
return $qb->select('s')
->where('s.parent = :parent')
->setParameter('parent',$parent)
->andWhere('s.visible = :visible')
->setParameter('visible',1)
->orderBy('s.position','ASC')
->getQuery()
->getResult();
}
?>
A entita vypadá takto(začátek, je tam hodně položek)
<?php
namespace App;
use Doctrine\ORM\Mapping as ORM;
use Kdyby\Doctrine\Entities\BaseEntity;
/**
* @ORM\Entity
* @ORM\Table(name="structure")
*/
class StructurePizza extends BaseEntity
{
const FOLDER = "structure";
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/**
* @ORM\Column(type="integer")
*/
protected $parent;
/**
* @return mixed
*/
public function getParent()
{
return $this->parent;
}
/**
* @param mixed $parent
*/
public function setParent($parent)
{
$this->parent = $parent;
}
...
...
?>
Čumím na to už dlouho a buď něco evidentně přehlížím, nebo fakt nevím. Před tou aktualizací to každopádně fungovalo. Nevidíte někdo, co by tam mohlo být špatně?
- leninzprahy
- Člen | 150
Problém bych viděl někde v té BaseEntity
kde bude nějaká
magie (__get
) na čtení protected vlastností. Podle hlášek to
hledá App\StructurePizza::$Id
, ale ono se to zatím jmenuje
App\StructurePizza::$id
(jiná velikost písmen)
- d@rkWolf
- Člen | 167
Zrovna toto by mělo být v pořádku, viz. třeba tady v tutoriálu je to použito úplně stejně: https://blog.venca-x.cz/…-a-doctrine/
- d@rkWolf
- Člen | 167
Tak jsem systémem pokus omyl zjistil, že nekonečný cyklus při tahání dat z entity způsobují joiny:
<?php
/**
* @ORM\OneToOne(targetEntity="ContentTypeStructurePizza")
* @ORM\JoinColumn(name="type", referencedColumnName="id")
*/
protected $contentType;
/**
* @ORM\OneToOne(targetEntity="TextStructurePizza", mappedBy="structure")
**/
private $content;
/**
* @ORM\OneToMany(targetEntity="FileStructurePizza", mappedBy="structure")
* @ORM\OrderBy({"position" = "ASC"})
* @var FileStructurePizza[]ArrayCollection
**/
protected $files;
?>
Pokud je z entity vyhodím, z jedné tabulky mi to vytáhne správná data, netušíte někdo, jestli tohlo může být problém s PHP 7, nebo něco s aktualizací Nette? Zkoušel jsem procházet dokumentace a tutoriály a zápis těch anotací pro Doctrine mi přijde v pořádku mým Doctrine-laickým pohledem…
Update: v PHP problém není, když si hodím server zpět na 5.6.x chyba přetrvá, takže je problém v aktualizaci přes Composer update.
Editoval d@rkWolf (20. 5. 2017 20:33)
- d@rkWolf
- Člen | 167
Tak jsem pokusy s Nette 2.2.13 vzdal, podle mě je problém někde ve verzích Doctrine nebo nějakých jejích kompoment…
Revertnul jsem změny a zkusil jinou variantu, upgrade na 2.3.10, kde se mi systém po úpravě neonu, indexu a zapnutí di.accessors systém rozjel, ale zase sem skončil na jiné věci, kterou už nechápu vůbec.
Neustále se generují nové session-každým refreshem, tzn. ztrácí se přihlášení i cokoliv jiného, co se do nich hodí(zboží v košíku třeba), mám podezření na nějakej problém s konfigurací, ale v popisu migrace z 2.2 na 2.3 jsem nic takového nenašel.
Nesetkali jste se někdo s tímto problémem? Zkoušel jsem hledat na fóru, ale nenarazil jsem na nic, co by odpovídalo tomuhle problému. Mám dojem, že dost podobně se to chovalo když jsem dříve zkoušel aktualizaci na 2.4.x. Nikde se nelogují žádné chyby.
- Jan Tvrdík
- Nette guru | 2595
Tak jsem pokusy s Nette 2.2.13 vzdal, podle mě je problém někde ve verzích Doctrine
Proč aktualizuješ Nette i Dotrine zároveň? Zkus pro začátek
aktualizovat jenom Nette (tj. composer update nette/*
)
- d@rkWolf
- Člen | 167
CZechBoy: jo, ukládají se, konfiguraci mám takto:
<?php
session:
debugger: true
expiration: +7 days
savePath: "%tempDir%/sessions"
#cookie_secure: true
?>
a temp/sessions se plněj hromadou sessions, co refresh/klik neustále přibývají další
Jan Tvrdík: protože se mi nepodařilo donutit Composer jen Nette updatovat, furt řval, že mám špatnou verzi Nette/Tracy a nemohl sem přijít na to, jak to udělat, jediný, co fungovalo, bylo kompletní Composer update, dost s tím composerem bojuju, je to tam složený stylem, že jsou tam required dev-mastery, který samozřejmě šly přidat před těma 2 roky, teď to všecko vyháže chyby kompatibility. Každopádně s tou 2.3.10 i aktualizací Doctrine se ty entity zdají v pořádku, protože front-end webu se sestavuje v pohodě a tam se toho tahá hafo.
Editoval d@rkWolf (21. 5. 2017 15:47)
- d@rkWolf
- Člen | 167
Tak se ukázalo, že je třeba vyzkoušet známou hlášku „zkusil jste to vypnout a zapnout“, protože když jsem to zapnul další den, najednou to funguje, aniž bych cokoliv změnil.
Nicméně mám ještě jeden problém s konfigurací, zkusil jsem to poslat na server, abych to vyzkoušel a zjistil jsem, že mi server bere připojení(resp. všechny údaje, co jsou v obou config neonech) k DB z config.local.neon a netuším proč. Na localhostu jede vše v pohodě, žádná chyba, nevím, kde hledat, měl jsem za to, že to detekuje podle IP takže mi není jasný, proč by to mělo tahat z local.neonu.
Config mám takto(po úpravě na formát Nette 2.3.x):
<?php
parameters:
database:
host: ...active24.cz
database: nazevdb
user: nazevusera
password: heslo
lazy: TRUE
profiler: TRUE
doctrine:
host: %database.host%
user: %database.user%
password: %database.password%
dbname: %database.database%
metadata:
App: %appDir%/_classes
a z historických důvodů ještě
services:
database:
class: \DibiConnection(%database%)
?>
v local.neon není services:db…, jinak to samé, jen změna v přihlašovacích údajích k DB
v boostrapu:
<?php
$configurator = new Nette\Configurator;
//$configurator->setDebugMode(true);
if ($configurator->debugMode) {
$configurator->enableDebugger(dirname(__FILE__) . '/../log');
} else {
$configurator->enableDebugger(dirname(__FILE__) . '/../log', array('email...'));
}
$configurator->addConfig(__DIR__ . '/config/config.neon');
$configurator->addConfig(__DIR__ . '/config/config.local.neon');
?>
Prosím nenapadá někoho, kde může být problém?(vypnout a zapnout server nemůžu :D) Veškerou cache i staré sessions jsem po aktualizaci samozřejmě promazal. (Na vypnutí a zapnutí serveru nemám dostatečná oprávnění:D)
Editoval d@rkWolf (23. 5. 2017 13:14)
- d@rkWolf
- Člen | 167
Tak jsem to asi pochopil při pročítání tohodle – https://forum.nette.org/…-config-neon
Úplně špatný chování, já potřebuju, abych tam měl config.neon s globálním nastavením a připojením k DB na serveru a k tomu config.local.neon aby se načítal když to mám na localhostu.
- Jan Mikeš
- Člen | 771
To je spatny postup nicmene toho jde taky docilit. Proc jednoduse na serveru
nevytvoris taky config.local.neon
ktery by mel sve nastaveni.
Hodnoty budes mit v config.neon
a config.local.neon
ti je muze prepisovat:
if (file_exists(__DIR__ . '/config/config.local.neon')) {
$configurator->addConfig(__DIR__ . '/config/config.local.neon');
}
- leninzprahy
- Člen | 150
d@rkWolf napsal(a):
Tak jsem to asi pochopil při pročítání tohodle – https://forum.nette.org/…-config-neon
Úplně špatný chování, já potřebuju, abych tam měl config.neon s globálním nastavením a připojením k DB na serveru a k tomu config.local.neon aby se načítal když to mám na localhostu.
Myšlenka je taková, že v config.local.neon
je konfigurace pro
daný stroj. Prostě na localhostu máš jiný config.local.neon
než na produkci. Z toho důvodu by ani neměl být součástí
repositáře..