Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP5] Monitoring obiektu w php, Czyli co się dzieje w naszysz obiektach
hwao
post 26.02.2006, 13:35:52
Post #1


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Ostatnio zastanawiałem się jak można pomierzyć, posprawdzać niektóre fragmenty aplikacji, wpadłem na pomysł zasotosowania metod __call(), __get(), __set() i całośc wyglada tak:

  1. <?php
  2. /**
  3.  * Monitor
  4.  * 
  5.  * @author Paweł `hwao` Halicki
  6.  * @version 1.0.0
  7.  */
  8. class Monitor {
  9. /**
  10.  * Obiekt do monitorowania
  11.  *
  12.  * @var Object
  13.  */
  14. private  $oObject = null;
  15. /**
  16.  * Nazwa monitorowanego obiektu
  17.  *
  18.  * @var string
  19.  */
  20. protected $sObject = null;
  21.  
  22. /**
  23.  * Konstruktor
  24.  *
  25.  * @param Object $oObject
  26.  */
  27. public function __construct( $oObject ) {
  28. $this->oObject = $oObject;
  29. $this->sObject = get_class( $oObject );
  30. }
  31.  
  32. /**
  33.  * Handler pobierania właściwości
  34.  *
  35.  * @param string $sKey
  36.  * @return mixed
  37.  */
  38. public function __get( $sKey ) {
  39. return $this->oObject->$sKey;
  40. }
  41.  
  42. /**
  43.  * Handler do przypisywania wartości właściwości
  44.  *
  45.  * @param string $sKey
  46.  * @param mixed $mVal
  47.  * @return mixed
  48.  */
  49. public function __set( $sKey, $mVal ) {
  50. return $this->oObject->$sKey = $mVal;
  51. }
  52.  
  53. /**
  54.  * Handler to obsługi metod
  55.  *
  56.  * @param string $sMethod
  57.  * @param array $aArgs
  58.  * @return mixed
  59.  */
  60. public function __call( $sMethod, $aArgs ) {
  61. switch( count( $aArgs ) ) {
  62. case 1:
  63. return $this->oObject->$sMethod( $aArgs[0] );
  64. break;
  65. case 2:
  66. return $this->oObject->$sMethod( $aArgs[0], $aArgs[1] );
  67. break;
  68. default:
  69. case 0:
  70. return $this->oObject->$sMethod();
  71. break;
  72. }
  73. return false;
  74. }
  75. }
  76. ?>


Na razie nic wielkiego, dajmy jakąś klasa do prze testowania np.:
  1. <?php
  2. /**
  3.  * Human
  4.  * 
  5.  * Testowa klasa, oczywiscie można uzyć każdej innej dowolnej
  6.  *
  7.  */
  8. class Human {
  9. /**
  10.  * Imię
  11.  *
  12.  * @var string
  13.  */
  14. private $sFirstName = '';
  15. /**
  16.  * Nazwisko
  17.  *
  18.  * @var string
  19.  */
  20. private $sSurname = '';
  21. /**
  22.  * Nick/ksywa
  23.  *
  24.  * @var string
  25.  */
  26. public $sNick = '';
  27. /**
  28.  * Czy żyje
  29.  *
  30.  * @var boolen
  31.  */
  32. protected $bAlive = null;
  33.  
  34. /**
  35.  * Konstruktor
  36.  *
  37.  */
  38. public function __construct() {
  39. $this->bAlive = false;
  40. }
  41.  
  42. /**
  43.  * Narodziny
  44.  *
  45.  * @param string $sFirstName
  46.  * @param string $sSurname
  47.  */
  48. public function Born( $sFirstName, $sSurname ) {
  49. if( $this->bAlive == false ) {
  50. $this->bAlive  = true;
  51. $this->sFirstName = $sFirstName;
  52. $this->sSurname  = $sSurname;
  53. }
  54. else {
  55. throw new Exception( 'Object already live!' );
  56. }
  57. }
  58.  
  59. /**
  60.  * Ustawienie "czasu" życia
  61.  * 
  62.  * @param integer $iLive
  63.  * @return boolen
  64.  */
  65.  
  66. public function setLiveTime( $iLive ) {
  67. return true;
  68. }
  69.  
  70. /**
  71.  * tongue.gif
  72.  * 
  73.  * @return boolen
  74.  */
  75. public function goToHell() { // :)
  76. $this->bAlive = false; 
  77. return true;
  78. }
  79. }
  80. ?>


Nie spierajmy sie o sama budowę klasy, to tylko przykład smile.gif

