Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Przeciążanie konstruktora
athabus
post
Post #1





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Mam pytanie czy w php5 da się przeciążyć konstruktor? Generalnie wiem, że można przeciążać dowolną funkcję za pomocą __call, ale z konstruktorem jakos mi nie wychodzi (IMG:http://forum.php.pl/style_emoticons/default/mad.gif)

Próbowałem zarówno użyć __construct jak i NazwaKlasy przy przeciążaniu w __call i nic z tego. Czy ktos wie jak można przeciążyć konstruktor?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 15)
ennics
post
Post #2





Grupa: Zarejestrowani
Postów: 312
Pomógł: 0
Dołączył: 29.12.2004

Ostrzeżenie: (0%)
-----


rzuć jakiś kod i napisz w jakim celu chcesz go przeciążyć.
odwoływałeś siędo niego przez self::__construct() ?
Go to the top of the page
+Quote Post
ikioloak
post
Post #3





Grupa: Zarejestrowani
Postów: 416
Pomógł: 0
Dołączył: 8.01.2004

Ostrzeżenie: (0%)
-----


Konstruktor przeciazasz w normalny sposob jak kazda inna metode. Tutaj przyklad:
  1. <?php
  2.  
  3. class foo
  4. {
  5. public function __construct()
  6. {
  7. print "foo<br>";
  8. }
  9. }
  10.  
  11. class fooEx extends foo
  12. {
  13. public function __construct()
  14. {
  15. parent::__construct();
  16. print "fooEx";
  17. }
  18. }
  19.  
  20. $foo = new foo();
  21. $fooex = new fooEx();
  22.  
  23. ?>

Wynik:
Kod
foo
foo
fooEx

oczywiscie parent::__construct(); jest tutaj niepotrzebny, dalem tylko zeby bylo widac ze jakikolwiek zwiazek z klasa nadrzedna istnieje.
Go to the top of the page
+Quote Post
athabus
post
Post #4





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


@ikioloak - chodzi mi raczej o przeciazenie konstruktora klasy tak aby moc go wywyolywac z roznymi parametrami (w innych jezykach to jest mozliwe nie wiem czy w php) - nie o dziedziczenie

@all

Podam przyklad co mniej wiecej chce zrobic. W takim razie zalozmy ze tworze klase o nazwie cls_ogloszenie. Bedzie ona zawierala tresc ogloszenia publikowana przez usera lub odczytana z bazy. Teraz musza byc 4 rozne konstruktory:

1) Ktory tworzy ogloszenie z domyslnymi danymi. np __cosntruct()
2) Ktory tworzy ogloszenie na podstawie tablicy asocjacyjnej __construct ($tablica)
3) Ktory tworzy ogloszenie na podstawie id_ogloszenia z danych z formularza np __construct($tytul_ogloszenia, $tresc_ogloszenia itp)
4) Ktory odczytuje ogloszenie z bazy np __construct($bool_odczyt_z_bazy, $id_ogloszenia)


Generalnie chodzi mi o to, ze w zaleznosci od podanej ilosci parametrow bedzie wywolywany odpowiedni konstruktor, ktory cos tam zrobi.

Probowalem takim kodem to zalatwic:
  1. <?php
  2.  
  3. public function __call($metoda, $p)
  4. {
  5.     if ($metoda=="__construct")//tu oczywiscie trzeba jeszcze liste parametrow sprawdzac
  6.     {
  7.         echo "mama";
  8.         throw new Exception ('uruchomiono konstruktor');
  9.     }
  10. }
  11.  
  12. ?>

Wiem ze kod jest jeszcze nie kompletny i trzeba sprawdzac dodatkowo liste parametrow, ale juz nawet w tym przypadku konstruktor jest pomijany -> dla innych funkcji wszystko dziala bez problemu

Nie zabardzo rozumiem o co chodzi z tym self::construct -> gdzie nalezaloby tego uzyc? W php jestem nowy.

Ten post edytował athabus 30.12.2005, 13:57:11
Go to the top of the page
+Quote Post
ikioloak
post
Post #5





Grupa: Zarejestrowani
Postów: 416
Pomógł: 0
Dołączył: 8.01.2004

Ostrzeżenie: (0%)
-----


