Autor Zpráva
had
Profil *
Dobré odpoledne,
trochu tápu kolem návratu objektu a potřeboval bych poradit. Následující příklad (psáno od kolene):

<?php
//...tady je nějaké dibi připojení...

class Trida {

  public function __construct($config = array){
  // dynamický konstruktor - zavolá metody podle jejich názvu, které přišly z pole $config

  return $this->metoda();         // tady je objekt stále typu DibiResult
  }


  private function metoda(){
  return dibi::query(SQL);         // tady vzniká objekt DibiResult
  }

}




$config = array("vlastnost" => "hodnota");

$a = new Trida($config);        // tady už neexistuje objekt typu DibiResult, ale jenom typu Trida. :-(


$b = new Trida2();
$b->nacist($a);    // tady se očekává objekt typu DibiResult
?>

Poradíte mi, prosím, jakým způsobem dostat do metody nacist() objekt typu DibiResult a ne Trida?
Alphard
Profil
Proč nepoužijete přímo danou metodu? Z konstruktoru nic vracet nejde.
Again
Profil
Mohu se zeptat k čemu ta třída bude vlastně sloužit?
Kromě toho porušuje základní principy OOP, jak už Alphard poznamenal, konstruktor nemůže mít návratovou hodnotu, ale slouží k prvotnímu nastavení třídy.

"dynamický konstruktor" je prosím co? Pokud by měl "volat metody podle jejich názvu", tak je třeba využit callback, ne však v konstruktoru.

"tady se očekává objekt typu DibiResult" - tak když se tam očekává typ DibiResult, tak ho tam předám: $b->nacist($a->metoda()); (nutné přenastavit modifikátor přístupu na public).

Stále však nechápu, jak má výsledná třída fungovat, proto spíše vařím z vody.
had
Profil *
Chtěl jsem ušetřit zbytečné volání metody. Měl jsem za to, že stačí spustit konstruktor, který by si vše ohlídal sám. Překvapuje mě, že konstruktor nemůže nic vracet. Pokud zavolám metodu, tak to funguje. Děkuji za pomoc.


Again: netušil jsem, že konstruktor nemůže mít návratovou hodnotu. Pak se leccos vysvětluje.

Třída má za úkol vytáhnout data z databáze. Možná to je zbytečně komplikované řešení, ale nevím, jak jinak na to.

Dynamický konstruktor: ano, má za úkol volat settery na základě jejich názvu. V praxi to vypadá nějak takhle:

<?php
public function __construct($config = array()){
  foreach($config as $id => $value){
    $first_letter = mb_convert_case(substr($id, 0, 1), MB_CASE_UPPER);
    $other = substr($id, 1);
    $name = "set".$first_letter.$other; 
      
      if(method_exists($this, $name)){
        try {        
        $this->$name($value);
        } catch (Exception $chyba){
        $this->dump($chyba->getMessage());
        }        
      }
    }
}
?>

jde o to, že se nemusím vyjmenovávat jednotlivě se všemi parametry, které chci nastavit a neřeším jejich pořadí při volání konstruktoru.

"tady se očekává objekt typu DibiResult" - měl jsem za to, že se předává tímhle: $b->nacist($a); Modifikátor přístupu samozřejmě změním, díky za upozornění.

Třída má fungovat tak, že konstruktor nastaví settery a pak se zavolá ta metoda, která pošle dibi dotaz do databáze a vrátí objekt dibi zpátky.
Alphard
Profil
Co třeba použít ucfirst()? Uvedená ukázka se ale nevztahuje k původnímu problému návratové hodnoty z konstruktoru.

To, co vy tady vyrábíte se mi zdá podobné na Factory vzor. Vy vlastně ani nepotřebujete vytvářet instanci od Trida, zvážil bych statické volání Trida::build($config);.
Blbě jsem to pochopil, o tohle asi nejde. Z těch nekonzistentních útržků se neodvažuji hádat.
had
Profil *
odpovídal jsem Againovi, jak si představuju dynamický konstruktor, proto ta ukázka.

Fci ucfirst() jsem neznal, proto jsem ji nepoužil - díky za její představení. Tak zřejmě jste mi pomohli problém vyřešit - nevěděl jsem, že konstruktor nemůže vracet. Leccos ještě nevím, v OOP jsem ještě v začátcích, tak prosím o pochopení.

Doteď jsem měl za to, že konstruktor je tu od toho, aby se automaticky spustil po inicializaci třídy a něco provedl. Obvykle se tím provede nastavení proměnných přes settery, ne? Snažil jsem se na internetu získat info o callbacku, ale nikde nic moc srozumitelnýho nepíšou, nebo vážně nechápu jeho smysl. Proč nemůžu projít pole a spustit metody v konstruktoru, který je určený pro volání setterů? Přijde mi pak zbytečný psát někde něco dalšího jinýho.

...mám sem zkopírovat teda celou třídu - nerad bych byl mimo téma a někomu tu ubíral čas, když se už vlastně problém vyřešil. Pro dnešek dobrou noc.
Alphard
Profil
had:
že konstruktor je tu od toho, aby se automaticky spustil po inicializaci třídy a něco provedl
Přesně tak, ale většinou nastavuje vlastní objekt tak, aby připraven pro další práci. Nazval bych to přípravnou fází.
Když vyjdu z had [#1], konstruktor by mohl připravit prostředí, metoda() pak obsahovat vlastní kód třídy. To je ok, jenom tu metodu nevolat v konstruktoru, ale přímo.

Kdyby takových tříd bylo víc, lze využití polymorfismu, předávat instanci vaše vlastní třídy a interně pak přistupovat k jejim metodám podle určitého rozhraní. Nebo v jiných situacích (tady ne) využít dedičnost. Celkově se mi moc nelíbí staticky volané dibi uprostřed instance.
had
Profil *
Alphard:
To je ok, jenom tu metodu nevolat v konstruktoru, ale přímo.
Jo, to zní celkem logicky. To volání metody tam smáznu.

Kdyby takových tříd bylo víc, lze využití polymorfismu
To máte pravdu. Polymorfismus ale v PHP k dispozici bohužel nemáme.

Celkově se mi moc nelíbí staticky volané dibi uprostřed instance.
Na stránkách Dibi to přímo doporučují a já s nimi v tomhle souhlasím - nemusím hledat, kde mám připojovací údaje a kvůli každému dotazu navazovat znovu spojení. Jednou to spojení mám a hotovo. Nemusíte získávat instanci připojení, prostě napíšete dibi:: a máte vystaráno. dibiphp.com/

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: