Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Dynamiczne dodawanie właściwości do obiektu, czy to normalne w PHP5 ?
nevt
post
Post #1





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


witajcie, może jestem durny, ale przewaliłem manual we wszystkie strony i nie znalazłem uzasadnienia do poprawności poniższej konstrukcji w PHP5, a jednak ona działa:

  1. <?php
  2. class x{};
  3. $x = new x();
  4. $x->test = 'dlaczego to tworzy nową właściwość w klasie?';
  5. echo $x->test;
  6. echo '<br />';
  7. ?>

a jeżeli to jest z jakichś dziwnych powodów normalne w PHP - to czy można jakoś ten mechanizm wyłączyć... (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 16)
LBO
post
Post #2





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


  1. <?php
  2. class x
  3. {
  4.    public function __set($name, $value)
  5.    {
  6.        trigger_error('cannot set undefined property');
  7.    }
  8. };
  9. ?>
Go to the top of the page
+Quote Post
nevt
post
Post #3





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


heh - dzięki - to że mogę zablokować __set to wiem... ale chodzi mi o globalne rozwiązanie... przecież bez sensu jest dopisywać tą funkcję do wszystkich klas w projekcie. jestem po prostu totalnie zaskoczony i rozczarowany, że pehap dopuszcza taka kombinację. to śmiech z podstaw OOP...
Go to the top of the page
+Quote Post
LBO
post
Post #4





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


