Autor Zpráva
AAA
Profil *
Ahoj, potřebuju poradit, dělám experimenty s namespace a zatím mi to nějak nefunguje. Na internetu jsem toho o tomto tématu nenašel (v češtině), většinou je na všech webech skoro stejný příklad. Nemáte někdo odkaz na nějaký dobrý stránky o používání namespace?
Snažím se dědit dvě třídy v namespace a hlásí mi to, že třída neexistuje. Tady je kod:
soubor TridaA.php:
namespace Pokus{
  class TridaA{
    public function MetodaA()
    {
      return "Ahoj";
    }
  }
}

soubor TridaB.php
namespace Pokus{
  class TridaB extends TridaA // zkoušel jsem i Pokus/TridaA
  {
    public function MetodaB()
    {
      return $this->MetodaA()."Cau";
    }
  }
}

Děkuji za pomoc
Nox
Profil
No a je před načtením TridaB načten soubor TridaA?
AAA
Profil *
Jak načten? myslíš include? no to je snad zbytečný, když jsou ve stejným namespace ne?
Nox
Profil
Není, ten soubor musí být jednou načtený ... vždycky. Samozřejmě existují auto-loadery, ale ty právě zjednodušují to načítání
AAA
Profil *
Jak načtený? když dám před namespace v TridaA.php include "TridaB.php" tak to hlásí
Namespace declaration statement has to be the very first statement in the script in
Mike8748
Profil
soubor TridaA.php
<?php 
namespace Pokus;
class TridaA { 
public function MetodaA() 
{ 
  return "Ahoj";  
} 
}

soubor TridaB.php
<?php 
namespace Pokus;
include 'TridaA.php';
use TridaA;

class TridaB extends TridaA{
public function MetodaB() 
{
  return $this->MetodaA().', svete!';
}
}
edit: doplněny chybějící závorky
AAA
Profil *
Jo aha tak děkuji a jakou teda má namespace výhodu, když stejně musím includovat, myslel jsem že když je mám ve stejným jmeným prostoru, že jsou jako propojený.
Mike8748
Profil
AAA:
pokud ti vadí že musíš každý soubor ručne includovat, najdi si co je autoloading (http://cz2.php.net/autoload), google ti toho najde dost... (příkladem třeba RobotLoader z frameworku Nette)

smyslem namespace je hlavně zabránit kolizi pojmenování tříd ve větším projektu kde budeš pracovat nejenom se svým kódem. také to díky aliasům umožní zkrátit některé zápisy. přečti si třeba http://cz2.php.net/manual/en/language.namespaces.rationale.php
ShiraNai7
Profil
AAA:
Jsou "propojený" .. jsou ve stejném jmenném prostoru, ale tím to končí.
Výhody například:
• zamezení kolizím názvů tříd, funkcí, konstant, interfací, ... tj také odpadnutí nutnosti přidávat prefixy do názvů
• názvy tříd/interfací/trait mohou snadno kopírovat adresářovou strukturu (viz ten autoload)
AAA
Profil *
Ok, díky moc za rady
Ugo
Profil
je to tak jako se všemi těmi módními hračičkami, smysl žádný, když budeš použivat jako zend - nette_form_rule, tak je to to samé jako s namespace \nette\forms\rule , výhodou je, že při namespace není třeba psát vždy celý název, jinak nic .. nebo že by přecijen? samozřejmě výhodu to má, autoloading podle adresářů ani tak ne, to jde s podtržítkem taky, ale především pro mě je to něco co můžu spracovat svym robotem a následně na to vydupat metodu $loader->ns() a tím získat to co chceš ty, načíst všechny soubory namespace, ať jsou kdekoliv
Nox
Profil
Ugo:
Nechci ti bořit iluze, ale ta "modní hračička" je úspěšně používána přinejmenším 14 let...

Pak tu máme http://cz.php.net/manual/en/language.namespaces.importing.php

Při namespacích je nesrovnatelně lepší možnost napovídání

Jakmile jsi v namespacu samotném, odpadnou ti všechny prefixy (až na podnamespacy nebo namespacy tříd mimo), u prefixů musíš úplně vždy vypisovat celý název

Zend_Service_DeveloperGarden_Response_ConferenceCall_CreateConferenceResponseType ;) tohle fakt nechci v kódu nikde vidět

Prefix jsou jen "hack", jak docílit nějaké bezkoliznosti, ale nice hezkého
Ugo
Profil
Nox:
s tím vším samozřejmě souhlasím, s tou modernou jsem to myslel trochu jinak než že je to nová věc

to importování budu muset ještě pořádně prozkoumat, vím že mi nechtělo fungovat jak jsem očekával (jako v jinejch jazycích), ale to je jedno.
ten zend zápis je luxusní a jak znám zend, tka bude dělat následující return "("; :-D

