Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Odniesienie się do obiektu przez inny w nim powstały
l0ud
post
Post #1





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Witam. Właśnie sobie uświadomiłem że dopiero raczkuję w programowaniu obiektowym, bo nie wiem nawet czy to jest możliwe: mam zamiar odnieść się do $zmienna znajdującej się w $obiekta w innym utworzonym przez niego obiekcie.

  1. <?php
  2. class A {
  3.  
  4. public $zmienna;
  5.  
  6. public function __construct() {
  7. $this->zmienna = asd;
  8. $obiektb = new B;
  9. }
  10.  
  11. }
  12.  
  13. class B {
  14.  
  15. public function __construct() {
  16. //czy da się teraz odnieść do $zmienna w obiekta?
  17. }
  18.  
  19. }
  20.  
  21. $obiekta = new A;
  22. ?>


Czy to jest w ogóle możliwe? wstydnis.gif

Pozdrawiam

Ten post edytował l0ud 29.03.2008, 21:28:03


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #2





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Nie, ale możesz przekazać referencję obiektu A do obiektu B i wtedy się da smile.gif

Pozdrawiam.


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
pyro
post
Post #3





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

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


Cytat(l0ud @ 29.03.2008, 21:27:22 ) *
Witam. Właśnie sobie uświadomiłem że dopiero raczkuję w programowaniu obiektowym, bo nie wiem nawet czy to jest możliwe: mam zamiar odnieść się do $zmienna znajdującej się w $obiekta w innym utworzonym przez niego obiekcie.

  1. <?php
  2. class A {
  3.  
  4. public $zmienna;
  5.  
  6. public function __construct() {
  7. $this->zmienna = asd;
  8. $obiektb = new B;
  9. }
  10.  
  11. }
  12.  
  13. class B {
  14.  
  15. public function __construct() {
  16. //czy da się teraz odnieść do $zmienna w obiekta?
  17. }
  18.  
  19. }
  20.  
  21. $obiekta = new A;
  22. ?>


Czy to jest w ogóle możliwe? wstydnis.gif

Pozdrawiam


Rozwiązanie twojego problemu jest aż za proste tongue.gif

class B extends A


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
l0ud
post
Post #4





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Rozumiem, że masz na myśli coś takiego?

  1. <?php
  2. class A {
  3.  
  4. public $zmienna;
  5.  
  6. public function __construct() {
  7. $this->zmienna = asd;
  8. $obiektb = new B(&$this);
  9. }
  10.  
  11. }
  12.  
  13. class B {
  14.  
  15. public function __construct(&$parent) {
  16. echo $parent->zmienna;
  17. }
  18.  
  19. }
  20.  
  21. $obiekta = new A;
  22. ?>


Zaczynam się zastanawiać, czy jest to dobre rozwiązanie przy większej aplikacji. Przykład powyżej był uproszczony: w rzeczywistości mam obiekt inicjujący, który wczytuje inne, tworzy i dodaje do swoich zmiennych (uciekło mi właściwe słowo). Te wczytane obiekty powinny móc się do siebie odnosić i dotychczas myślałem że będzie to możliwe bez problemów przez obiekt rodzica (inicjujący). Teraz się zastanawiam, czy przekazując za każdym razem jego instancję nie dochodzę do jakiegoś antywzorca?


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Moli
post
Post #5





Grupa: Zarejestrowani
Postów: 662
Pomógł: 45
Dołączył: 26.03.2007
Skąd: Warszawa

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


Możesz dać np.
  1. <?php
  2. $this->var = new var ( ) ;
  3. ?>

i później
  1. <?php
  2. $this->var->metoZklasyVar( );
  3. ?>
Go to the top of the page
+Quote Post
pyro
post
Post #6





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

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


Cytat(l0ud @ 29.03.2008, 21:51:55 ) *
Rozumiem, że masz na myśli coś takiego?

  1. <?php
  2. class A {
  3.  
  4. public $zmienna;
  5.  
  6. public function __construct() {
  7. $this->zmienna = asd;
  8. $obiektb = new B(&$this);
  9. }
  10.  
  11. }
  12.  
  13. class B {
  14.  
  15. public function __construct(&$parent) {
  16. echo $parent->zmienna;
  17. }
  18.  
  19. }
  20.  
  21. $obiekta = new A;
  22. ?>


