7

I have a chain call like so:

$object->getUser()->getName();

I know that I can use a string to call a function on an object:

$functionName = 'getUser';
$object->$functionName() or call_user_func(array($object, functionName))

I was wondering if it was possible to do the same for a chain call? I tried to do:

$functionName = 'getUser()->getName';
$object->functionName();

But I get an error

Method name must be a string

I guess this is because the () and -> cannot be interpreted since they are part of a string? Is there any way I can achieve this without having to do:

$function1 = getUser;
$function2 = getName;
$object->$function1()->$function2();

The aim is to get an array of functions and to chain them, in order to call this chain on the given object, e.g.:

$functions = array('getCoordinates', 'getLongitude'); // or any other chain call
$functionNames = implode('()->',$functions);
$object->$functionNames()
15
  • In your class method return the current class by doing this return $this;'. Commented May 19, 2015 at 8:08
  • 1
    @Voitcus Could you give me an example? Commented May 19, 2015 at 8:15
  • @Akar I don't understand what you mean... Commented May 19, 2015 at 8:15
  • Does it have to be a string in this format 'getUser()->getName'? It'd be pretty darn trivial if you "support" a more neutral format like getUser.getName. Would you need to support parameters as well? (If that's the case I'd question whether this whole endeavour is a good idea though.) Commented May 19, 2015 at 8:17
  • 1
    Well, that's what you have the alterable callback function for...!? If you need further details on this you should create a new question with appropriate details. Commented May 19, 2015 at 8:48

2 Answers 2

15

Let's start with a more neutral text format that's easy to handle:

$chain = 'getUser.getName';

And then simply reduce it:

$result = array_reduce(explode('.', $chain), function ($obj, $method) {
    return $obj->$method();
}, $object);

Note that you could even inspect the $obj to figure out whether $method is a method or a property or even an array index and return the value appropriately. See Twig for inspiration.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice one, but explode can use multiple-string as a delimiter, so there is no problem with ->
Yes, but the goal is to start from a language-neutral expression, not PHP-code-as-string.
1

I am trying to create a generic way of filtering objects in and array. Sometimes this filtering requires a chain call to compare specific fields with a given value.

I think that instead of inventing new solution you can use existing one like PropertyAccess Component from Symfony.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.