Robimy coś takiego:
  1. <?php
  2. $Human = new Monitor( new Human() );
  3. $Human->Born( 'Paweł', 'Halicki' );
  4. $Human->setLiveTime( 100 );
  5. $Human->sNick = 'hwao';
  6. $Human->setLiveTime( 50 );
  7. $Human->sNick = 'jedi hwao';
  8. $Human->setLiveTime( 0 );
  9. $Human->goToHell();
  10. $Human->sNick = 'sith hwao';
  11. ?>


Wszytko działa, tak jakbyśmy operowali na obiekcie Human, ale tak naprawdę wszystkie operacje wykonywane są na obiekcie Monitor. W praktyce oznacza to że zanim cos trafi do instancji klasy Human zostaje przeanalizowane przez obiekt Monitor. Daje nam to sporo możliwość, rozbudujmy klasę Monitor w taki oto sposób:
  1. <?php
  2. /**
  3.  * Rozszerzenie Monitora
  4.  * 
  5.  * @author hwao
  6.  * @version 1.0.0
  7.  */
  8. class ProMonitor extends Monitor {
  9. /**
  10.  * Konstuktor
  11.  *
  12.  * @param Object $oObject
  13.  */
  14. public function __construct( $oObject ) {
  15. parent::__construct( $oObject );
  16. echo 'Create new instance of object "'.$this->sObject.'"'."\n";
  17. }
  18.  
  19. /**
  20.  * Handler pobierania właściwości
  21.  *
  22.  * @param string $sKey
  23.  * @return mixed
  24.  */
  25. public function __get( $sKey ) {
  26. echo 'return '.$this->sObject.'::'.$sKey."\n";
  27. return parent::__get( $sKey );
  28. }
  29.  
  30. /**
  31.  * Handler do przypisywania wartości właściwości
  32.  *
  33.  * @param string $sKey
  34.  * @param mixed $mVal
  35.  * @return mixed
  36.  */
  37. public function __set( $sKey, $mVal ) {
  38. echo $this->sObject.'::'.$sKey.' = '.$this->____getType( $mVal )."\n";
  39. return parent::__set( $sKey, $mVal );
  40. }
  41.  
  42. /**
  43.  * Handler to obsługi metod
  44.  *
  45.  * @param string $sMethod
  46.  * @param array $aArgs
  47.  * @return mixed
  48.  */
  49. public function __call( $sMethod, $aArgs ) {
  50. $aArgs = array_map( array( $this, '____getType' ), $aArgs );
  51. echo $this->sObject.'::'.$sMethod.'( '.join( ', ', $aArgs ).' );'."\n";
  52. return parent::__call( $sMethod, $aArgs );
  53. }
  54.  
  55. /**
  56.  * Zdobywanie wiadomości o zmiennej
  57.  * 
  58.  * Pobieranie jej typu i możliwie przydatnych informacji
  59.  *
  60.  * @param mixed $mVal
  61.  * @return string
  62.  */
  63. protected function ____getType( $mVal ) {
  64. switch( strtolower( gettype( $mVal ) ) ) {
  65. case 'boolean':
  66. return '(boolean)'.( $mVal==true ? 'true' : 'false' );
  67. break;
  68. case 'integer':
  69. return '(integer)'.$mVal;
  70. break;
  71. case 'double':
  72. return '(double)'.$mVal;
  73. break;
  74. case 'string':
  75. return '(string)''.$mVal.'''; //'(length='.strlen($mVal).')';
  76. break;
  77. case 'array':
  78. return '(array)'.$mVal.'(count='.count($mVal).')';
  79. break;
  80. case 'object':
  81. return '(object)'.$mVal.'(name='.get_class($mVal).')';
  82. break;
  83. case 'resource':
  84. return '(resource)'.$mVal.'(type='.get_resource_type($mVal).')';
  85. break;
  86. case 'null':
  87. return '(null)Null';
  88. break;
  89. default:
  90. return '(unknown)'.$mVal;
  91. break;
  92. }
  93.  
  94. }
  95. }
  96. ?>


Trochę zostało dodane, głównie wyświetlanie informacji co i jak się dzieje sprawdzamy co się stanie po uruchomieniu takiego kodu:
  1. <?php
  2. /**
  3.  * Prosty sposób użycia
  4.  */
  5. echo '<pre>';
  6. $Human = new ProMonitor( new Human() );
  7. $Human->Born( 'Paweł', 'Halicki' );
  8. $Human->setLiveTime( 100 );
  9. $Human->sNick = 'hwao';
  10. $Human->setLiveTime( 50 );
  11. $Human->sNick = 'jedi hwao';
  12. $Human->setLiveTime( 0 );
  13. $Human->goToHell();
  14. $Human->sNick = 'sith hwao';
  15. echo '</pre>';
  16. ?>


