# $arr = array('Hello', 'world'); $arr();

- Thread: https://externals.io/message/52940
- Original archive: https://news-web.php.net/php.internals/52940
- Started by Felipe Pena on 2011-06-05T15:52:45+00:00
- Messages: 26
- Page 1 of 2: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/52940.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #52940 — Felipe Pena — 2011-06-05T15:52:45+00:00

URL: https://externals.io/message/52940#52940

Hi all,
Reading our bug tracker I noticed a good feature request [1] from 2009 which
points to an interesting feature that I think makes sense for us, since we
are now working with $f() using objects and strings, and the array('class',
'method') is an old known for `call_user_func()`-like functions.

So, I wrote a patch [2] that allow such behavior to be consistent with
arrays. See some examples:

class Hello {
   public function world($x) {
      echo "Hello, $x\n"; return $this;
   }
}

$f = array('Hello','world');
var_dump($f('you'));

$f = array(new Hello, 'foo');
$f();

All such calls match with the `call_user_func()` behavior related to magic
methods, static & non-static methods.

The array to be a valid callback should be a 2-element array, and it must be
for the first element object/string and for the second string only. (just
like our zend_is_callable() check and opcodes related to init call)

Any thoughts?

[1] - http://bugs.php.net/bug.php?id=47160
[2] - http://felipe.ath.cx/diff/fr47160.diff
phpt: http://felipe.ath.cx/diff/fr47160.phpt

-- 
Regards,
Felipe Pena

---

## #52941 — Benjamin Eberlei — 2011-06-05T15:57:59+00:00

URL: https://externals.io/message/52940#52941 · In reply to: #52940

That can lead to quite a bit of simplifications in code where you now have to check for is_array/is_callable/instanceof Closure and such. I like it.

On Sun, 5 Jun 2011 12:52:45 -0300
Felipe Pena <felipensp@gmail.com> wrote:

> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
> 
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
> 
> class Hello {
>    public function world($x) {
>       echo "Hello, $x\n"; return $this;
>    }
> }
> 
> $f = array('Hello','world');
> var_dump($f('you'));
> 
> $f = array(new Hello, 'foo');
> $f();
> 
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static & non-static methods.
> 
> The array to be a valid callback should be a 2-element array, and it must be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
> 
> Any thoughts?
> 
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt
> 
> -- 
> Regards,
> Felipe Pena

---

## #52942 — Felipe Pena — 2011-06-05T16:21:19+00:00

URL: https://externals.io/message/52940#52942 · In reply to: #52941

2011/6/5 Benjamin Eberlei <kontakt@beberlei.de>

> That can lead to quite a bit of simplifications in code where you now have
> to check for is_array/is_callable/instanceof Closure and such. I like it.
>
>
Exactly, and since our current $x = 'hello::world'; $x(); doesn't support
method calls, the array one can help on this just like the `call_user_func()`
approach with arrays.

<?php

class Hello {
   static public function world($x) {
     echo "Hello, $x\n";
   }
}

function hello_world($x) {
   echo "Hello, $x\n";
}

$callbacks = array(
   array('Hello', 'world'),
   function ($x) { echo "Hello, $x\n"; },
   'hello_world'
);

foreach ($callbacks as $k => $callback) {
   if (is_callable($callback)) {
     $callback($k);
   }
}

Output:
Hello, 0
Hello, 1
Hello, 2

-- 
Regards,
Felipe Pena

---

## #52945 — Etienne Kneuss — 2011-06-05T16:41:35+00:00

URL: https://externals.io/message/52940#52945 · In reply to: #52942

I consider this an improvement in terms of consistency w.r.t.
callbacks, so +1 from me, good job!

Best,


> 2011/6/5 Benjamin Eberlei <kontakt@beberlei.de>
>
> > […]
> Exactly, and since our current $x = 'hello::world'; $x(); doesn't support
> method calls, the array one can help on this just like the `call_user_func()`
> approach with arrays.
>
> <?php
>
> class Hello {
>   static public function world($x) {
>     echo "Hello, $x\n";
>   }
> }
>
> function hello_world($x) {
>   echo "Hello, $x\n";
> }
>
> $callbacks = array(
>   array('Hello', 'world'),
>   function ($x) { echo "Hello, $x\n"; },
>   'hello_world'
> );
>
> foreach ($callbacks as $k => $callback) {
>   if (is_callable($callback)) {
>     $callback($k);
>   }
> }
>
> Output:
> Hello, 0
> Hello, 1
> Hello, 2
>
> --
> Regards,
> Felipe Pena
>



-- 
Etienne Kneuss
http://www.colder.ch

---

