Hello everyone,

I tried to create a page in the wiki but I dont see the "create" button. I
have an account but I guess I still lack permissions. Anyway here is my
proposal:

Implementation of magic method __invokeStatic

Here is the specific case that gave me the idea for the need of
__invokeStatic.

file translate.php:
<?
namespace some\path;

function translate($string) {
   return $string;
}

class translate // a singleton
{
    private static $instance;

    public function __construct() {
    }

    public static function getInstance() {
        if (!is_object(self::$instance)) {
            self::$instance = new translate();
        }
        return self::$instance;
    }

    public static function t($string) { \\ or can be _ like the gettext
        self::$instance->internalTranslate($string);
    }

    public function __invoke($string) {
        $this->internalTranslate();
    }

    public static function __invokeStatic() { // the new magic method
        return self::$instance->internalTranslate($string);
    }

    private function internalTranslate($string) {
        return $string;
    }

}
?>

In the following file invoke.php  are shown the possible ways of invokation
of the function & the methods of the class:
<?
namespace some\other\path;

use some\path as f; // [1]
use some\path\translate as t; // [2]


f\translate('something');// [1]

t::getInstance()->('something'); // [2]

t::t('something'); // [3]

t::$i('something') // [4] (unsupported at the moment)

t('something'); // [5] (this is what the proposal is about)
?>

In the real word functions like translate() are invoked very often and is
good to havea very short way to call them. Here are the options:
[1] - as the functions can not be imported with different name we have to
import the ns as something very short. But still we have to type
f\translate. We can shortne it even more if we rename the function from
translate() to t() and then it will be f\t(). But we still can not avoid
refenrecing the ns.
[2] - the calsses can be imported with different name and this saves a lot.
Then we can get/create an instance and invoke the translation using the
existing __invoke(). It is shortest than any invokation of methods like
$t->_(); for example. But this is too long
[3] - a short way to call it. But can it be even shorter?
[4] - it is not actually shorter - it implies that the $instance is public
static $i. The idea is to get the public instance and use the dynamic
__invoke. Unfortuately at the moment the php syntax does not allow this.
(anyway it is not shorter than t::t()).
[5] - a call similar to the $t() but in static context. Here is supposed the
__callStatic to be invoked. The shortest...

The problems:

The biggest problem is that there is the collision with a function defined
in some\other\path namespace called t. But fortunately this is (as far as I
can think) the only possible collision and I think it will never happen in a
modern namespaced, properly organized code, as the functions will be in
other files and namespaces, while the invoke.php file will contain only
calls but not definitions.
And of course it may confuse the developers (a function or a static
invokation of a method?). But since a lot of time we have $something() and
now we have $object(). As well in 5.3 was added some magic for static
(__callStatic).

Positives:
We can simulate functions this way! (actually I'm not pretty sure is this
good or bad). Simulating functions this way we can import them in the
namespaces (just like classes because they are in fact classes). This way
any function can be transparently converted to a class (with whatever name)
by defining __invokeStatic method and importing with an alias the class in
the working namespace (or without alias by just nameing the class with the
name of the function).

But I think the main question is - if the naming conflict can be resolved -
do you think this would be useful? I think it will be because this way all
the php code can be converted to OOP (I'm not a zealot of OOP, just
discussing the possibilities here). And if it is useful is it possible to be
implemented (my C knowledge is near 0 and my php internals is absolute 0)?


If the topic is found interesting and I get somehow permission to create a
wiki page I will happily do a RFC there.


Vesselin Kenashkov

P.S. a little offtopic but looking back at [4] - can it be done to support
the t::$i('something'); call? or {t::$i}('something'); ?

Reply via email to