Po wykonaniu skryptu naszym oczom ukaże się co się działo z obiektem Human:
Kod
Create new instance of object "Human"
Human::Born( (string)'Paweł', (string)'Halicki' );
Human::setLiveTime( (integer)100 );
Human::sNick = (string)'hwao'
Human::setLiveTime( (integer)50 );
Human::sNick = (string)'jedi hwao'
Human::setLiveTime( (integer)0 );
Human::goToHell(  );
Human::sNick = (string)'sith hwao'


W przykładzie widać tylko wejście ale nic nie stoi na przeszkodzie żeby dodać inne rzeczy, np.:
- czas dostępu do metod/właściwości (jak długo co się wykonuje),
- co zwraca dane metoda/właściwości.

Wszelkie pytania mile widziane, wiem że nie jest to za bardzo zaawansowane, ale komuś może się przydać.

Kod jest fragmentem framework'a.

Pozdrawiam
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 10)
bela
post 27.02.2006, 14:34:49
Post #2


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

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


hwao, na phpedii jest opisany obserwator. Może zainteresujesz się ;]


--------------------
Go to the top of the page
+Quote Post
Strzałek
post 4.03.2006, 20:25:35
Post #3





Grupa: Przyjaciele php.pl
Postów: 384
Pomógł: 6
Dołączył: 11.09.2004
Skąd: Grodzisk Mazowiecki

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


Bardzo ciekawe zastosowanie magicznych metod.

Mi się to podoba.


--------------------
Go to the top of the page
+Quote Post
NetJaro
post 4.03.2006, 20:40:11
Post #4





Grupa: Zarejestrowani
Postów: 475
Pomógł: 0
Dołączył: 1.04.2005
Skąd: Warszawa

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


Dzięki temu zrozumiałem działanie __set(), __get() i __call() - hwao dzięki smile.gif
Go to the top of the page
+Quote Post
LBO
post 5.03.2006, 00:45:02
Post #5





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

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


hmm.. nie jestem pewien ale chyba w repozytorium PEAR'a maja cos podobnego.. chodzi o monitorowanie obiektu, a nie sposob jaki zostal podany wyzej
Go to the top of the page
+Quote Post
hwao
post 5.03.2006, 10:27:37
Post #6


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Cytat(LBO @ 2006-03-05 00:45:02)
hmm.. nie jestem pewien ale chyba w repozytorium PEAR'a maja cos podobnego.. chodzi o monitorowanie obiektu, a nie sposob jaki zostal podany wyzej

Co rozumiesz przez monitorowanie obiektu, dla mnie jest to zobaczenie jak obiekt oddzialowywuje ze srodowiskiem jakie go otacza.
Go to the top of the page
+Quote Post
Vomit
post 5.03.2006, 12:01:40
Post #7





Grupa: Zarejestrowani
Postów: 122
Pomógł: 0
Dołączył: 23.01.2006

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


Ale po co to robic? Ma to jakis cel? rolleyes.gif
Go to the top of the page
+Quote Post
Vengeance
post 5.03.2006, 14:04:42
Post #8





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

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


"Ma to jakis cel? "

Jeden woli robić var_dumpy, drugi unit testy, a trzeci skorzysta z metody hwao. Nic nigdy się nie zmarnuje.


--------------------
Go to the top of the page
+Quote Post
hwao
post 5.03.2006, 14:20:42
Post #9


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Cytat(Vomit @ 2006-03-05 12:01:40)
Ale po co to robic? Ma to jakis cel? rolleyes.gif

Ma, ma, latwo mozna sprawdzic co sie dzieje w obiekcie, przydatne przy szukaniu bledu.

Ale glownie pisze to poto zeby pomierzyc czasy wykonywania poszczegolnych metod.

Przyklad tez pokazuje jak uzywac w php5 magicznych metod, dzieki czemu mozna napisac np DBObject, moge pokazac kod jak ktos chce.
Go to the top of the page
+Quote Post
Vengeance
post 5.03.2006, 14:50:34
Post #10





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

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


"pomierzyc czasy wykonywania poszczegolnych metod"

Zend Studio Client/Server + Debug ? I nie ma mocnych ;]


--------------------
Go to the top of the page
+Quote Post
hwao
post 5.03.2006, 15:10:47
Post #11


Developer


Grupa: Moderatorzy
Postów: 2 844
Pomógł: 20
Dołączył: 25.11.2003
Skąd: Olkusz




Cytat(Vengeance @ 2006-03-05 14:50:34)
"pomierzyc czasy wykonywania poszczegolnych metod"

Zend Studio Client/Server + Debug ? I nie ma mocnych ;]

i nie dziala, przynajmniej mi...

pozatym koszty;)
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: 14.08.2025 - 06:07