Kompatibilita Nette s PHP 7

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
d@rkWolf
Člen | 167
+
0
-

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
+
+3
-

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
+
0
-

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.

d@rkWolf
Člen | 167
+
0
-

Super, díky, vyzkouším jít prvně na 2.2.13 a pak uvidím. Jo, vím, že je doporučeno jít na novější, ale hrozně moc toho kleklo, když sem to zkusil poslat na 2.4.x.

David Grudl
Nette Core | 8227
+
+5
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.

CZechBoY
Člen | 3608
+
0
-

A ukládaj se ti vůbec ty sessiony? Nemáš vlastní session handler nebo nevoláš session_write_close, jiná práce se session?

Jan Tvrdík
Nette guru | 2595
+
+2
-

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
+
0
-

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
+
+1
-

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
+
-2
-

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
+
+1
-

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
+
+3
-

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..