Page 1 of 1

Validating a chain of functions

Posted: Thu Dec 10, 2009 8:41 am
by pylon42
I may be using the wrong terms here. I'm just wondering if there's an easy way to test if the return value of a chain of functions exists?

Example:

Code: Select all

$var->getObject1()->getObject2()->getObject3()->getId()
In this example if any of the objects don't exist (due to being deleted in the database or whatever) I get a fatal error.

If I try an if(is_callable()), or is if(is_object()) I can validate specific objects in the chain, but I'd love to be able to validate the whole statement with a single 'if' - is that possible?

Re: Validating a chain of functions

Posted: Thu Dec 10, 2009 9:17 am
by yacahuma
is called an OR(||)

Code: Select all

 
if ( func1() || func2() || func3())
 

Re: Validating a chain of functions

Posted: Thu Dec 10, 2009 9:40 am
by pylon42
Hello,

Thanks for your reply, but I'm not sure that I understand how it would help...

I probably didn't explain the situation very well. I'm having trouble with a function chain between objects, not several methods of the same object.

So I could use &&:

Code: Select all

if(is_object($var->getObject1()) && is_object($var->getObject1()->getObject2()) && is_object($var->getObject1()->getObject2()->getObject3()) && is_integer($var->getObject1()->getObject2()->getObject3()->getId()))
But that doesn't save me any typing - and some of these chains are rather enormous. :(

I'm really just hoping there's something like 'isset()' or 'is_object()' that returns false if the function can't perform the check because the parameter is invalid, instead of causing a fatal error.

Re: Validating a chain of functions

Posted: Thu Dec 10, 2009 11:23 am
by AbraCadaver
Not that I know of, but you can build your own to use. Not tested, but here are some examples to test your chain:

Using an array of methods:

Code: Select all

is_chainable($obj, array('getObject1', 'getObject2', 'getObject3', 'getId'));
 
function is_chainable($obj, $methods)
{
    foreach($methods as $method) {
        if(!method_exists($obj, $method)) {
            return false;
        }
    }
    return true;
}
 
Using PHP syntax (might be easier as you can copy/paste stuff):

Code: Select all

is_chainable($obj, 'getObject1()->getObject2()->getObject3()->getId()');
 
function is_chainable($obj, $chain)
{
    $names = explode('->', $chain);
 
    foreach($names as $name) {
        $method = preg_replace('/\(.*/', '', $name);
        if(!method_exists($obj, $method)) {
            return false;
        }       
    }
    return true;
}
I'm not sure, but if you pass the object in by reference, then you may be able to actually execute the chain and return it. I didn't give this much thought, just an idea:

Code: Select all

$id = call_user_chain($obj, 'getObject1()->getObject2()->getObject3()->getId()');
 
function call_user_chain(&$obj, $chain)
{
    $names = explode('->', $chain);
 
    foreach($names as $name) {
        $method = preg_replace('/\(.*/', '', $name);
        if(!method_exists($obj, $method)) {
            return false;
        }       
    }
    return eval('$obj->' . $chain);
}

Re: Validating a chain of functions

Posted: Thu Dec 10, 2009 1:01 pm
by pylon42
Ah, good idea - thank you kindly, I'll give it a shot :)

Re: Validating a chain of functions

Posted: Thu Dec 10, 2009 1:04 pm
by gixmi
you have shot me :) lol, it's really gorgeous idea.:)