Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zmieniana obiektu w jego wnętrzu
Forum PHP.pl > Forum > PHP > Object-oriented programming
#luq
Mam obiekt Person który odzwierciedla 2 tabelki w bazię.

user_name
userId | userName | userSurname | email (...)

user_memo
userId | userMemo

dlatego 2 tabelki, bo nie każda osoba musi mieć opis

Stworzyć go można tylko za pomocą metody statycznej get( $id ).
Mam metodę edit( $parmArr ), który edytuje strukturę w bazię jeśli jest to konieczne, np sprawdza czy osoba ma opis jeśli nie a ja chce go jej dodać tworzy nowy rekord w tabelcę user_memo

Ogólnie działanie
  1. <?php
  2. $p = Person::get( 1 );
  3. $p->edit(
  4.    'userName' => 'foo'
  5.    'userMemo' => 'opis'
  6. );
  7. ?>


i chcę teraz żeby po edycji obiekt został zaktualizowany. Myślałem nad prostym rozwiązaniem:

  1. <?php
  2. public function edit( $dataArr ){
  3.    // jesli to potrzebne aktualizuje bazę i potem    
  4.    $this = self::get( $this->getId() );
  5. }
  6. ?>

Fatal error: Cannot re-assign $this

Ok, da się to jeszcze przejść po prostu zczytać dane podane w $dataArr i powpisywać je do właściwości, podobnie jak dla bazy robie. Ale co jeśli chce metode delete(), która ma usuwać odpowiadające rekordy w user_name oraz w user_memo oraz usunąć obiekt.

  1. <?php
  2. public function delete(){
  3.      // wywal rekordy w bazie
  4.      $this = NULL;
  5.  }
  6. ?>


Nie zadziała.
Może totalnie źle myślę... dry.gif

Edit

Oczywiście mógłbym zwracać obiekt tymi metodami ale zastanawiam się czy da się to zrobić wewnątrz.
vokiel
Witaj w te piękne niedzielne popołudnie:)

Po pierwsze, to co mi się nasuwa, to czy dana persona może mieć klika opisów? Jeśli nie (jak to jest w przypadku np stopki na forum, opisu gg... etc) to uważam, że zaoszczędzenie miejsca wynikające z przeniesienia opisów do oddzielnej tabeli jest niewielkie, a nawet przy większej ilości osób z opisami żadne. Dodatkowo powoduje niepotrzebne utrudnienia.
Proponowałbym przenieść kolumne userMemo do tabeli user_name. W takiej strukturze wszelkie odczyty i modyfikację stają się ciut łatwiejsze.
A klasę operującą na tym można by zrobić mniej więcej tak:
  1. <?php
  2. $id = 1; // id osoby w bazie
  3. $p = new Person($id);
  4. echo $p->get('userMemo'); // "Mój stary opis"
  5. $p->set('userMemo','Nowy opis');
  6. // lub
  7. $fields = array ('userMemo'=>'Nowy opis','userSurname'=>'Kowalski');
  8. $p->set($fields);
  9. $p->save();
  10. echo $p->get('userMemo'); // "Nowy opis"
  11. ?>
#luq
Tak, osoba może mieć jeden opis. W sumie masz rację z tym przeniesieniem userMemo do user_name, przy łączeniu tych 2 tabelek idzie to na pewno dłużej niż jakby było w jednej tabelce winksmiley.jpg Było by łatwiej. W sumie można by robić to tak jak to pokazałeś, tyle że ja mam statyczną metode get ponieważ są jeszcze metody
  1. <?php
  2. Person::getAll();
  3. Person::getSite( $site );
  4. ?>

Ale mniejsza z tym.

Z editem jeszcze dałbym rade zaktualizować obiekt, tylko co z delete? Można by to zrobić tak.
  1. <?php
  2. public function edit( $dataArr ){
  3.    // jesli to potrzebne aktualizuje bazę i potem    
  4.    return self::get( $this->getId() );
  5. }
  6.  
  7. public function delete(){
  8.      // wywal rekordy w bazie
  9.      return NULL;
  10. }
  11. ?>


  1. <?php
  2. $p = Person::get( 1 );
  3. $p = $p->delete();
  4. ?>


Tylko jeśli przez pomyłkę napiszemy:
  1. <?php
  2. $p = Person::get( 1 );
  3.  $p->delete();
  4. ?>


To już mamy dupkę winksmiley.jpg Obiekt istnieje natomiast w bazie już go nie ma. Dlatego zastanawiam się czy można w jakiś sposób wewnątrz obiektu go usunąć, żeby takie błędy nie mały możliwości wystąpić.
vokiel
Trochę nie rozumiem struktury klas. Masz tą klasę Person, która pobiera dane, tak? Np ::get, ::getAll, getSite(), czyli pobiera poszczególne pola z tabeli dla danego usr?
Jeśli tak, to bym proponował jedną metodę get($what), potem drugą set($what, $newValue)
Te metody, które piszesz (edit, delete) są metodami klasy Person?