Zaczynam się zastanawiać, czy jest to dobre rozwiązanie przy większej aplikacji. Przykład powyżej był uproszczony: w rzeczywistości mam obiekt inicjujący, który wczytuje inne, tworzy i dodaje do swoich zmiennych (uciekło mi właściwe słowo). Te wczytane obiekty powinny móc się do siebie odnosić i dotychczas myślałem że będzie to możliwe bez problemów przez obiekt rodzica (inicjujący). Teraz się zastanawiam, czy przekazując za każdym razem jego instancję nie dochodzę do jakiegoś antywzorca?


nie...

Ten post edytował pyro 29.03.2008, 22:09:55


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
l0ud
post
Post #7





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


@pyro, nie wiem do czego Twoja odpowiedź się odnosi, bo w cytacie znajdują się 3 pytania.

@Moli, nie zrozumiałem tego zbytnio. Chodzi mi o odniesienie się w podrzędnym obiekcie do nadrzędnego, a nie odwrotnie.


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Moli
post
Post #8





Grupa: Zarejestrowani
Postów: 662
Pomógł: 45
Dołączył: 26.03.2007
Skąd: Warszawa

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


No to jak dasz
  1. <?php
  2. class B extends A
  3. ?>

To do metod z A dajesz
  1. <?php
  2. $this->metodaZklasyA();
  3. ?>
Go to the top of the page
+Quote Post
l0ud
post
Post #9





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


@Moli, ale ja chcę się odnieść do konkretnego obiektu zawierającego swoje zmienne i dane a nie tylko odziedziczyć jego metody smile.gif No chyba że coś źle myślę?


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
pyro
post
Post #10





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

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


Cytat(l0ud @ 29.03.2008, 22:37:49 ) *
@Moli, ale ja chcę się odnieść do konkretnego obiektu zawierającego swoje zmienne i dane a nie tylko odziedziczyć jego metody smile.gif No chyba że coś źle myślę?


dziedziczysz tez zmienne i inne dane od rodzica


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
l0ud
post
Post #11





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Cytat
dziedziczysz tez zmienne i inne dane od rodzica


Ale nie konkretnego. (albo jestem ciągle w błędzie). Przykład: jest obiekt $db a po nim dziedziczy $queryMaker . Dane do bazy dla $db podajemy w konstruktorze. Teraz chcemy w $queryMaker wykonać zapytanie do bazy wykorzystując obiekt $db, który został już utworzony. Chyba nie uda się to przy użyciu dziedziczenia? smile.gif Singleton nie wchodzi w grę.


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Kicok
post
Post #12





Grupa: Zarejestrowani
Postów: 1 033
Pomógł: 125
Dołączył: 17.09.2005
Skąd: Żywiec

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


Dlaczego miałoby się nie udać?
  1. <?php
  2.  
  3.  
  4. class DB
  5. {
  6. public $connected = false;
  7. protected $prefix = 'abc_';
  8.  
  9.  
  10. public function __construct( )
  11. {
  12. echo "Połączono z bazą danych<br />";
  13. $this->connected = true;
  14.  
  15. }
  16.  
  17. public function query( $query )
  18. {
  19. echo "Wykonujesz zapytanie:<pre>$query</pre><br />";
  20. }
  21.  
  22. }
  23.  
  24.  
  25. class QueryMaker extends DB
  26. {
  27.  
  28. public function makeSelect( $table, $cols = '*' )
  29. {
  30. if( $this->connected )
  31. {
  32. echo "OK, jesteś połączony<br />";
  33.  
  34. $query = "SELECT $cols FROM {$this->prefix}{$table}";
  35. $this->query( $query );
  36. }
  37.  
  38. }
  39.  
  40. }
  41.  
  42.  
  43. $query = new QueryMaker();
  44. $query->makeSelect( 'tabela' );
  45.  
  46. $query->makeSelect( 'tabela2', 'a, b, c' );
  47.  
  48. ?>


