Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Przeciążanie konstruktora
athabus
post 30.12.2005, 13:20:03
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 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
ennics
post 30.12.2005, 13:38:13
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 30.12.2005, 13:46:28
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 30.12.2005, 13:53:41
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 30.12.2005, 14:08:24
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 30.12.2005, 14:17:29
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 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: biggrin.gif
Go to the top of the page
+Quote Post
orson
post 30.12.2005, 16:14:40
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


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
athabus
post 31.12.2005, 17:02:22
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 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 31.12.2005, 18:36:36
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 2.01.2006, 12:53:41
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.


--------------------
"Niezależnie od tego, jakie masz osiągnięcia, ktoś Ci pomaga..."
Go to the top of the page
+Quote Post
orson
post 2.01.2006, 12:58:03
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


--------------------
Computer games don't affect kids; I mean if <span style="font-weight: bold;">Pac Man</span> affected us as kids,we would all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music.
Go to the top of the page
+Quote Post
yarpo
post 18.01.2009, 21:44:28
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:biggrin.gifB tak ma:
Kod
$a = DB::connect($dsn);
Go to the top of the page
+Quote Post
WaterIntelligenc...
post 3.02.2009, 11:42:12
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 4.02.2009, 17:43:27
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


--------------------
Wyobraźnia bez wiedzy może stworzyć rzeczy piękne.
Wiedza bez wyobraźni najwyżej doskonałe.

Albert Einstein
Go to the top of the page
+Quote Post
WaterIntelligenc...
post 5.02.2009, 11:22:56
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 5.02.2009, 18:24:16
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
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.05.2025 - 07:50