I'm giving my first steps with php, and I was trying to implement a few things I find pretty useful in asp (ok, it's mainly ruby inspired stuff, actually)...
I wanted to implement named parameters, using an associative array to access the actual the properties of the object
and i wanted automatic accessors to behave like this:
by default every propery is read/write
if I define some getter / setter method, then execute it, otherwise access directly the variable.
well, i managed to achieve all this... this is how (please, any opinion / advice is welcome!)
Code: Select all
class my_class {
private $_name = 'unknown';
private $_surname = 'unknown';
public function get_surname_and_name() {
return $this->surname . ', ' . $this->name;
}
public function set_surname_and_name( $value ) {
$parsed_value = explode( ', ', $value );
$this->surname = isset( $parsed_value[0] ) ? $parsed_value[0] : 'unknown';
$this->name = isset( $parsed_value[1] ) ? $parsed_value[1] : 'unknown';
}
public function __construct( $members = null ) {
if ( ! is_null( $members ) ) $this->set_members( $members );
}
public function __destruct() {
}
public function set_member( $member, $value ) {
eval( '$this->' . $member . ' = ' . var_export( $value, true ) . ';' );
}
public function set_members( $members ) {
foreach( $members as $member => $value ) {
$this->set_member( $member, $value );
}
}
public function __set( $name, $value ) {
// si existe el setter lo ejecuto
if (method_exists( $this, 'set_'.$name ) ) {
$this->{'set_'.$name}( $value ); return;
}
//si existe la propiedad la modifico
if (property_exists( get_class( $this ), '_'.$name ) ) {
$this->{'_'.$name} = $value; return;
}
// error
throw new exception( "No 'set_$name' setter method nor '_$name' private/protected property found." );
}
public function __get( $name ) {
// if the getter exists, execute it
if (method_exists( $this, 'get_'.$name ) ) {
return $this->{'get_'.$name}();
}
if (property_exists( get_class( $this ), '_'.$name ) ) {
return $this->{'_'.$name};
}
// error
throw new exception( "No 'get_$name' getter method nor '_$name' private/protected property found." );
}
}
$c = new my_class( array(
name => 'Juan',
surname => 'Gutierrez'
) );
echo '$c->surname_and_name: '.$c->surname_and_name.'<br/>';
$c->surname_and_name = 'de la Serna, Federico';
echo '$c->surname_and_name: '.$c->surname_and_name.'<br/>';
echo '$c->name: '.$c->name.'<br/>';
echo '$c->surname: '.$c->surname.'<br/>';
the problem is that i'd like to have all this behaviour in a base class, something like base_object, so that all of my clases can extend it, and inherit all this stuff...$c->surname_and_name: Gutierrez, Juan
$c->surname_and_name: de la Serna, Federico
$c->name: Federico
$c->surname: de la Serna
so I created a base_object class with the following methods: __construct, __destruct, set_member, set_members, __set and __get
then I defined my_class2 which extended base_object
this is my new "my_class"
Code: Select all
require 'base.php';
class my_class extends base_object {
private $_name = 'unknown';
private $_surname = 'unknown';
public function get_surname_and_name() {
return $this->surname . ', ' . $this->name;
}
public function set_surname_and_name( $value ) {
$parsed_value = explode( ', ', $value );
$this->surname = isset( $parsed_value[0] ) ? $parsed_value[0] : 'unknown';
$this->name = isset( $parsed_value[1] ) ? $parsed_value[1] : 'unknown';
}
public function __construct( $members = null ) {
parent::__construct($members);
}
public function __destruct() {
parent::__destruct();
}
}
$c = new my_class( array(
name => 'Juan',
surname => 'Gutierrez'
) );
echo '$c->surname_and_name: '.$c->surname_and_name.'<br/>';
$c->surname_and_name = 'de la Serna, Federico';
echo '$c->surname_and_name: '.$c->surname_and_name.'<br/>';
echo '$c->name: '.$c->name.'<br/>';
echo '$c->surname: '.$c->surname.'<br/>';
but then I get the following error:
so, it seems like $this cannot access the private $_name variable from base_object... but, should it run just as if it were defined in class my_class??? isn't that what inheritance is about??Fatal error: Uncaught exception 'Exception' with message 'No 'set_name' setter method nor '_name' private/protected property found.' in C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php:32 Stack trace: #0 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php(13) : eval()'d code(1): base_object->__set('name', 'Juan') #1 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php(13): eval() #2 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php(18): base_object->set_member('name', 'Juan') #3 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php(6): base_object->set_members(Array) #4 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\accessor_test_2.php(22): base_object->__construct(Array) #5 C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\accessor_test_2.php(34): my_class->__construct(Array) #6 {main} thrown in C:\Inetpub\wwwroot\urbanistik\lib\cls\experiment\base.php on line 32
it seems like $this variable cannot access any of "my_class" methods or properties, its context seem to be tied to "base_object"
am I missing something???
thanks a lot
saludos
sas