Różnica jest taka, że tworzymy tylko obiekt klasy QueryMaker. Jako że klasa ta nie ma swojego konstruktora to wywoływany jest konstruktor rodzica i nawiązywane jest połączenie z bazą danych. Takie rozwiązanie ma jednak sporo wad, np.: nie da się teraz sensownie przekazać parametrów połączenia z bazą - musiałbyś przerobić klasę DB na statyczną. Trzeba także zrobić z QueryMakera Singleton bo każda nowa instancja będzie nawiązywała nowe połączenie z bazą danych.

Ja proponowałbym coś takiego:
  1. <?php
  2.  
  3.  
  4. class DBConfig
  5. {
  6. public static $DBhost  = 'localhost';
  7. public static $DBuser  = 'root';
  8. public static $DBpass  = '';
  9. public static $DBname  = 'test';
  10. public static $DBprefix = '';
  11.  
  12. public static function setConfig( array $configValues )
  13. {
  14. self::$DBhost  = $configValues['host'];
  15. self::$DBuser  = $configValues['user'];
  16. self::$DBpass  = $configValues['pass'];
  17. self::$DBname  = $configValues['name'];
  18. self::$DBprefix = $configValues['prefix'];
  19. }
  20. }
  21.  
  22.  
  23.  
  24. class DB
  25. {
  26. private $connID = null;
  27.  
  28.  
  29. public function __construct()
  30. {
  31. echo "Następuje połączenie z serwerem '" . DBConfig::$DBuser . ":" . DBConfig::$DBpass ."@" . DBConfig::$DBhost . "' i wybranie bazy '" . DBConfig::$DBname . "'<br />";
  32. }
  33.  
  34. public function __destruct()
  35. {
  36. echo "Koniec połączenia z serwerem<br />";
  37. }
  38.  
  39.  
  40. public function query( Query $query )
  41. {
  42. echo "Wykonuje zapytanie:<pre>$query</pre><br />";
  43. }
  44.  
  45. }
  46.  
  47.  
  48.  
  49. interface Query
  50. {
  51. public function __toString();
  52. }
  53.  
  54.  
  55.  
  56. class Select implements Query
  57. {
  58. private $queryParts = array();
  59.  
  60.  
  61. public function __construct( $table, array $cols = array() )
  62. {
  63. $this->queryParts['cols'] = empty( $cols ) ? '*' : implode( ', ', $cols );
  64. $this->queryParts['table'] = $table;
  65. }
  66.  
  67.  
  68. public function where( $where )
  69. {
  70. $this->queryParts['where'] = $where;
  71. return $this;
  72. }
  73.  
  74. public function order( $order, $direction = 'ASC' )
  75. {
  76. $this->queryParts['order'][] = "$order $direction";
  77. return $this;
  78. }
  79.  
  80. public function limit( $a, $b = null )
  81. {
  82. $this->queryParts['limit'] = is_null( $b ) ? "$a" : "$a, $b";
  83. return $this;
  84. }
  85.  
  86.  
  87. public function __toString()
  88. {
  89. $query = "SELECT {$this->queryParts['cols']}\nFROM " . DBConfig::$DBprefix . "{$this->queryParts['table']}";
  90.  
  91. if( !empty( $this->queryParts['where'] ) ) {
  92. $query .= "\nWHERE ( {$this->queryParts['where']} )";
  93. }
  94. if( !empty( $this->queryParts['order'] ) ) {
  95. $query .= "\nORDER BY " . implode( ', ', $this->queryParts['order'] );
  96. }
  97. if( !empty( $this->queryParts['limit'] ) ) {
  98. $query .= "\nLIMIT {$this->queryParts['limit']}";
  99. }
  100.  
  101.  
  102. return $query;
  103. }
  104.  
  105. }
  106.  
  107.  
  108. class Update implements Query
  109. {
  110. // ...
  111.  
  112. public function __toString()
  113. {
  114. }
  115.  
  116. }
  117.  
  118. class Insert implements Query
  119. {
  120. // ...
  121.  
  122. public function __toString()
  123. {
  124. }
  125.  
  126. }
  127.  
  128.  
  129.  
  130.  
  131. $DBconfig = array(
  132. 'host'  => 'localhost',
  133. 'user'  => 'root',
  134. 'pass'  => 'pass',
  135. 'name'  => 'baza',
  136. 'prefix' => 'abc_'
  137. );
  138. DBConfig::setConfig( $DBconfig );
  139.  
  140.  
  141.  
  142. $DB = new DB;
  143.  
  144.  
  145. $query = new Select( 'tabela', array( 'col1', 'col2', 'col3' ) );
  146. $DB->query( $query );
  147.  
  148. $query = new Select( 'tabela' );
  149. $query->where( 'col1 = 'abcde' AND ( col2 = 321 OR col3 IN ( 0, 2, 4, 6, 8 ) )' )
  150. ->order( 'col1' )
  151. ->order( 'col3', 'DESC' )
  152. ->limit( 50, 25 );
  153. $DB->query( $query );
  154.  
  155. ?>


