Autor Zpráva
Actimel
Profil
Ahojte, mám spíše takový dotaz kdy třídá nemůže dědit/být děděna protože se mi teď stalo, že chci podědit třídu ale vyskočí mi to fatal errorem - třída nenalezena (requirenutá je) a když si ji místo dědění zkusím nainstancovat v té třídě, která ji měla dědit, tak to funguje.

Vypadá to +/- takto

soubor A.php

namespace Main;
class A{
    public function __construct(){ echo 'A->__construct'; }
}

a soubor B.php

namespace Main;
class B extends \Main\A{
    /* když oddělám extends a takhle si to nainstancuju, vše funguje - ale já potřebuju dědit */
    public function __construct(){ $a = new \Main\A(); }

    public function something(){ echo 'B->something';}
}

//edit
případně je něco, co by mohlo třídě bránit v dědění?
Lamicz
Profil
Rozchoď si autoload, jinak se z těch require zachvíli zblázníš. Pokud jsi ve stejném namespace, nemusíš jej uvádět.
Actimel
Profil
Autoloader mám - zadám složku a naloaduje mi to všechny .php soubory - to problém není..
Jinak namespace tam mám pro přehlednost protože je to součást něčeho většího, kde namespaces používám - nicméně to problém není :/ (neměl by být)

Jinak ten modelový příklad funguje ale vpodstatě stejně to tu mám v tom větším projektu, kde mi tohle nejde (je to asi černá magie, že všdy modelové příklady fungují) - takže spíš mě zajímá jestli někdy třída nemůže být děděná/dědit
Joker
Profil
Actimel:
Autoloader mám - zadám složku a naloaduje mi to všechny .php soubory - to problém není
Lamicz myslel něco jiného, a sice načtení příslušného souboru ve chvíli použití dosud nedefinované třídy. Viz odkaz.
Actimel
Profil
Joker:
Aha, o tom jsem ani nevěděl, každopádně ta funkce vypadá hezky, vědět o ní o 3 dny dřív nemusel bych dělat autoloader :D

Nicméně soubory jsou načtený i tak...
Actimel
Profil
No ještě to tu vyzdvihnu, třeba někdo poradí ohledně mé anomálie...

Zkusil jsem do souboru před definici třídy (třída Bootstrap, která měla dědit jinou třídu) requirnout zvlášť to, co to má dědit a najednou to fungovalo, přitom už před instancí Bootstrapu byly autoloaderem requirnutý všechny .php soubory. V indexu mám tady toto
$loader->load( $load, $except ); //Requirne soubory
$app = new \Singular\Bootstrap(); //instance Bootstrapu

podle toho erroru to vypadá jako by se ta instance spouštěla dřív než loader (což by měla být blbost)

moje otázka tedy na závěr -» Neví někdo jakto, že Bootstrap nemohl najít třídu, když mu loader před instancí všechno načetl?
Tori
Profil
Actimel:
Možná se tím Bootstrapem includují ve špatném pořadí (tzn. nejdřív potomek, až potom rodič). Zkuste si logovat (do souboru) názvy includovaných tříd.
Actimel
Profil
Tori:
Tyjo.. to by mě nenapadalo, že záleží na pořadí v jakým to bylo naloadovaný, když ho potřebuje a v době vytváření instance, kde už načetlej byl.
Díky, teď už vím s čím počítat...
Tori
Profil
Actimel:
v době vytváření instance, kde už načetlej byl
Tak tady už ne, samozřejmě. Myslela jsem tenhle případ:
include 'B.php'; // class B extends A
$obj = new B;
include 'A.php'; // class A
, ale to jste vlastně psal, že nenastane. Omlouvám se, špatně jsem si přečetla dotaz.
Actimel
Profil
no původně jsem to pochopil tak, že děděná třída má být načtená dřív než ta, co dědí - což mi přišlo jako blbost, nicméně když jsem nejdřív načetl rodiče a až potom tu třídu, tak to šlo
require 'A.php' //class A
require 'B.php' //class B extends A

$obj = new B;
//funguje
require 'B.php' //class B extends A
require 'A.php' //class A

$obj = new B;
//tohle už ne
Tori
Profil
Actimel:
No tak to je zajímavé! A tentýž případ bez require pro změnu funguje:
class B extends A {} 
class A {}

$obj = new B; // funguje
V manuálu se sice píše „Unless autoloading is used, then classes must be defined before they are used. If a class extends another, then the parent class must be declared before the child class structure. This rule applies to classes that inherit other classes and interfaces.“, ale tenhle rozdíl mezi require a tímtéž souborem nechápu. Nevíte někdo, proč se PHP v obdobné situaci chová různě?
Actimel
Profil
no sranda je v tom, že na php.net se píše že pořadí definování tříd je důležitý, ale když nadefinuju v jednom souboru nejdřív potomka a pak rodiče, tak to funguje
class B extends A{}
class A{}

$obj = new B(); //funguje

problém začne až když chci vložit rodiče ze souboru po té, co byl potomek definován

class B extends A{}
require 'ClassA.php';

$obj = new B(); //nefunguje

když requirnu potomka a až potom nadefinuji rodiče, tak to funguje

require 'ClassB.php'; // class B extends A
class A{}

$obj = new B; //funguje

Tori:
Nevíte někdo, proč se PHP v obdobné situaci chová různě?
Tohle by mě taky zajímalo, ale stejně to nic nezmění na tom, že to takhle nefunguje (pokud se nenajde jiná finta, než to loadovat ve správným pořadí) :/

Vaše odpověď

Mohlo by se hodit

Odkud se sem odkazuje


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: