# __invokeStatic() method

- Thread: https://externals.io/message/66664
- Original archive: https://news-web.php.net/php.internals/66664
- Started by Daniele Orlando on 2013-03-16T19:33:49+00:00
- Messages: 16
- 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

---

## #66664 — Daniele Orlando — 2013-03-16T19:33:49+00:00

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

Hi List,

I'm interested in proposing an RFC and I would know your opinion.

=== Current Situation ===
Since PHP 5.3 we can use an object instance, who defines the __invoke()
method, as a callable object.
Example:

// PHP Code.
class Runnable
{
    public function __invoke()
    {
        echo "Runned";
    }
}

$r = new Runnable();
$r();

// Output
Runned

=== The Idea ===
In Python, when you construct an object, you don't need to use the "new"
keyword but you just invoke the class name followed by "()", like the class
is a function.
Example:

// Python Code.
class A:
    pass

A()

// Output.
<__main__.A instance at %address>

Now, would be interesting to extend the PHP __invoke() method adding an
__invokeStatic() method, like happens with __call() and __callStatic()
methods.
In this way could be possible to use a class name to invoke the
__invokeStatic() method.
Example:

// PHP Code.
class TrueRunnable
{
    public static function __invokeStatic()
    {
        echo "Runned";
    }
}

TrueRunnable();

// Output.
Runned

But the possibility are endless:

class A
{
    public static function __invokeStatic()
    {
        return new A();
    }
    public method m() {}
}

A()->m();

// or

class A
{
    private $_instance;
    public static function __invokeStatic()
    {
        // Singleton pattern.
        if (self::$_instance) {
            return self::$_instance;
        }

        return self::$_instance = new A();
    }
    public method m() {}
}

A()->m();


=== Conclusion ===
This feature makes the __invoke() method consistent with the __call() and
__callStatic() methods,
and opens the door to many cool stuff.

Any feedback is appreciated.

Daniele Orlando

---

## #66665 — Simon J Welsh — 2013-03-16T20:07:59+00:00

URL: https://externals.io/message/66664#66665 · In reply to: #66664

> Hi List,
> 
> I'm interested in proposing an RFC and I would know your opinion.
> 
> === Current Situation ===
> Since PHP 5.3 we can use an object instance, who defines the __invoke()
> method, as a callable object.
> Example:
> 
> // PHP Code.
> class Runnable
> {
>    public function __invoke()
>    {
>        echo "Runned";
>    }
> }
> 
> $r = new Runnable();
> $r();
> 
> // Output
> Runned
> 
> === The Idea ===
> In Python, when you construct an object, you don't need to use the "new"
> keyword but you just invoke the class name followed by "()", like the class
> is a function.
> Example:
> 
> // Python Code.
> class A:
>    pass
> 
> A()
> 
> // Output.
> <__main__.A instance at %address>
> 
> Now, would be interesting to extend the PHP __invoke() method adding an
> __invokeStatic() method, like happens with __call() and __callStatic()
> methods.
> In this way could be possible to use a class name to invoke the
> __invokeStatic() method.
> Example:
> 
> // PHP Code.
> class TrueRunnable
> {
>    public static function __invokeStatic()
>    {
>        echo "Runned";
>    }
> }
> 
> TrueRunnable();
> 
> // Output.
> Runned
> 
> But the possibility are endless:
> 
> class A
> {
>    public static function __invokeStatic()
>    {
>        return new A();
>    }
>    public method m() {}
> }
> 
> A()->m();
> 
> // or
> 
> class A
> {
>    private $_instance;
>    public static function __invokeStatic()
>    {
>        // Singleton pattern.
>        if (self::$_instance) {
>            return self::$_instance;
>        }
> 
>        return self::$_instance = new A();
>    }
>    public method m() {}
> }
> 
> A()->m();
> 
> 
> === Conclusion ===
> This feature makes the __invoke() method consistent with the __call() and
> __callStatic() methods,
> and opens the door to many cool stuff.
> 
> Any feedback is appreciated.
> 
> Daniele Orlando


Function and class names can overlap. So:

function a() { return "A"; }
class A {}

is valid.
---
Simon Welsh
Admin of http://simon.geek.nz/

---

## #66667 — Pierre du Plessis — 2013-03-16T20:33:05+00:00

URL: https://externals.io/message/66664#66667 · In reply to: #66664