Warto też poczytać o:
Criteria
http://www.php.net/manual/pl/language.oop5.static.php
http://www.php.net/manual/pl/language.oop5...nekudotayim.php
http://www.php.net/manual/pl/language.oop5.interfaces.php
http://www.php.net/manual/pl/language.oop5.typehinting.php


--------------------
"Sumienie mam czyste, bo nieużywane."
Go to the top of the page
+Quote Post
pyro
post
Post #13





Grupa: Zarejestrowani
Postów: 2 148
Pomógł: 230
Dołączył: 26.03.2008

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


Cytat(l0ud @ 30.03.2008, 00:10:12 ) *
Ale nie konkretnego. (albo jestem ciągle w błędzie). Przykład: jest obiekt $db a po nim dziedziczy $queryMaker . Dane do bazy dla $db podajemy w konstruktorze. Teraz chcemy w $queryMaker wykonać zapytanie do bazy wykorzystując obiekt $db, który został już utworzony. Chyba nie uda się to przy użyciu dziedziczenia? smile.gif Singleton nie wchodzi w grę.


jakto nie konkretnego? DZIEDZICZYSZ DANE KONKRETNEGO DZIEDZICZONEGO RODZICA, czyli tego, którego podasz w paramtetrze extends


--------------------
ET LINGUA EIUS LOQUETUR IUDICIUM
Go to the top of the page
+Quote Post
l0ud
post
Post #14





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Kicok, dzięki wielkie Twoja odpowiedź na pewno mi się przyda przy budowie sterownika bazy winksmiley.jpg Tak czy siak wróciliśmy właściwie do punktu wyjścia, czyli przekazania $DB do dowolnej klasy. Owszem, można by to było robić za każdym razem przez np. parametr w konstruktorze, ale licząc, że podobnych klas do przekazania może być kilkanaście, byłoby to niepraktyczne. Do singletonów się nie przekonam, więc myślałem jak to objeść.