Ach, to przepraszam (IMG:http://forum.php.pl/style_emoticons/default/sad.gif)

Na pocieszenie pokażę ci to:

  1. <?php
  2.  
  3. //error_reporting(E_ALL | E_STRICT);
  4. //ini_set('display_startup_errors', 1);
  5. //ini_set('display_errors', 1);
  6.  
  7. $foo->bar = "jestem obiektem powstałym z niczego";
  8. var_dump($foo);
  9.  
  10. ?>


(IMG:http://forum.php.pl/style_emoticons/default/biggrin.gif) :D:D:D:D

edit:

Ha, znalazłem.
Cytat
It’s not a bug, it’s a feature!


Ten post edytował LBO 11.11.2008, 17:18:16
Go to the top of the page
+Quote Post
mike
post
Post #5





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Nie rozumiem poruszenia. Od zawsze tak było i nie ma w tym nic strasznego.
Go to the top of the page
+Quote Post
sobstel
post
Post #6





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

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


Wydaje mi się, że to zachowanie jest całkowicie normalne dla PHP jako języka, w którym nie trzeba deklarować zmiennych wprost etc. I skoro to samo odnosi się do zmiennych, więc naturalne jest, że tak samo działa dla właściwości obiektu. W obu przypadkach PHP wyrzuca też błędy E_NOTICE (odpowiednio Undefined variable i Undefined property), co należy interpretować tak, że "pozwalamy tak robić, ale nie polecamy".

Co do przykładu LBO, to rzeczywiście takie zachowanie wydaje się trochę dziwne, ale chyba zostało pozostawione bardziej ze względu backward compatibilty, skoro obecnie w php5 wyrzuca Strict standards: Creating default object from empty value.
Go to the top of the page
+Quote Post
LBO
post
Post #7





Grupa: Zarejestrowani
Postów: 1 415
Pomógł: 117
Dołączył: 7.09.2005
Skąd: Warszawa

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


notice wyrzuca tylko kiedy chcesz odczytać atrybut wcześniej nie ustawiony. Czyli jak ustawisz taki, który nie występował w deklaracji klasy, a potem go odczytasz to nic nie wyskoczy.
Go to the top of the page
+Quote Post
sobstel
post
Post #8





Grupa: Zarejestrowani
Postów: 853
Pomógł: 25
Dołączył: 27.08.2003
Skąd: Katowice

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


Cytat(LBO @ 11.11.2008, 18:35:21 ) *
notice wyrzuca tylko kiedy chcesz odczytać atrybut wcześniej nie ustawiony. Czyli jak ustawisz taki, który nie występował w deklaracji klasy, a potem go odczytasz to nic nie wyskoczy.


Dokładnie tak jak w przypadku zmiennych, od czego zacząłem mojego posta. Jest to dla mnie naturalne zachowanie dla PHP. Nie chcę tu za wszelką cenę tego bronić i nie wiadomo czego udawadniać, ale podobnie jak mike nie widzę tutaj nic strasznego.
Go to the top of the page
+Quote Post
nevt
post
Post #9





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


ok. przyjmuję do wiadomości, że skoro zawsze tak było, to trudno, już zawsze tak będzie.

może i nic w tym strasznego, ale logiki jednak brak.

chociażby dlatego, że może skutkować ciężkimi do wychwycenia błędami w przypadku prostych literówek w nazwach właściwości obiektu. dla mnie zmienna prosta w kodzie programu a właściwość obiektu to nie to samo.

gdyby tak podchodzić do wszystkich kwestii to po co OOP w PHP ? po co PHP5 a teraz 6 skoro stare, poczciwe 4 nadal świetnie się spisuje?

pozdrawiam.
Go to the top of the page
+Quote Post
mike
post
Post #10





Grupa: Przyjaciele php.pl
Postów: 7 494
Pomógł: 302
Dołączył: 31.03.2004

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


Cytat(nevt @ 11.11.2008, 23:17:01 ) *
może i nic w tym strasznego, ale logiki jednak brak.
No własnie jest w tym logika. ~sobstel ładnie to wytłumaczył.
Cytat(nevt @ 11.11.2008, 23:17:01 ) *
chociażby dlatego, że może skutkować ciężkimi do wychwycenia błędami w przypadku prostych literówek w nazwach właściwości obiektu
Stosowanie pól publicznych i jawne odwołania do nich to powinna być rzadkość.
Więc potencjlny błąd możesz popełnić bardzo rzadko.
Go to the top of the page
+Quote Post
dr_bonzo
post
Post #11





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

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


Cytat
chociażby dlatego, że może skutkować ciężkimi do wychwycenia błędami w przypadku prostych literówek w nazwach właściwości obiektu. dla mnie zmienna prosta w kodzie programu a właściwość obiektu to nie to samo.

Jak wyzej - publiczne pola?(IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif) (normalnie nie uzywam, oprocz w moim ORM - dla wygody)
Pozatym masz uzupelnianie skladni wiec gdzie miejsce na bledy
Go to the top of the page
+Quote Post
nevt
post
Post #12





Grupa: Przyjaciele php.pl
Postów: 1 595
Pomógł: 282
Dołączył: 24.09.2007
Skąd: Reda, Pomorskie.

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


Cytat
Stosowanie pól publicznych i jawne odwołania do nich to powinna być rzadkość.
Więc potencjlny błąd możesz popełnić bardzo rzadko.

a czy ja gdzieś napisałem o publicznych właściwościach... (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)
przecież w kodzie klasy bez przerwy są odwołania do jej właściwości... to właśnie dlatego się wkurzyłem na tą konstrukcję bo kilka godzin straciłem na oświecenie że przy literówce w stylu:
  1. <?php
  2. class test
  3. {
  4.  private $dlugaNazwaZmiennej = 'TEST';
  5.  
  6.    public function __construct($value)
  7.    {
  8.        $this->dlugaNawzaZmiennej = $value;
  9.    }
  10.    
  11.    public function get()
  12.    {
  13.        return $this->dlugaNazwaZmiennej;
  14.    }
  15. }
  16.  
  17. $test = new test('ZMIANA');
  18. echo $test->get();
  19. ?>

nie dostaję od PHP najmniejszej uwagi czy ostrzeżenia...

a co do logiki to mnie nie przekonacie. nie można stawiać znaku równości między zmienną strukturalną i właściwością obiektu. to zachowanie php narusza jedną z podstawowych zasad OOP czyli hermetyzację. przecież user sobie może wrzucać do dowolnej klasy dowolne dane, na których metody obiektu nie wykonują żadnych operacji. nie mam pretensji że tak jest - tak to sobie autorzy PHP wymyślili i trudno - dostosuję się - ale nie wciskajcie mi, że jest to normalne i logiczne zachowanie kodu przy OOP... i na pewno niczego nie ułatwia a tylko potencjalnie komplikuje debugowanie aplikacji.

proponuję zakończyć dyskusję, pozdrawiam wszystkich.
Go to the top of the page
+Quote Post
Cysiaczek
post
Post #13





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




Heh, no można się o to spierać, ale ten bug...eee...feature nie stoi w sprzeczności z OOP - jest raczej zaburzeniem samego języka wynikającym z jego filozofii. Wydaje mi się, że twórcy podeszli do tego jak do normalnych zmiennych, czyli
  1. <?php
  2. $foo=true;
  3. $o->foo=true;
  4. ?>

Oznaczają to samo - inicjalizację zmiennej i jednoczesne przypisanie jej typu i wartości. Zauważcie, że intencja wydaje się słuszna - mniej pisania - lżejszy kod.
  1. <?php
  2. class A{}
  3. $o=new A();
  4. $o->foo=true;
  5. // jest lżejsze niż
  6. class A
  7. {
  8.  var foo;
  9. }
  10. $o=new A();
  11. $o->foo=true;
  12. ?>

Specjalnie użyłem var, bo taka była filozofia wcześniejszych wersji PHP. Skoro php5 jest kompatybilne z 4, to taka konstrukcja jest jak najbardziej poprawna. Skrypty PHP miały być szybkie, mało zajmować na dysku i pochłaniać mało pamięci. Jak to wygląda dla interpretera? Czy jeśli nie tworzy składowej na starcie, to oszczędza trochę pamięci? (nie zawsze trzeba z tej zmiennej korzystać)

Pozdrawiam
Go to the top of the page
+Quote Post
ucho
post
Post #14





Grupa: Zarejestrowani
Postów: 300
Pomógł: 32
Dołączył: 31.07.2006

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


Dla mnie nielogiczne jest
Kod
<?php
$a = array(1,2);
foreach($a as &$i) {
}
foreach($a as $i) {
}
print_r($a);

I to, że w manualu jest opisane dlaczego się tak dzieje i jak sobie z tym radzić wcale mnie nie przekonuje - podobnie jak w powszechnie znanym:
Kod
<?
var_dump(0 == '');
var_dump(0 == '0');
var_dump('' == '0');

A możliwość takiego modyfikacji obiektów jak opisana wątku to cecha powszechna wśród wszystkich języków dynamicznych.
Go to the top of the page
+Quote Post
singollo
post
Post #15





Grupa: Zarejestrowani
Postów: 47
Pomógł: 1
Dołączył: 25.11.2003

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


Cytat(ucho @ 13.11.2008, 09:06:23 ) *
I to, że w manualu jest opisane dlaczego się tak dzieje i jak sobie z tym radzić wcale mnie nie przekonuje - podobnie jak w powszechnie znanym:
Kod
<?
var_dump(0 == '');
var_dump(0 == '0');
var_dump('' == '0');

A możliwość takiego modyfikacji obiektów jak opisana wątku to cecha powszechna wśród wszystkich języków dynamicznych.


Ale jeśli się zastanowisz przez chwilę, to bool(false) w trzecim przykładzie jest oczywiste. W innym wypadku porównanie dwóch danych przesłanych przez użytkownika (wszystko z POST, GET itp to string) byłoby, co najmniej, zawodne - zwłaszcza przed wprowadzeniem operatora ===
Go to the top of the page
+Quote Post
ucho
post
Post #16





Grupa: Zarejestrowani
Postów: 300
Pomógł: 32
Dołączył: 31.07.2006

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


Ale psuje się przechodniość, nawet kiedy "==" oznacza "równe, choć nie musi mieć tego samego typu" to było by miło gdyby
  1. <?php
  2. (a==b) && (a==c) => b==c
  3. ?>

Efekt jest taki że w łaściwie z == nie powinno się korzystać tylko wszystko ręcznie rzutować na określony typ i porównywać ===. Tylko wtedy do czego nam == potrzebne ?
Ogólnie to tylko takie moje narzekanie bo wiadomo, że tak było, jest i będzie w dającej się przewidzieć przyszłości, choćby ze względu na zgodność ze starszym oprogramowaniem. W sumie chyba lepsze podejście niż "Chodźcie zmienimy print z instrukcji na funkcję, nieważne że wszystko się posypie, zrobimy jakieś automaty które _prawie_ wszystko przerobią same" w pythonie3k =)

Ten post edytował ucho 24.11.2008, 11:25:04
Go to the top of the page
+Quote Post
bregovic
post
Post #17





Grupa: Zarejestrowani
Postów: 562
Pomógł: 15
Dołączył: 8.08.2003
Skąd: Denmark/Odense

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


Jeśli wiesz co robisz, to czasem == można użyć z dużą efektywnością. Słabe typowanie PHP jest jednocześnie pięknem i stopą achillesową PHP. Co do tematu, to wydaje mi się że ta konstrukcja pochodzi jeszcze z czasów gdy obiekty w PHP były rozszerzonymi tablicami, a w tablicach jak wiadomo można definiować wartości bez żadnych ceregieli. Niestety PHP w tej chwili znajduje się raczej w niezbyt eksperymentalnym okresie, i jakakolwiek propozycja złamania BC (poza najmniejszymi) wywołuje w devach napady padaczki (przynajmniej wnioskując z @internals).
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: 15.09.2025 - 15:47