>
> Hi List,
>
> I'm interested in proposing an RFC and I would know your opinion.
>
> === Current Situation ===
> Since PHP 5.3 we can use an object instance, who defines the __invoke()
> method, as a callable object.
> Example:
>
> // PHP Code.
> class Runnable
> {
>     public function __invoke()
>     {
>         echo "Runned";
>     }
> }
>
> $r = new Runnable();
> $r();
>
> // Output
> Runned
>
> === The Idea ===
> In Python, when you construct an object, you don't need to use the "new"
> keyword but you just invoke the class name followed by "()", like the
class
> is a function.
> Example:
>
> // Python Code.
> class A:
>     pass
>
> A()
>
> // Output.
> <__main__.A instance at %address>
>
> Now, would be interesting to extend the PHP __invoke() method adding an
> __invokeStatic() method, like happens with __call() and __callStatic()
> methods.
> In this way could be possible to use a class name to invoke the
> __invokeStatic() method.
> Example:
>
> // PHP Code.
> class TrueRunnable
> {
>     public static function __invokeStatic()
>     {
>         echo "Runned";
>     }
> }
>
> TrueRunnable();
>
> // Output.
> Runned
>
> But the possibility are endless:
>
> class A
> {
>     public static function __invokeStatic()
>     {
>         return new A();
>     }
>     public method m() {}
> }
>
> A()->m();
>
> // or
>
> class A
> {
>     private $_instance;
>     public static function __invokeStatic()
>     {
>         // Singleton pattern.
>         if (self::$_instance) {
>             return self::$_instance;
>         }
>
>         return self::$_instance = new A();
>     }
>     public method m() {}
> }
>
> A()->m();
>
>
> === Conclusion ===
> This feature makes the __invoke() method consistent with the __call() and
> __callStatic() methods,
> and opens the door to many cool stuff.
>
> Any feedback is appreciated.
>
> Daniele Orlando

I don't really see a use case for this, as you can already use the syntax
A::method();

E.G class A { public static function invoke() { return new A; }

public function m() { echo 'Runned'; }

A::invoke()->m();

Your example above only saves a few characters to type and can lead to a
lot of problems if you have a function with the same name as the class.

---

## #66676 — Thomas Bley — 2013-03-18T00:40:20+00:00

URL: https://externals.io/message/66664#66676 · In reply to: #66667

On Sat, Mar 16, 2013 at 9:33 PM, Pierre du Plessis
<pierre@pcservice.co.za> wrote:
> 
> > […]
> class
> > […]
>
> I don't really see a use case for this, as you can already use the syntax
> A::method();
>
> E.G class A { public static function invoke() { return new A; }
>
> public function m() { echo 'Runned'; }
>
> A::invoke()->m();
>
> Your example above only saves a few characters to type and can lead to a
> lot of problems if you have a function with the same name as the class.

Using A::invoke(), you need to know the name of "invoke()" and it's
hard to force users always to use the invoke() function.
Using A() would be more clean since all the static init(), factory(),
invoke(), getInstance() are gone.
Having __call(), __callStatic(), __invoke() and invokeStatic() would
make the overloading concept more consistent.

Regards,
Thomas

---

## #66677 — Pierre du Plessis — 2013-03-18T05:52:23+00:00

URL: https://externals.io/message/66664#66677 · In reply to: #66676

>
> On Sat, Mar 16, 2013 at 9:33 PM, Pierre du Plessis
> <pierre@pcservice.co.za> wrote:
> > […]
"new"
> > […]
and
> > […]
syntax
> > […]
>
> Using A::invoke(), you need to know the name of "invoke()" and it's
> hard to force users always to use the invoke() function.
> Using A() would be more clean since all the static init(), factory(),
> invoke(), getInstance() are gone.
> Having __call(), __callStatic(), __invoke() and invokeStatic() would
> make the overloading concept more consistent.
>
> Regards,
> Thomas
>
> --
> 
> 
>

Using A() looks too much like a function call. And there is still the issue
with having a function name the same as the class name.

---

## #66678 — mrtreinis@gmail.com — 2013-03-18T07:07:43+00:00

URL: https://externals.io/message/66664#66678 · In reply to: #66677

Not only that. This potentially might break compatibility with many
software products already out there. Also, this might lead to many
misunderstandings and, in fact, ambiguous code. Consider the sample.

$name = 'something';
$something = $name(); // What is this - a function call or object?

Fact is, we can not know that unless a) do a search in code b) var_dump?