Nie wiem czy to jest optymalne rozwiazanie, ale dziala:
  1. <?php
  2.  
  3. class foo
  4. {
  5. public function __construct($p1,$p2,$p3,$p4)
  6. {
  7. if (is_array($p1)) 
  8. {
  9. $this->ConstructFromArray($p1);
  10. }
  11. else if ((is_string($p1))&&(is_string($p2)))
  12. {
  13. $this->ConstructFromUser($p1,$p2);
  14. }
  15. }
  16.  
  17. private function ConstructFromArray($array)
  18. {
  19. print_r($array);
  20. }
  21.  
  22. private function ConstructFromUser($title,$text)
  23. {
  24. print 'tytul:'.$title.' tresc:'.$tresc;
  25. }
  26. }
  27.  
  28.  
  29. $t = array(1,2,4);
  30. $foo = @new foo($t);
  31. $foo2 = @new foo('tytul newsa','tresc newsa');
  32.  
  33. ?>

Inna opcja to jest utworzenei jednej klasy abstrakcyjnej, pozniej 4 klasy gdzie kazda implementuje na swoj sposob konstruktor, i w zaleznosci od parametrow tworzyc obiekt danej klasy. Co o tym mysilsz?
Go to the top of the page
+Quote Post
athabus
post
Post #6





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Tez wlasnie o czym takim myslalem (pierwsze rozwiazanie). Drugie jest nawet ciekawsze (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
Mam nadziej, ze kiedys w php wprowadza jakies fajne mechanizmy przeciazania takie jak np w C#. Jakos mam uprzedzenie do tych wszystkich if'ow i sprawdzania czy dany parametr jest tablica czy obiektem itd... troche to psuje czytelnosc kodu.

Ale dzieki bardzo za ten drugi sposob - jest calkiem ciekawy: (IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif)
Go to the top of the page
+Quote Post
orson
post
Post #7





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

Ostrzeżenie: (0%)
-----


witam ...

w php nie można przeciążać funkcji oraz operatorów ... do c++ jeszcze mu daleko ...

co do wywoływania to można w kontruktorze klasy bazowej robić tak: return $this = new klasa_z_parametrow ... to pozwala tworzyć obiekt zawsze przez $foo = new KlasaBazowa ...takie pseudo przeciążanie ...

pozdrawiam
Go to the top of the page
+Quote Post
athabus
post
Post #8





Grupa: Zarejestrowani
Postów: 898
Pomógł: 48
Dołączył: 2.11.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


Cytat
w php nie można przeciążać funkcji oraz operatorów ... do c++ jeszcze mu daleko ...

No funkcje niby mozna przeciazac za pomoca __call($nazwa, $parametry) - ale szczerze to faktycznie nazwanie tego przeciazaniem funckji to naduzycie (IMG:http://forum.php.pl/style_emoticons/default/worriedsmiley.gif)

Ja się obiektowego programowania uczylem na C# i teraz mi tych mechanizmow brakuje w php - moze w wersji 6 rozwiaza pare kwestii. Ale moim zdaniem i tak jest o niebo lepiej niz w PHP4
Go to the top of the page
+Quote Post
Vengeance
post
Post #9





Grupa: Zarejestrowani
Postów: 657
Pomógł: 2
Dołączył: 15.08.2003
Skąd: Łódź

Ostrzeżenie: (0%)
-----


  1. <?php
  2.  
  3.  class FOobar 
  4.  {
  5. public function __construct()
  6. {
  7. $params = func_get_args();
  8. //dalej rob co chccesz
  9. }
  10.  
  11.  }
  12.  
  13. ?>
Go to the top of the page
+Quote Post
DeyV
post
Post #10





Grupa: Zarząd
Postów: 2 277
Pomógł: 6
Dołączył: 27.12.2002
Skąd: Wołów/Wrocław




Cytat(orson @ 2005-12-30 16:14:40)
co do wywoływania to można w kontruktorze klasy bazowej robić tak: return $this = new klasa_z_parametrow ... to pozwala tworzyć obiekt zawsze przez $foo = new KlasaBazowa ...takie pseudo

Niestety - nic z tego.
Kontruktor nie może nic zwracać.
Return może zostać użyte tylko bez parametrów, w celu zakończenia działania metody.
Go to the top of the page
+Quote Post
orson
post
Post #11





Grupa: Zarejestrowani
Postów: 548
Pomógł: 2
Dołączył: 19.07.2003

Ostrzeżenie: (0%)
-----


witam ...

to w takim razie w php5 się to zmieniło bo pod 4 używam tego w klasie dostępu do danych ... tworze w zależności od wymagań instancję klasy pochodnej mysql lub postgresa ...
a właściwie to nie musi to być w returnie ... można wywalić słowo return i też powinno działać ...

pozdrawiam
Go to the top of the page
+Quote Post
yarpo
post
Post #12





Grupa: Zarejestrowani
Postów: 22
Pomógł: 0
Dołączył: 19.06.2007
Skąd: Gdańsk

Ostrzeżenie: (10%)
X----


A to nie możesz stworzyć w klasie bazowej dla obu klas pochodnych (mysql, postgree), metody statycznej, która będzie zwracać odpowiedni obiekt?

Zauważ, że PEAR:(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) B tak ma:
Kod
$a = DB::connect($dsn);
Go to the top of the page
+Quote Post
WaterIntelligenc...
post
Post #13





Grupa: Zarejestrowani
Postów: 7
Pomógł: 1
Dołączył: 29.09.2008
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


Można również stworzyć Fabrykę i jest to moim zdaniem najlepsze rozwiązanie dla tworzenia parametryzowanych obiektów. Rozdzielamy odpowiedzialność w czytelny i bardziej intuicyjny sposób.

CODE


class Foo
{
public function __construct()
{ }
}

class FactoryFoo{

public function createFromArray($arr){
$objFoo = new Foo(); $objFoo->p1 = $arr['p1']; // itd
return $objFoo;
}

public function createFromUser($user){ ... }

public function createFromPOSTRequest($arrPost){ ... }

// itd.

}



Unikamy stosowania 'if'.
Go to the top of the page
+Quote Post
plurr
post
Post #14





Grupa: Zarejestrowani
Postów: 175
Pomógł: 12
Dołączył: 28.06.2007
Skąd: Bytom

Ostrzeżenie: (0%)
-----


WaterIntelligence, nie rozumiem, jak chcesz unikac ifów (ew. case'ów) stosując Factory ? Wg mnie jedno z drugim jest powiazane. Co za tym idzie, aby osiągnać coś na kształt overrida i tak musimy wykonać rzezbe na parametrach konstruktora.

Ten post edytował plurr 4.02.2009, 17:43:49
Go to the top of the page
+Quote Post
WaterIntelligenc...
post
Post #15





Grupa: Zarejestrowani
Postów: 7
Pomógł: 1
Dołączył: 29.09.2008
Skąd: Świdnica

Ostrzeżenie: (0%)
-----


To oczywiście zależy w jakim miejscu budujemy taki obiekt. Możemy przecież zbudować go bezpośrednio wywołując metodę konkretną z fabryki w klasie klienta. Wtedy nie ma w ogóle potrzeby korzystania z 'if'. Podam przykład który zobrazuje o co mi chodziło:

CODE

// Dla fabryki:
class JakisKontroler{
$arr['wypelniacz1'] = $_POST['wypelniacz1'];
$arr['wypelniacz2'] = $_POST['wypelniacz2'];
$obj = $objFabrykaKlasyA->zbudujZtablicy($arr);
}
// sposób na "if'y"
class JakisKontroler{

public function wykonajCos(){
$arr['wypelniacz1'] = $_POST['wypelniacz1'];
$arr['wypelniacz2'] = $_POST['wypelniacz2'];
$obj = new KlasaA($arr); // w konstruktorze wykonuja sie warunki
}
}



Jak widać w pierwszym przypadku w ogóle nie ma 'if' a jedynie wywołanie konkretnej metody, ściśle określonej. Dodatkowo odciążamy klasę od odpowiedzialności budowania obiektu z samej siebie. Klasa moim zdaniem powinna przejmować się tym co ma robić, a nie tym w jaki sposób ma sie "rodzić" - od tego powinny być inne obiekty (oczywiście nie w każdym przypadku ale akurat w tym tak). Co więcej uznaje za złe stosowanie przeciążania ponieważ jest ono niejednoznaczne i łatwo można zapomnieć jakie parametry stosować aby otrzymać to co chcemy, przy stosowaniu metod taki problem nie istnieje bo jest wszystko jasne i przejrzyste.

Jest jeszcze kwestia tego, że przecież nie tylko możemy ustawiać zmienne w tworzonym obiekcie ale wykonywać bardziej złożone operacje podczas budowania obiektu. Więc lepiej trzymać się jednej metodyki wtedy projekt staje się spójny.
Go to the top of the page
+Quote Post
markoni
post
Post #16





Grupa: Zarejestrowani
Postów: 1
Pomógł: 0
Dołączył: 8.08.2007
Skąd: Leszno

Ostrzeżenie: (0%)
-----


wcale w Factory nie musisz stosować ifów
możesz przecież skorzystać z ReflectionClass
ewentualnie stworzyć obiekt na podstawie zmiennej $object = new $classname();
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 22.08.2025 - 14:12