## #52946 — Pierre Joye — 2011-06-05T16:42:52+00:00

URL: https://externals.io/message/52940#52946 · In reply to: #52940

+1, very good job!


> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
>
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
>
> class Hello {
>   public function world($x) {
>      echo "Hello, $x\n"; return $this;
>   }
> }
>
> $f = array('Hello','world');
> var_dump($f('you'));
>
> $f = array(new Hello, 'foo');
> $f();
>
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static & non-static methods.
>
> The array to be a valid callback should be a 2-element array, and it must be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
>
> Any thoughts?
>
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt
>
> --
> Regards,
> Felipe Pena
>



-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #52947 — Marcel Esser — 2011-06-05T16:49:04+00:00

URL: https://externals.io/message/52940#52947 · In reply to: #52946

> +1, very good job!
> 
> 
> > […]
> 
> 
> 
> -- 
> Pierre
> 
> @pierrejoye | http://blog.thepimp.net | http://www.libgd.org
> 
This is a very good idea.

-- 
Marcel Esser
VP/Engineering, CROSCON
Washington, D.C. Office
@: marcel.esser@croscon.com

office.us +1 (202) 470-6090
mobile.us +1 (202) 250-1988
mobile.de +49 (0)176 391 226 23

---

## #52950 — Ferenc Kovacs — 2011-06-05T18:16:42+00:00

URL: https://externals.io/message/52940#52950 · In reply to: #52940

> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009
> which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
>
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
>
> class Hello {
>   public function world($x) {
>      echo "Hello, $x\n"; return $this;
>   }
> }
>
> $f = array('Hello','world');
> var_dump($f('you'));
>
> $f = array(new Hello, 'foo');
> $f();
>
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static & non-static methods.
>
> The array to be a valid callback should be a 2-element array, and it must
> be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
>
> Any thoughts?
>
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt
>
> --
> Regards,
> Felipe Pena
>

+1

Tyrael

---

## #52958 — Stas Malyshev — 2011-06-05T19:49:55+00:00

URL: https://externals.io/message/52940#52958 · In reply to: #52940

Hi!

> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:

Looks good. Only question I have is that we seem to have that code 
(calling a function based on variable) in two places instead of one, I 
wonder if it's necessary and if we could unify them...
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #52959 — Zeev Suraski — 2011-06-05T19:52:38+00:00

URL: https://externals.io/message/52940#52959 · In reply to: #52940

> -----Original Message-----
> class Hello {
>    public function world($x) {
>       echo "Hello, $x\n"; return $this;
>    }
> }
>
> $f = array(new Hello, 'foo');
> $f();

Am I the only one who doesn't understand what this one is supposed to do..?

Zeev

---

## #52960 — Pierre Joye — 2011-06-05T19:55:00+00:00

URL: https://externals.io/message/52940#52960 · In reply to: #52959

> > […]
>
> Am I the only one who doesn't understand what this one is supposed to do..?

Hello::World(), like what you do in call user func, or similar to.



-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

---

## #52961 — johannes@schlueters.de — 2011-06-05T19:56:05+00:00

URL: https://externals.io/message/52940#52961 · In reply to: #52940

Hi,

recently I was surprised this didn't work. so +1 from me.

johannes


> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
> 
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
> 
> class Hello {
>    public function world($x) {
>       echo "Hello, $x\n"; return $this;
>    }
> }
> 
> $f = array('Hello','world');
> var_dump($f('you'));
> 
> $f = array(new Hello, 'foo');
> $f();
> 
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static & non-static methods.
> 
> The array to be a valid callback should be a 2-element array, and it must be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
> 
> Any thoughts?
> 
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt

---

## #52962 — Felipe Pena — 2011-06-05T20:01:55+00:00

URL: https://externals.io/message/52940#52962 · In reply to: #52959

Hi,

2011/6/5 Zeev Suraski <zeev@zend.com>

> > […]
>
> Am I the only one who doesn't understand what this one is supposed to do..?
>
>
If you are refering to the 'foo' method and the lack of arg, it's was a
typo...

The right one:

<?php

class Hello {
    public function world($x) {
      echo "Hello, $x\n"; return $this;
    }
}

$f = array(new Hello, 'world');
$f('devs');


-- 
Regards,
Felipe Pena

---

## #52964 — Zeev Suraski — 2011-06-05T20:09:39+00:00

URL: https://externals.io/message/52940#52964 · In reply to: #52962

Ok, that makes much more sense.  Given how everyone loved it I was beginning to wonder whether I’ve become too old to understand simple pieces of code ☺

Zeev

