So, I'm playing around with PHP, trying to write a small ORM. Having worked with Magento quite a bit lately, I've fallen in love with the automagic getters/setters that Magento, I think, inherited from Zend.
For those, who've never seen it in action, this is what I'm talking about:
$my_object->setSomeProperty('foo');
just works, as does
$my_object->getSomeProperty();
which obviously yields "foo".
Since I'm trying to implement an ORM, my goal is to provide the user with the ability to use generic functions on one hand, where
$orm_object->setSomeProperty('foo')
would map to
$orm_object->set('some_property', 'foo') // set() would obviously be a generic part of the ORM
by convention. On the other hand, if the user wanted to handle some situations differently, he could do so by defining a more specifically named function.
class foo extends ORM {
function setSome($arg_1, $arg_2)
{
…
}
}
The above example call
$orm_object->setSomeProperty('foo')
would now be mapped to
$orm_object->setSome('property', 'foo')
instead of the default set().
Alright, let's get to the point: Do you have any feedback on my implementation?
function __call($name, $arguments) {
if(preg_match('/([a-z]+)/', $name, $matches))
{
$action = $matches[0];
if(preg_match_all('/([A-Z]+)([^A-Z]+)/', $name, $matches))
{
$matches = $matches[0];
array_unshift(&$matches, $action);
for ($i = count($matches); $i > 0; $i--)
{
$potential_func_name = implode('', array_slice($matches, 0, $i));
if (method_exists($this, $potential_func_name))
{
$arguments_rest = array_slice($matches, $i);
break; // found matching function!
}
}
// handle number of arguments now!
$reflector = new ReflectionClass($this);
$num_expected_params = count($reflector->getMethod($potential_func_name)->getParameters());
$num_expected_params = $num_expected_params - count($arguments);
$params = array();
for ($i = $num_expected_params; $i > 1; $i--)
{
$params[] = strtolower(array_shift($arguments_rest));
}
$last_var = '';
$i = 0;
foreach($arguments_rest as $part)
{
$last_var .= strtolower($part);
$i++;
if ($i != count($arguments_rest)) $last_var .= '_';
}
$params[] = $last_var;
if (count($arguments) == 1) {
$arguments = array_shift(&$arguments);
}
$params[] = $arguments;
return(call_user_func_array(array($this, $potential_func_name), $params));
}
}
}