Page 1 of 1
Ingenious setter pattern
Posted: Sat Dec 20, 2008 11:09 pm
by josh
Code: Select all
$method = 'set' . $normalized;
if (method_exists($this, $method)) {
$this->$method($value);
} else {
$this->setAttrib($key, $value);
}
Wow im so stupid. Been sub classing all to necessarily, just found this "PHP Pattern" in Zend_Form..
Just thought I'd share

Been tying my head into knots over this stupid @$$ problem for longer than I'd like to publicly admit

Now I can polymorphicly handle implicit as well as explicit APIs without resorting to "magic", or "reflection"
Re: Ingenious setter pattern
Posted: Sat Dec 20, 2008 11:23 pm
by Chris Corbyn
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 12:43 am
by josh
Haha I couldn't figure out how to refactor my controllers. Some models have fields that need to change at run-time, some have fields I can define on the model. I smelled a fat controller smell but couldn't figure it out, when the solution was so simple haha. Before I was subclassing my CRUD controller making template methods like:
Code: Select all
public function doExtractValues( Ne8_Model $model )
{
return array( 'title' => $model->getTitle() );
}
Now I can define available fields in an array and pass it to the CRUD controller
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 3:07 am
by Christopher
Sorry, what are you using this code for???
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 5:00 am
by Chris Corbyn
Indeed, I'm still confused
It looks like all that code does is looks for setSomeProperty and invokes it using a variable-invocation, otherwise it's stores the values in a key-value pair array? I'm not clear what the use-case is.
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 5:52 am
by VladSun
I'm confused too

I've similar methods in my base object class:
Code: Select all
abstract class Base_Object
{
......
public function set($fields)
{
foreach ($fields as $field => $value)
if (isset($this->{$field}))
$this->{$field} = $value;
return $this; // Chain
}
public function extend($fields, $overwrite = false)
{
foreach ($fields as $field => $value)
if (isset($this->{$field}) && true === $overwrite || !isset($this->{$field}))
$this->{$field} = $value;
return $this; // Chain
}
}
I usually use them to initialize an object with values ($fields) fetched by a SQL query.
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 6:24 am
by Chris Corbyn
I can't help but think an array is an ideal candidate for stuff like that.
Code: Select all
class Example
{
private $_values = array();
public function setValue($key, $value)
{
$this->_values[$key] = $value;
}
public function getValue($key)
{
return isset($this->_values[$key])
? $this->_values[$key]
: null;
}
public function getExampleProperty()
{
return $this->getValue('exampleProperty');
}
}
That's the sort of thing I use for classes that contain collections of vales, such as a record from a database.
Maybe I'm still not getting it?
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 9:07 am
by alex.barylski
In PHP 5 I would call that code confusing and bloated not ingenius...
__call and __set would make far more sense - unless I'm missing something...
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 1:04 pm
by josh
For instance in your skeleton framework you're using public properties for values in the data Mapper. Same concept, have you mappers call setOptions( array ) and have setOptions be defined in a model superclass, then each model can expose its interface independently of the mappers, as long as they implement the setOptions() method
Itll work for CRUD controllers, mappers ( data mappers ), etc..
Basically a "Foo" class might have setField( field, value ), where a "Bar" class may instead have setField( value ), if both implement setOptions they can accept a name / value array and be treated uniformly by the mappers. Previously I had to create a ComponentMapper that overrode a method that took an array of values and called each setter.. even though I knew about the reflective syntax of PHP method calling for some reason I didn't think to do this.
Re: Ingenious setter pattern
Posted: Sun Dec 21, 2008 2:49 pm
by Christopher
jshpro2 wrote:For instance in your skeleton framework you're using public properties for values in the data Mapper. Same concept, have you mappers call setOptions( array ) and have setOptions be defined in a model superclass, then each model can expose its interface independently of the mappers, as long as they implement the setOptions() method
The plan for the Skeleton Mappers is to allow you to map to a property, or to specifically named getter/setter methods, or to standard get(name)/set(name, value) methods.