From: Felipe Pena [mailto:felipensp@gmail.com]
Sent: Sunday, June 05, 2011 11:02 PM
To: Zeev Suraski
Cc: internals
Subject: Re: [PHP-DEV] $arr = array('Hello', 'world'); $arr();

Hi,
2011/6/5 Zeev Suraski <zeev@zend.com<mailto:zeev@zend.com>>
> -----Original Message-----
> class Hello {
>    public function world($x) {
>       echo "Hello, $x\n"; return $this;
>    }
> }
>
> $f = array(new Hello, 'foo');
> $f();

Am I the only one who doesn't understand what this one is supposed to do..?

If you are refering to the 'foo' method and the lack of arg, it's was a typo...

The right one:

<?php

class Hello {
    public function world($x) {
      echo "Hello, $x\n"; return $this;
    }
}

$f = array(new Hello, 'world');
$f('devs');


--
Regards,
Felipe Pena

---

## #52967 — Felipe Pena — 2011-06-05T20:35:10+00:00

URL: https://externals.io/message/52940#52967 · In reply to: #52958

Hi,

2011/6/5 Stas Malyshev <smalyshev@sugarcrm.com>

> Hi!
>
>
>  So, I wrote a patch [2] that allow such behavior to be consistent with
> > […]
>
> Looks good. Only question I have is that we seem to have that code (calling
> a function based on variable) in two places instead of one, I wonder if it's
> necessary and if we could unify them...
>

We have the code to initialize the call from a object variable, and string
variable (function only) in this exact opcode ZEND_INIT_FCALL_BY_NAME, which
now treat the array case as well, there is no other place doing such stuff.

-- 
Regards,
Felipe Pena

---

## #52968 — Stas Malyshev — 2011-06-05T20:50:40+00:00

URL: https://externals.io/message/52940#52968 · In reply to: #52967

Hi!

> We have the code to initialize the call from a object variable, and string
> variable (function only) in this exact opcode ZEND_INIT_FCALL_BY_NAME, which
> now treat the array case as well, there is no other place doing such stuff.

What about `call_user_func()` implementation? It must be doing pretty much 
the same thing.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #52973 — Felipe Pena — 2011-06-05T21:16:14+00:00

URL: https://externals.io/message/52940#52973 · In reply to: #52968

2011/6/5 Stas Malyshev <smalyshev@sugarcrm.com>

> Hi!
>
>
>  We have the code to initialize the call from a object variable, and string
> > […]
>
> What about `call_user_func()` implementation? It must be doing pretty much
> the same thing.
>
>
1. We do not use zend_fcall_info stuff in the VM (which zend_is_callable
works in)
2. We have to use zend_do_fcall_common_helper instead of
zend_call_function() in the VM

-- 
Regards,
Felipe Pena

---

## #52979 — Hannes Landeholm — 2011-06-05T21:49:42+00:00

URL: https://externals.io/message/52940#52979 · In reply to: #52973

+1

~Hannes

---

## #52981 — Stas Malyshev — 2011-06-05T22:15:54+00:00

URL: https://externals.io/message/52940#52981 · In reply to: #52973

Hi!

> 1. We do not use zend_fcall_info stuff in the VM (which zend_is_callable
> works in)
> 2. We have to use zend_do_fcall_common_helper instead of
> zend_call_function() in the VM

Yes, I know, I just have a feeling we have two pieces of code doing the 
same in different way. But I think your proposal is good, if we figure 
out later how to unify it we can do it.
-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

---

## #53002 — Dmitry Stogov — 2011-06-06T07:24:12+00:00

URL: https://externals.io/message/52940#53002 · In reply to: #52940

Hi Felipe,

I like the idea. It makes indirect method calls less expensive.