2013/3/18 Pierre du Plessis <pierre@pcservice.co.za>

> 
> > […]
> __invoke()
> > […]
> "new"
> > […]
> an
> > […]
> and
> > […]
> syntax
> > […]
> a
> > […]
>
> Using A() looks too much like a function call. And there is still the issue
> with having a function name the same as the class name.

---

## #66679 — David Muir — 2013-03-18T07:49:26+00:00

URL: https://externals.io/message/66664#66679 · In reply to: #66678

> Not only that. This potentially might break compatibility with many
> software products already out there. Also, this might lead to many
> misunderstandings and, in fact, ambiguous code. Consider the sample.
> 
> $name = 'something';
> $something = $name(); // What is this - a function call or object?
> 
> Fact is, we can not know that unless a) do a search in code b) var_dump?
> 
> 
> 2013/3/18 Pierre du Plessis <pierre@pcservice.co.za>
> 
> > […]

This works well in languages like JavaScript where functions are objects.
As much as I like the feature there, I'm not sure it's a great fit for PHP.

David

Sent from my iPhone

---

## #66693 — Bruno CHALOPIN — 2013-03-19T07:26:04+00:00

URL: https://externals.io/message/66664#66693 · In reply to: #66678

Hi,

Le Mon, 18 Mar 2013 09:07:43 +0200, Matīss Roberts Treinis a écrit :
> Not only that. This potentially might break compatibility with many
> software products already out there. 

I don't see how it could break existing software as it is not a 
modification of an existing method but a brand new one.

> Also, this might lead to many
> misunderstandings and, in fact, ambiguous code. Consider the sample.
> 
> $name = 'something';
> $something = $name(); // What is this - a function call or object?
> 
> Fact is, we can not know that unless a) do a search in code b) var_dump?

As long as you use syntax like $foo = new $bar() or $foo = $bar(), you'll 
always wonder if the function/class behind $bar exist or not, etc...
And it is easy to remove any ambiguity by using $something = $functionName
() or $something = $className() or add proper comments. It's only up to 
the dev.

I find that __invokeStatic() could be a quite cool syntactic sugar.

My 2 cents.

Bruno

---

## #66694 — Pierre du Plessis — 2013-03-19T07:37:43+00:00

URL: https://externals.io/message/66664#66694 · In reply to: #66693

> Hi,
>
> Le Mon, 18 Mar 2013 09:07:43 +0200, Matīss Roberts Treinis a écrit :
> > […]
>
> I don't see how it could break existing software as it is not a
> modification of an existing method but a brand new one.
>


It would break existing software if you have a class and function with the
same name.
Consider the following example:

class foo {
}

function foo()
{

}


Now what if you have several calls to foo() in your existing application?
With the new change, will those calls call the function, or invoke the
__invokeStatic method if it is available?



>
> > […]
>
> As long as you use syntax like $foo = new $bar() or $foo = $bar(), you'll
> always wonder if the function/class behind $bar exist or not, etc...
> And it is easy to remove any ambiguity by using $something = $functionName
> () or $something = $className() or add proper comments. It's only up to
> the dev.
>
> I find that __invokeStatic() could be a quite cool syntactic sugar.
>
> My 2 cents.
>
> Bruno


I'm not against the function, just the implementation of it. __invokeStatic
might be useful in some (rare) cases,
but I don't think the proposed syntax will work.
Also I'm sure that most use cases can anyway be solved by using the
__callStatic method

---

## #66695 — Bruno CHALOPIN — 2013-03-19T07:54:19+00:00

URL: https://externals.io/message/66664#66695 · In reply to: #66694

Le Tue, 19 Mar 2013 09:37:43 +0200, Pierre du Plessis a écrit :
> It would break existing software if you have a class and function with
> the same name.
> Consider the following example:
> 
> class foo {
> }
> 
> function foo()
> {
> 
> }
> 
> Now what if you have several calls to foo() in your existing
> application? With the new change, will those calls call the function, or
> invoke the __invokeStatic method if it is available?

It will clearly technically lead to a problem. Now I don't see why in the 
world a class and a function could share the same name. Regarding 
conventions, a class name should begin with an uppercase character and a 
function a lowercase one. I don't see any relevant use case where a class 
and a function should share the same name.

Bruno

---

## #66696 — Pierre du Plessis — 2013-03-19T08:08:51+00:00

