<?php /** * Monitor * * @author Paweł `hwao` Halicki * @version 1.0.0 */ class Monitor { /** * Obiekt do monitorowania * * @var Object */ private $oObject = null; /** * Nazwa monitorowanego obiektu * * @var string */ protected $sObject = null; /** * Konstruktor * * @param Object $oObject */ public function __construct( $oObject ) { $this->oObject = $oObject; $this->sObject = get_class( $oObject ); } /** * Handler pobierania właściwości * * @param string $sKey * @return mixed */ public function __get( $sKey ) { return $this->oObject->$sKey; } /** * Handler do przypisywania wartości właściwości * * @param string $sKey * @param mixed $mVal * @return mixed */ public function __set( $sKey, $mVal ) { return $this->oObject->$sKey = $mVal; } /** * Handler to obsługi metod * * @param string $sMethod * @param array $aArgs * @return mixed */ public function __call( $sMethod, $aArgs ) { case 1: return $this->oObject->$sMethod( $aArgs[0] ); break; case 2: return $this->oObject->$sMethod( $aArgs[0], $aArgs[1] ); break; default: case 0: return $this->oObject->$sMethod(); break; } return false; } } ?>
Na razie nic wielkiego, dajmy jakąś klasa do prze testowania np.:
<?php /** * Human * * Testowa klasa, oczywiscie można uzyć każdej innej dowolnej * */ class Human { /** * Imię * * @var string */ private $sFirstName = ''; /** * Nazwisko * * @var string */ private $sSurname = ''; /** * Nick/ksywa * * @var string */ public $sNick = ''; /** * Czy żyje * * @var boolen */ protected $bAlive = null; /** * Konstruktor * */ public function __construct() { $this->bAlive = false; } /** * Narodziny * * @param string $sFirstName * @param string $sSurname */ public function Born( $sFirstName, $sSurname ) { if( $this->bAlive == false ) { $this->bAlive = true; $this->sFirstName = $sFirstName; $this->sSurname = $sSurname; } else { throw new Exception( 'Object already live!' ); } } /** * Ustawienie "czasu" życia * * @param integer $iLive * @return boolen */ public function setLiveTime( $iLive ) { return true; } /** * * * @return boolen */ public function goToHell() { // :) $this->bAlive = false; return true; } } ?>
Nie spierajmy sie o sama budowę klasy, to tylko przykład

Robimy coś takiego:
<?php $Human = new Monitor( new Human() ); $Human->Born( 'Paweł', 'Halicki' ); $Human->setLiveTime( 100 ); $Human->sNick = 'hwao'; $Human->setLiveTime( 50 ); $Human->sNick = 'jedi hwao'; $Human->setLiveTime( 0 ); $Human->goToHell(); $Human->sNick = 'sith hwao'; ?>
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:
<?php /** * Rozszerzenie Monitora * * @author hwao * @version 1.0.0 */ class ProMonitor extends Monitor { /** * Konstuktor * * @param Object $oObject */ public function __construct( $oObject ) { parent::__construct( $oObject ); } /** * Handler pobierania właściwości * * @param string $sKey * @return mixed */ public function __get( $sKey ) { return parent::__get( $sKey ); } /** * Handler do przypisywania wartości właściwości * * @param string $sKey * @param mixed $mVal * @return mixed */ public function __set( $sKey, $mVal ) { return parent::__set( $sKey, $mVal ); } /** * Handler to obsługi metod * * @param string $sMethod * @param array $aArgs * @return mixed */ public function __call( $sMethod, $aArgs ) { return parent::__call( $sMethod, $aArgs ); } /** * Zdobywanie wiadomości o zmiennej * * Pobieranie jej typu i możliwie przydatnych informacji * * @param mixed $mVal * @return string */ protected function ____getType( $mVal ) { case 'boolean': return '(boolean)'.( $mVal==true ? 'true' : 'false' ); break; case 'integer': return '(integer)'.$mVal; break; case 'double': return '(double)'.$mVal; break; case 'string': return '(string)''.$mVal.'''; //'(length='.strlen($mVal).')'; break; case 'array': break; case 'object': return '(object)'.$mVal.'(name='.get_class($mVal).')'; break; case 'resource': return '(resource)'.$mVal.'(type='.get_resource_type($mVal).')'; break; case 'null': return '(null)Null'; break; default: return '(unknown)'.$mVal; break; } } } ?>
Trochę zostało dodane, głównie wyświetlanie informacji co i jak się dzieje sprawdzamy co się stanie po uruchomieniu takiego kodu:
<?php /** * Prosty sposób użycia */ $Human = new ProMonitor( new Human() ); $Human->Born( 'Paweł', 'Halicki' ); $Human->setLiveTime( 100 ); $Human->sNick = 'hwao'; $Human->setLiveTime( 50 ); $Human->sNick = 'jedi hwao'; $Human->setLiveTime( 0 ); $Human->goToHell(); $Human->sNick = 'sith hwao'; ?>
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'
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