prefixy jsou dobré dokud to má nějaký limit, když to z něj vyleze tak máme zend no, ale to platí o všem
Alphard
Profil
[#11] Ugo
Názor ti neberu, ale příště by bylo lepší formulovat ho tak, aby vyzněl jako tvůj subjektivní názor. Mysli na to, prosím.
AAA
Profil *
Mě ty namespace pořád nejsou moc jasný, takže to je fakt jenom kvůli názvům? programuju C# a tam je to lépe řešený a nemyslím si že to je jen kvůli dlouhým názvům. Tam stačí do projektu dát using Namespace a můžu krásně používat všechny třídy. To samé pokud jsem v jednom jmeném prostoru a mám to ve více souborech, nemusím používat include jako v php..
Nemáte někdo odkaz na nějaký rozumný článek o namespace? sice jsem už něco málo vygoogloval ale všude uvádění téměř totožný příklad a témeř stejný věty, takže z toho taky zrovna moc moudrý nejsem.
ShiraNai7
Profil
Jak fungujou "namespaces v C#" netuším. Určitě zapomeň všechny podobnosti a soustřeď se jen na to, jak se namespacy v PHP prakticky chovají. V PHP slouží pro seskupení tříd, konstant a funkcí bez použití nějakého prefixu (jak už to bylo zde určitě mnohokrát popsáno), pro importování tříd pod jiným názvem a tak dále. Jak je využiješ už záleží na tobě. Pokud je nepotřebuješ, používat je nemusíš.

S include namespace přímo nesouvisí. Pokud chceš, aby se ti definice tříd načítaly automaticky, napiš si autoloader.
AAA
Profil *
Ještě bych měl jednu a poslední prosbu, nenapsali byste mi jednoduchý příklad, jak používat třídy z jednoho namespace v jiném? nějak to nemůžu na netu najít, děkuji
ShiraNai7
Profil
AAA:
Pomocí výrazu use ideálně na začátku souboru. Viz manuál.
Příklad:

<?php

namespace Ahoj;

use Test\Trida; // importuje tridu Test\Trida takze ji lze pouzivat jen jako Trida
use Test\Priklad as Blabla; // importuje tridu Test\Priklad pod aliasem Blabla

Importovat je možné krom konkrétních tříd také samotné namespaces:

<?php

namespace Ahoj;

use Test\Moduly; // importuje namespace Test\Moduly, takze lze psat Moduly\Nejakymodul namisto plneho nazvu
AAA
Profil *
Já se omlouvám, že s tím zase otravuju, asi vám připadám natvrdle, ale zkouším teda udělat takový příklad používání metod z třídy v jednom namespace v třídě v jiném namespace. No a pořád mi to nějak nefunguje.
soubor Pokus.php:
namespace Test{
    class Pokus {
        public function Read()
        {
            return "Hello";
        }
    }
}

Pokus2.php
namespace Test\Test2{
    include "Pokus.php";
 use Test\Pokus;   
    class Pokus2 {
        public function Vypis()
        {
           return Pokus::Read()."world";
        }
    }
}
index.php
   include "Pokus2.php";
            $pokus = new \Test2\Pokus2;
            $pokus->Vypis();
Děkuji za trpělivost se mnou :)
Nox
Profil
a co znamená nefunguje? tady voláš staticky standardní metodu, ale jinak by to jet mělo
ShiraNai7
Profil
AAA:
1) index.php - chyby:
include "Pokus2.php";
$pokus = new \Test\Test2\Pokus2; // chybel kus namespace
echo $pokus->Vypis(); // nebylo echo tak by se nic nevypsalo

2) Pokus.php - pokud chces volat metodu Read staticky, mela by byt staticka:
<?php
namespace Test{
    class Pokus {
        static public function Read()
        {
            return "Hello";
        }
    }
}

Taky bych nepoužíval syntaxi namespace foo { ... } ale namespace foo; - první verze nepřináší žádný užitek, akorát to blbě vypadá. (V PHP tahle syntaxe je hlavně kvůli různým nástrojům, které mohou potřebovat definovat více tříd v různých namespace v 1 souboru).
AAA
Profil *
Tak na takovouhle syntaxi jsem zvyklý z C#, ale budu teda používat tu se středníkem. Jinak k tomu statickýmu, zkoušel jsem různý formy a nefungovalo ani jedno, vypisovalo mi to že ta třída Pokus neexistuje, jak tedy bude vypadat to volání metody Read() v Pokus2 nestaticky?
Farrell
Profil *
Musíš inicializovat třídu...
Tady máš funkční ukázku i s autoloadem


Pokus.php
namespace Test;

class Pokus
{
    public function Read()
    {
        return "Hello";
    }
}

Pokus2.php
namespace Test\Test2;

use Test\Pokus;  
 
class Pokus2
{
    public function Vypis()
    {
        $trida = new Pokus;
        return $trida->Read()." world";
    }
}

index.php
function __autoload($name)
{
    require_once(substr($name,strrpos($name,'\\')+1).".php");
}

$pokus = new Test\Test2\Pokus2;
echo $pokus->Vypis();  // tady jsi to měl bez echa, tudíž jsi returnoval do luftu a nic bys neviděl
Farrell
Profil
...a pozor na chyby "Namespace declaration statement has to be the very first statement in the script..." pokud jsou zjevně bezdůvodné, používám Dreamweaver a ten přidává na konec souboru signaturu BOM, vypnout lze Ctrl+J->Titul/kódování, ale musí se to provést u každého souboru :-x

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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