URL: https://externals.io/message/66664#66696 · In reply to: #66695

> Le Tue, 19 Mar 2013 09:37:43 +0200, Pierre du Plessis a écrit :
> > […]
>
> It will clearly technically lead to a problem. Now I don't see why in the
> world a class and a function could share the same name. Regarding
> conventions, a class name should begin with an uppercase character and a
> function a lowercase one. I don't see any relevant use case where a class
> and a function should share the same name.
>
>
PHP doesn't care about uppercase or lowercase when it comes to function
names.
Have a look at http://3v4l.org/cePT5 for an example.
And not everybody uses conventions anyway (although they should)

Although it is not common to have a class and function have the same name,
it can happen.
Take the following code as an example.

class Debug {
    public static dump($var)
    {
        // some code to debug $var
    }
}

function debug($var)
{
    return Debug::dump($var);
}

The problem is clear if you have a __invokeStatic method in the debug
class, and you want to make a call to debug().

---

## #66697 — Patrick Schaaf — 2013-03-19T08:13:08+00:00

URL: https://externals.io/message/66664#66697 · In reply to: #66695

On Tuesday 19 March 2013 02:54:19 Bruno CHALOPIN wrote:

> Now I don't see why in the world a class and a function could share the same 
name.

Well, for one, I might have code like this:

class Foo {
	public static the_usual() {
		static $instance;
		if (!isset($instance)) $instance = new Foo();
		return $instance;
	}
}

function Foo() {
	Foo::the_usual();
}

.....

> Regarding conventions, a class name should begin with an uppercase character 
and a function a lowercase one.

That' s a convention. That means that noone has to adhere to it. I don't.

> I don't see any relevant use case where a class
> and a function should share the same name.

Don't let yourself be limited by your imagination.

best regards
  Patrick

---

## #66698 — mrtreinis@gmail.com — 2013-03-19T08:37:02+00:00

URL: https://externals.io/message/66664#66698 · In reply to: #66696

Bruno,

Poor or questionable design or language use is not what this discussion is
about. PHP's greatest strength is its flexibility - PHP does allow to do
silly and sometimes, questionable things. Trying to limit this flexibility
is like trying to limit PHP, which is obviously bad thing to do. Example
given by Pierre clearly shows possibility of such code, and in fact, I have
seen such code myself in some applications where methods are shorthand's to
specific functionality provided as the class with same name. I even approve
such use and believe it can be quite handy for utility functions which does
some specific task and where you do not want your function to be miles
long, so you split it to handful of methods and wrap them in class.

These proposed changes can potentially break a lot of peoples work without
a real profit to the language or its users. By my opinion, syntax
considering function and object calls should stay separated to ensure clean
and convenient way to properly identify one from another. Also, there are
no or never has been clear and unified standard by PHP for how to name
things in PHP. If one chooses to name his functions with names similar or
exactly like classes, he must be able to do so.

2013/3/19 Pierre du Plessis <pierre@pcservice.co.za>

> > […]
> or
> > […]
> PHP doesn't care about uppercase or lowercase when it comes to function
> names.
> Have a look at http://3v4l.org/cePT5 for an example.
> And not everybody uses conventions anyway (although they should)
>
> Although it is not common to have a class and function have the same name,
> it can happen.
> Take the following code as an example.
>
> class Debug {
>     public static dump($var)
>     {
>         // some code to debug $var
>     }
> }
>
> function debug($var)
> {
>     return Debug::dump($var);
> }
>
> The problem is clear if you have a __invokeStatic method in the debug
> class, and you want to make a call to debug().

---

## #66704 — Daniele Orlando — 2013-03-19T16:35:55+00:00

URL: https://externals.io/message/66664#66704 · In reply to: #66698

It is clear to me that there are valid reasons to say yes to this proposal,
but there are a lot to say no too.
Even if it could be interesting in theory, due to of how PHP handles
collisions between classes and functions names (no check at all),
implementing a callable class could break existing code.

At the moment a class and a function with the same name can coexist,
but implementing a callable class would mess this state of affairs.
With the adoption of the namespaces, I think that this collisions could
became
so rare to not exist, but of course we cannot ignore pre existing
situations.

As suggested by Patrick Schaaf, a workaround is to implement a function,
with
the same name of the class, that behaves like a wrapper for a method call.
It is a good point, but has the negative side that it must be implemented
for every
class who follow this pattern. It is not usable in a framework for example.