A może zrobić tak:
  1. <?php
  2. class Person{
  3.  
  4.    public function __construct($id){}
  5.    public function get($what){}
  6.    public function set($what, $newValue){}
  7.    public function delete(){}
  8.    public function __destruct(){
  9.        $this->delete();
  10.    }
  11. }
  12. //Wykorzystanie
  13. $p = new Pesron(1);
  14. $p->get('userMemo');
  15. unset($p); // obiekt zniszczony, z bazy usunięty
  16. ?>
#luq
Cytat
Np ::get, ::getAll, getSite(), czyli pobiera poszczególne pola z tabeli dla danego usr?

Nie, nie, nie.
::get() pobiera wszystkie dane jednego usera i tworzy z tego obiekt
::getAll() pobiera i tworzy obiekty wszystkich userów z bazy
::getSite() pobiera stronę userów przykładowo gdy podamy parametr 2 dostaniemy userów od 21 do 40 (ORDER BY un.userId LIMIT (...)) oczywiście zależne jest to od wartości stałej ile ma być userów na stronie. W tym wypadku stała jest ustawiona na 20.

Ogólnie ta klasa reprezentuje jednego konkretnego człowieka, właściwie tylko przechowuje we właściwościach odpowiednie pola z bazy. Ten obiekt będzie wrzucony do innego obiektu, jak zresztą masa innych.
Na stronie będzie jedynie używana tylko w takiej formie.

  1. <?php
  2. $id = // pobrane skądś tam
  3. Person::get( $id );
  4. echo Person->getName();
  5. ?>


Natomiast w panelu admina, musi być możliwośc przeglądania wszystkich, podzielenia tego na strony, edycji, usuwania i dodawania nowych. I tutaj będzie to wykorzystywane w taki sposób

  1. <?php
  2. $persons = Person::getSite( $actSite );
  3. $cntPer = count( $persons );
  4. for( $i = 0; $i < $cntPer; $i++ ){
  5.    echo $persons[$i]->getName().'<br />';
  6.    //...
  7. }
  8. ?>


Tak naprawdę to co aktualnie mam mi wystarcza. Przy usuwaniu kieruje się na adres /admin/deleteuser/3
  1. <?php
  2. $person = Person::get( 3 );
  3. $person->delete();
  4. //przenosi mnie spowrotem, wyświetla komunikat że wywalono user
  5. ?>


Wyszysko działa, tyle, że pomyślałem, że fajnie byłoby usuwać te obiekt, któego po delecie tak naprawdę już nie ma. Zostaje mi obiekt który już nie ma odzwieciedlenia w bazie. Myślę, że to było by to bardziej zgodne z OOP, logiką itd. winksmiley.jpg

Jak widać destruktor nie wchodzi w rachubę. Wyświetle usera, parser pojedzie do końca kodu i buum usuwa mi wszystkie obiekty, tym samym wywala mi je z bazy.

Nie wiem, taki model widaje mi się rozsądny. Może się myle? Z OOP nie jestem jeszcze tak bardzo obeznany winksmiley.jpg
vokiel
No to teraz rozumiem troche bardziej winksmiley.jpg

Nie widzę tu możliwości usunięcia obiektu poza unset(), poza tym nie ma takiej potrzeby.
Żeby zmodyfikować jakiegoś usr musisz wpiewr go pobrać, stworzyć obiekt. Zatem jak zrobisz:
  1. <?php
  2. $person = Person::get( 3 );
  3. $person->delete();
  4. unset($person);
  5. //to już teraz
  6. $person = Person::get( 3 ); //się nie powiedzie
  7. // ani nie zrobisz
  8. $person->edit();
  9. ?>



Myślę, że chodziło Ci o automatyzację tego unset, juz w metodzie delete, tak? Chyba pozostaje Ci samo unset, albo przeprojektowanie klas. Tak, że miałbyś klase Usr, i UsrsAdm, do której byś przekazywał obiekt tej pierwszej, na wzór:
  1. <?php
  2. $ua = new UsrAdm(new Usr(1));
  3. $ua->delete(1);
  4. ?>
#luq
Cytat(vokiel @ 24.05.2009, 23:01:19 ) *
Myślę, że chodziło Ci o automatyzację tego unset, juz w metodzie delete, tak?

Dokładnie.

Dzięki za zainteresowanie. Twoja odpowiedź mnie satysfakcjonuje, nie da się tak jak ja to wymyśliłem smile.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.