Wymyśliłem utworzenie głównego obiektu $fbCore, który będzie tworzył i przechowywał wszystkie inne, przekazując im przy tworzeniu swoją instancję. Wtedy taka dołączona klasa miałaby możliwość np. do odniesienia się do wcześniej zadeklarowanej klasy bazy danych w ten sposób:
(przykładowy fragment):

  1. <?php
  2. class configRegistry {
  3. private $db;
  4. private $configArray;
  5.  
  6. public function __construct(fbCore $fbCore) {
  7. $this->db = $fbCore->getObject('database');
  8. $this->loadConfig();
  9. }
  10. ?>


Po czym inne obiekty mogłyby się odnieść do configRegistry przez $fbCore->getObject('configRegistry') smile.gif (z założenia prawie wszystkie obiekty byłyby tworzone od razu po zaincludowaniu ich kodu przez $dbCore. Byłaby też możliwość np. załadowania odpowiedniego modelu w klasie widoku przez $modelInstance = $fbCore->loadModel('nazwa_pliku','nazwaKlasy')

Główny problem, to czy nie dochodzimy w takiej koncepcji do jakiegoś antywzorca? sad.gif

Pozdrawiam


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #15





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Przenoszę na OOP

Nie będzie to jakiś antywzorzec, a przynajmniej ja tego problemu nie widzę. Możesz opisać, dlaczego tak uważasz?


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
l0ud
post
Post #16





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Bo za każdym razem przekazujemy wszystko do wszystkiego, czyli do każdego wczytanego obiektu przekazujemy instancję $dbCore które zawiera instancje do wszystkich innych klas. Chociaż tak po przemyśleniu, chyba nie jest to aż tak strasznie zasobożerne? Druga sprawa, że od razu zakładamy że każdy wczytany obiekt musi pobierać w konstruktorze tylko instancję $dbcore. Chociaż to chyba również nie jest takie złe, bo mamy jeden interfejs do tego i porządek? smile.gif

Generalnie w powyższym poście chodziło mi o ocenę pomysłu przez osobę bardziej doświadczoną z OOP. Nie chciałbym popełnić poważnych błędów już na starcie tworzenia rozbudowanej aplikacji.

Pozdrawiam


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #17





Grupa: Moderatorzy
Postów: 4 465
Pomógł: 137
Dołączył: 26.03.2004
Skąd: Gorzów Wlkp.




Pamiętaj, że przechowujesz tylko referencje do obiektów, więc nie jest to coś strasznego. Należy jedynie uważać z kopiami obiektów smile.gif

Pozdrawiam


--------------------
To think for yourself you must question authority and
learn how to put yourself in a state of vulnerable, open-mindedness;
chaotic, confused, vulnerability, to inform yourself.
Think for yourself. Question authority.
Go to the top of the page
+Quote Post
l0ud
post
Post #18





Grupa: Zarejestrowani
Postów: 1 387
Pomógł: 273
Dołączył: 18.02.2008

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


Problemów z kopiami raczej nie będzie, bo klasa jest includowana i obiekt z niej tworzony tylko raz, przez użycie $fbCore->loadX() . Za każdym każdym razem gdy jest potrzebny, pobieram instancję przez $dbCore->getObject() . Myślę, że to dobra metoda pod warunkiem, że uwzględni się wyjątki takie jak np. klasy abstrakcyjne.
Tak więc problem rozwiązany smile.gif

Dzięki za pomoc
Pozdrawiam


--------------------
XMPP: l0ud@chrome.pl
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #19





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

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


Nie wiem dlaczego, ale w trakcie czytania na myśl nasunęły mi się dwa wzorce, Budowniczy i Obserwator...
(ale zmęczony jestem, więc nie analizuję tego dokładniej, muszę w końcu wypocząć... ach ten remont)

Cytat(Cysiaczek @ 30.03.2008, 15:57:32 ) *
Pamiętaj, że przechowujesz tylko referencje do obiektów, więc nie jest to coś strasznego. Należy jedynie uważać z kopiami obiektów smile.gif


Dlatego w PHP5 domyślnie jest przy przypisaniu referencja robiona. (można wywalić & jak używasz PHP5 [a masz public więc na pewno tak jest])
Do tego kopiowanie jest ciężkie jak są złożone zależności.

Tak myśląc jednak trochę, to Budowniczy trochę jest innego zastosowania... Ale jeśli te wartości się nie zmieniają, to ustawienie ich jest najlepszym rozwiązaniem. Natomiast jeśli są zmienne to można chyba użyć obserwatora, ale to jeśli jest potrzeba reakcji na zmianę...

W sumie to coś mi się wydaje, że można by było te wartości przekazać tamtemu budowanemu obiektowi, ale musiał bym się wczytać.

(I jak już wiele razy pisałem, nie przedstawiajcie swoich rozwiązań, przemyśleń, a to co macie zrobić. Mówię tak bo to problem jest do rozwiązania, a wielokrotnie już się zdarzało, że autor proponując rozwiązanie nie przedstawił tego dobrze. Tak więc piszcie co jest problemem, a potem co najwyżej swoją propozycję, bo jak nie wiemy co dokładnie mamy rozwiązać, ciężko coś doradzić. Tak jak czy to się zmienia, czy obiekty muszą wiedzieć o zmianie itp. itd, a niże w ogóle inaczej to rozwiązać? Dlatego dobry opis problemu jest tak ważny)


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
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 Aktualny czas: 21.08.2025 - 08:10