It seams that to handle consistently a callable class is to modify PHP
to treat functions/classes names case sensitive and to trigger an
 `E_WARNING` (or similar) in case of collision.
In this way new code could take advantage of the new syntax and old code
could simply suppress the warning.

What do you think?

2013/3/19 Matīss Roberts Treinis <mrtreinis@gmail.com>

> Bruno,
>
> Poor or questionable design or language use is not what this discussion is
> about. PHP's greatest strength is its flexibility - PHP does allow to do
> silly and sometimes, questionable things. Trying to limit this flexibility
> is like trying to limit PHP, which is obviously bad thing to do. Example
> given by Pierre clearly shows possibility of such code, and in fact, I have
> seen such code myself in some applications where methods are shorthand's to
> specific functionality provided as the class with same name. I even approve
> such use and believe it can be quite handy for utility functions which does
> some specific task and where you do not want your function to be miles
> long, so you split it to handful of methods and wrap them in class.
>
> These proposed changes can potentially break a lot of peoples work without
> a real profit to the language or its users. By my opinion, syntax
> considering function and object calls should stay separated to ensure clean
> and convenient way to properly identify one from another. Also, there are
> no or never has been clear and unified standard by PHP for how to name
> things in PHP. If one chooses to name his functions with names similar or
> exactly like classes, he must be able to do so.
>
> 2013/3/19 Pierre du Plessis <pierre@pcservice.co.za>
>
> > […]
> with
> > […]
> the
> > […]
> a
> > […]
> class
> > […]
> name,
> > […]

---

## #66705 — Ferenc Kovacs — 2013-03-19T17:28:45+00:00

URL: https://externals.io/message/66664#66705 · In reply to: #66704

> It is clear to me that there are valid reasons to say yes to this proposal,
> but there are a lot to say no too.
> Even if it could be interesting in theory, due to of how PHP handles
> collisions between classes and functions names (no check at all),
> implementing a callable class could break existing code.
>
> At the moment a class and a function with the same name can coexist,
> but implementing a callable class would mess this state of affairs.
> With the adoption of the namespaces, I think that this collisions could
> became
> so rare to not exist, but of course we cannot ignore pre existing
> situations.
>
> As suggested by Patrick Schaaf, a workaround is to implement a function,
> with
> the same name of the class, that behaves like a wrapper for a method call.
> It is a good point, but has the negative side that it must be implemented
> for every
> class who follow this pattern. It is not usable in a framework for example.
>
> It seams that to handle consistently a callable class is to modify PHP
> to treat functions/classes names case sensitive and to trigger an
> `E_WARNING` (or similar) in case of collision.
> In this way new code could take advantage of the new syntax and old code
> could simply suppress the warning.
>
> What do you think?
>
>
pls don't top post on this list.
about the idea: I think that it would be a really major change and doing
that for the sake of a feature which only a small percentage of the
userbase would ever use seems to be a bad idea.


-- 
Ferenc Kovács
@Tyr43l - http://tyrael.hu

---

## #66706 — Pierre du Plessis — 2013-03-19T18:58:10+00:00

URL: https://externals.io/message/66664#66706 · In reply to: #66704

> It is clear to me that there are valid reasons to say yes to this proposal,
> but there are a lot to say no too.
> Even if it could be interesting in theory, due to of how PHP handles
> collisions between classes and functions names (no check at all),
> implementing a callable class could break existing code.
>
> At the moment a class and a function with the same name can coexist,
> but implementing a callable class would mess this state of affairs.
> With the adoption of the namespaces, I think that this collisions could
> became
> so rare to not exist, but of course we cannot ignore pre existing
> situations.
>
> As suggested by Patrick Schaaf, a workaround is to implement a function,
> with
> the same name of the class, that behaves like a wrapper for a method call.
> It is a good point, but has the negative side that it must be implemented
> for every
> class who follow this pattern. It is not usable in a framework for example.
>
> It seams that to handle consistently a callable class is to modify PHP
> to treat functions/classes names case sensitive and to trigger an
> `E_WARNING` (or similar) in case of collision.
> In this way new code could take advantage of the new syntax and old code
> could simply suppress the warning.
>
> What do you think?


This change might be disastrous in some applications, and I don't think it
will be worth it just for the sake of some syntactic sugar.
And still this change won't even make a difference if you have a class and
function with the same name that E.G uses all lowercase.