I would add a hint to specializer, to eliminate small overhead for 
regular function calls.

} else if (OP1_TYPE != IS_CONST &&
            EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
            zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {

Thanks. Dmitry.



> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
>
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
>
> class Hello {
>     public function world($x) {
>        echo "Hello, $x\n"; return $this;
>     }
> }
>
> $f = array('Hello','world');
> var_dump($f('you'));
>
> $f = array(new Hello, 'foo');
> $f();
>
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static&  non-static methods.
>
> The array to be a valid callback should be a 2-element array, and it must be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
>
> Any thoughts?
>
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt

---

## #53010 — david.zuelke@bitextender.com — 2011-06-06T10:53:44+00:00

URL: https://externals.io/message/52940#53010 · In reply to: #52940

<3

David




> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.
> 
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
> 
> class Hello {
>   public function world($x) {
>      echo "Hello, $x\n"; return $this;
>   }
> }
> 
> $f = array('Hello','world');
> var_dump($f('you'));
> 
> $f = array(new Hello, 'foo');
> $f();
> 
> All such calls match with the `call_user_func()` behavior related to magic
> methods, static & non-static methods.
> 
> The array to be a valid callback should be a 2-element array, and it must be
> for the first element object/string and for the second string only. (just
> like our zend_is_callable() check and opcodes related to init call)
> 
> Any thoughts?
> 
> [1] - http://bugs.php.net/bug.php?id=47160
> [2] - http://felipe.ath.cx/diff/fr47160.diff
> phpt: http://felipe.ath.cx/diff/fr47160.phpt
> 
> -- 
> Regards,
> Felipe Pena

---

## #53018 — Julien Pauli — 2011-06-06T13:22:05+00:00

URL: https://externals.io/message/52940#53018 · In reply to: #53010

+1 , nice job

Julien

On Mon, Jun 6, 2011 at 12:53 PM, David Zülke
<david.zuelke@bitextender.com> wrote:
> <3
>
> David
>
>
> 
>
> > […]

---

## #53028 — Hannes Magnusson — 2011-06-06T14:34:01+00:00

URL: https://externals.io/message/52940#53028 · In reply to: #52940

> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.


I like it.

I also think we should implement "callable" typehint.
A lot of framworks are now adopting Closure as a typehint for that,
which is annoying due to the fact you have to wrap anything else in a
closure just to pass that typehint.

Essentially the callable typehint would be the same as is_callable($arg, true);

That means I can pass in any string with a function name, an array
(with class+methodname), and a closure.

-Hannes

---

## #53036 — Matthew Weier O'Phinney — 2011-06-06T15:55:07+00:00

URL: https://externals.io/message/52940#53036 · In reply to: #52940

> Reading our bug tracker I noticed a good feature request [1] from 2009
> which points to an interesting feature that I think makes sense for
> us, since we are now working with $f() using objects and strings, and
> the array('class', 'method') is an old known for `call_user_func()`-like
> functions.
>
> So, I wrote a patch [2] that allow such behavior to be consistent with
> arrays. See some examples:
>
> class Hello {
>    public function world($x) {
>       echo "Hello, $x\n"; return $this;
>    }
> }
>
> $f = array('Hello','world');
> var_dump($f('you'));
>
> $f = array(new Hello, 'foo');
> $f();
>
> All such calls match with the `call_user_func()` behavior related to
> magic methods, static & non-static methods.
>
> The array to be a valid callback should be a 2-element array, and it
> must be for the first element object/string and for the second string
> only. (just like our zend_is_callable() check and opcodes related to
> init call)
>
> Any thoughts?

Huge +1 from me -- having to do constructs like the following have been
a huge headache for me:

    if (is_callable($callback)) {
        if (is_object($callback) || is_string($callback)) {
            return $callback($arg);
        }

        return call_user_func($callback, $arg)
    }

This would simplify that tremendously:

    if (is_callable($callback)) {
        return $callback($arg);
    }

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #53043 — Matthew Weier O'Phinney — 2011-06-06T16:31:50+00:00

URL: https://externals.io/message/52940#53043 · In reply to: #53028

> 
> > […]
>
> I like it.
>
> I also think we should implement "callable" typehint.
> A lot of framworks are now adopting Closure as a typehint for that,
> which is annoying due to the fact you have to wrap anything else in a
> closure just to pass that typehint.

Agreed. It's even more problematic because the manual clearly states
that the "Closure" class is considered an implementation detail, and
should not be relied upon. As such, if the implementation changes in the
future, all those frameworks/libraries will need to refactor.

And for those that try to do it "right," they need to jump through a
fair bit of logic (test for object or string, test for array) in order
to hand off execution properly.

> Essentially the callable typehint would be the same as
> is_callable($arg, true);
>
> That means I can pass in any string with a function name, an array
> (with class+methodname), and a closure.

+1.

-- 
Matthew Weier O'Phinney
Project Lead            | matthew@zend.com
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

---

## #53081 — Christopher Jones — 2011-06-06T20:51:07+00:00

URL: https://externals.io/message/52940#53081 · In reply to: #52940

> Hi all,
> Reading our bug tracker I noticed a good feature request [1] from 2009 which
> points to an interesting feature that I think makes sense for us, since we
> are now working with $f() using objects and strings, and the array('class',
> 'method') is an old known for `call_user_func()`-like functions.

[...]

 > Any thoughts?

Felipe,

How about collating the emails and examples and creating an RFC for it?

Chris

-- 
Email: christopher.jones@oracle.com
Tel:  +1 650 506 8630
Blog:  http://blogs.oracle.com/opal/

---

Next page: https://externals.io/message/52940.md?page=2
