| Autor | Zpráva | ||
|---|---|---|---|
| Jankosar Profil |
#1 · Zasláno: 31. 5. 2010, 14:16:12
Dobrý den,
mám jistý problém v mém PHP kódu. Nejsem si zcela jistý, v čem spočívá, ale protože se problém táhne přes asi 2000 řádků v několika souborech, pokusím se uvést pouze ty části, kterých se to pravděpodobně dotýká. Mám vytvořenou třídu pro tvorbu HTML hlavičky. Funguje jednoduše: vytvořím si objekt této třídy, nastavím mu všechny parametry a pak mi funkce Head::vytvor() vrátí HTML kód celé hlavičky. Takhle vypadá začátek třídy: <?php
class Head
{
//definice proměnných
private $title;
private $description;
private $author;
private $encoding;
private $keyword;
private $css;
private $js;
//konstruktor
function __construct()
{
;
}
//set-funkce
function set_title($title)
{
$this->title=$title;
}
function set_description($description)
{
$this->description=$description;
}
atd............................ tuto třídu mám celou definovanou v souboru head.php. V souboru index.php pak deklaruji objekt této třídy takto:
include('head/head.php');
$head=new Head();
Tento objekt $head potom použivám jednak v souboru index.php a pak v dalších souborech includovaných do index.php, což funguje poměrně bez problémů. Potíže ale nastanou ve chvíli, kdy se pokouším k tomuto objektu přistupovat z nějaké funkce. Příklad (soubor lsloupec.php includovaný do index.php): Tohle funguje skvěle:
$head->set_title('tralala');
function lsloupec()
{
$return='';
//----------Články------------//
$menu_clanky=new Menu('Články');
{
$menu_clanky->add_polozky('O rase','o_rase','');
$menu_clanky->add_polozky('Rozhovory','clanky','rozhovory');
$menu_clanky->add_polozky('Rady nováčkům','clanky','rady_novackum');
$menu_clanky->add_polozky('Herní principy','clanky','herni_principy');
}
$return.=$menu_clanky->vytvor();
$return.='<br><br>';
Kdežto tohle vyhazuje chybu:
function lsloupec()
{
$head->set_title('tralala');
$return='';
//----------Články------------//
$menu_clanky=new Menu('Články');
{
$menu_clanky->add_polozky('O rase','o_rase','');
$menu_clanky->add_polozky('Rozhovory','clanky','rozhovory');
$menu_clanky->add_polozky('Rady nováčkům','clanky','rady_novackum');
$menu_clanky->add_polozky('Herní principy','clanky','herni_principy');
}
$return.=$menu_clanky->vytvor();
$return.='<br><br>';
Tady je celý výpis chyby: Fatal error: Call to a member function set_title() on a non-object in /home/free/ic.cz/k/kosar-vyvoj/root/www/novy/lsloupec.php on line 4 Celá funkce lsloupec() je deklarována až poté, co je vytvořen objek head. Nevíte prosím někdo, jak by se tohle dalo řešit? Tuším sice, že by se to možná dalo řešit jakýmsi předáváním ukazatele na objekt jako argumentu volání funkce, ale já těch funkcí používám opravdu hodně, i těch objektů bude trochu více. Takže budu vděčný za jakékoliv nápady a rady. Předem děkuji všem |
||
| __construct Profil |
#2 · Zasláno: 31. 5. 2010, 14:41:21 · Upravil/a: __construct
Pletú sa Ti pojmy funkcia a metóda (pred pár dňami to tu bolo rozoberané)
Každopádne ak chceš z funkcie (nie metódy) pristupovať k nejakému objektu musíš si v nej vytvoriť inštanciu tej triedy ... Pokiaľ chceš k tomu objektu pristupovať z vnútra iného objektu (z metódy - nie funkcie) stačí si vytvoriť inštanciu v rámci objektu a pristupovať k nej cez $this->objekt->metoda(); //edit: odporúčam prečítať tento článok |
||
| Jankosar Profil |
#3 · Zasláno: 31. 5. 2010, 14:56:31
rozdíl mezi funkcí a metodou je mi celkem jasný, teď vidím, že jsem to nahoře trochu spletl (zmátla mě ta chybová hláška)
Jinak tebou navrhované řešení by v tomto případě příliš nepomohlo. Já už mám vytvořenou jednu instanci třídy Head a v ní mám uložena všechna data. Pokud bych si vytvořil další instanci třídy, nemohl bych přistupovat k datům té první instance. I když teď mě napadá, že kdybych všechny atributy třídy označil jako static, tak by jsem potom mohl měnit data v jakékoliv instanci a fungovalo by to skvěle.... Co myslíte? PS: ten článek mám dávno načtený |
||
| Majkl578 Profil |
#4 · Zasláno: 31. 5. 2010, 15:31:54 · Upravil/a: Majkl578
V tom případě by ti pomohla globálně dostupná instance. Vhodným řešením by mohla být jakási servisní třída, která by spravovala instance (hotovým příkladem může být třída Nette\Environment, která toto obstarává jako služby).
Při správném návrhu by to mohlo být poměrně čisté řešení problému. |
||
| Mastodont Profil |
#5 · Zasláno: 31. 5. 2010, 15:48:05
Jankosar:
V podstatě máš tři základní možnosti, jak řešit globální dostupnost: 1. Předávat všechny potřebné jiné objekty do funkce jako parametr, do jiného objektu obvykle v konstruktoru (dependency injection - stovky článků, v poslední době silně prosazováno hlavně kvůli TDD) 2. Globální registr vracející potřebné objekty nějakou getX metodou. Registr sám je statická třída. 3. Globální statické třídy pro jednotlivé potřebné objekty. |
||
| Jankosar Profil |
#6 · Zasláno: 31. 5. 2010, 16:04:57
Děkuji všem za rady, myslím, že už začínám mít představu, co tento problém obnáší a jaké jsou možnosti ho řešit.
Majkl578: Nedělám zas tak velikou aplikaci, abych tam dával přímo tuto třídu, ale asi vytvořím něco vlastního a značně primitivnějšího Mastodont: to 2. nebo 3. bude asi ideální buď by se to dalo udělat takhle: class Get
{
static private head;
static private neco;
static private cosi;
__construct()
{
$this->head=new Head();
$this->neco=new Neco();
$this->cosi=new Cosi();
}
}a pak k nim přistupovat takto: $get=new Get();
$get->head->set_title("Titulek");
nebo by bylo skoro lepší, kdyby se to obešlo bez té obslužné třídy. Můžete mi prosím ještě trochu přiblížit, jak jste to myslel s tím bodem č 3? Děkuji. |
||
| Majkl578 Profil |
#7 · Zasláno: 31. 5. 2010, 16:16:33
Jankosar:
„abych tam dával přímo tuto třídu“ Ona by sama stejně nefungovala. A ani to nebylo záměrem. Pokud chceš použít takový přístup jaký jsi popsal, asi by bylo vhodné použít singleton třídy Get a její overloading s lazy vytvářením instancí. |
||
| Jankosar Profil |
#8 · Zasláno: 31. 5. 2010, 16:31:14
Majkl578:
"(hotovým příkladem může být třída Nette\Environment, která toto obstarává jako služby)" Tak vzhledem k tomu, že tato třída "toto obstarává", tak nevidím důvod, proč by se nedala použít. Jinak se mrknu na to cos psal. Nejsem zas moc pokročilý v PHP, tak si o tom budu muset něco počíst. |
||
| __construct Profil |
#9 · Zasláno: 31. 5. 2010, 19:46:25 · Upravil/a: __construct
[#6] Jankosar:
Toto nie je správne: class Get {
static private head;
static private neco;
static private cosi;
__construct() {
$this->head=new Head();
$this->neco=new Neco();
$this->cosi=new Cosi();
}
}
$get=new Get();
$get->head->set_title("Titulek");- Hodilo by Ti to fatal error .. k privátnej metóde sa dá pristupovať iba zvnútra .. - na statické metódy sa odkazuje dvoma dvojbodkami Trieda::statickaMetoda($argument); |
||
| Jankosar Profil |
#10 · Zasláno: 31. 5. 2010, 20:39:51
Tak jsem to vyřešil docela dobře. Děkuji všem za rady. Udělal jsem to nakonec tak, že jsem celou třídu předělal na statickou a přistupuji k ní tedy staticky. Doufám, že s tím nebudou nějaké komplikace.
Ještě jednou děkuji všem. |
||
|
Časová prodleva: 15 let
|
|||
0