# static constructor

- Thread: https://externals.io/message/84602
- Original archive: https://news-web.php.net/php.internals/84602
- Started by Johannes Ott on 2015-03-11T23:21:34+00:00
- Messages: 54
- RFC: Static Constructor (Inactive) — https://externals.io/rfc/static_constructor.md
- Page 1 of 3: messages 1 to 25 (25 per page, add `?page=N` to the URL)
- Next page: https://externals.io/message/84602.md?page=2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #84602 — Johannes Ott — 2015-03-11T23:21:34+00:00

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

So now I want to do my first own proposal for a new function in PHP and
I hope doing it right with starting a discussion here first.

The purpose of this suggestion is to introduce a static constructor,
which is called before the first call to class either static or
non-static to initialize some static properties which are needed by the
class.

I think about two different possible syntax to realize that purpose:

Version 1 (similar to Java):

class A {
    private static $var;

    static {
         //Do some code here to initialize self::$var;
    }

}

Version 2 (a new magic method):

class B {
    private static $var;

    private static function __static() {
        //Do some code here to initialize self::$var;
    }
}

My prefered code would be version 2 at the moment.

Looking forward to your feedback,

-- 
DerOetzi

---

## #84603 — Marco Pivetta — 2015-03-11T23:30:07+00:00

URL: https://externals.io/message/84602#84603 · In reply to: #84602

> The purpose of this suggestion is to introduce a static constructor,
> which is called before the first call to class either static or
> non-static to initialize some static properties which are needed by the
> class.
>

Hey Johannes,

Why can't this be done at autoloading time?

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

---

## #84604 — Johannes Ott — 2015-03-11T23:57:05+00:00

URL: https://externals.io/message/84602#84604 · In reply to: #84603

Am 12.03.2015 um 00:30 schrieb Marco Pivetta:
> Hey Johannes,
> 
> Why can't this be done at autoloading time?

In my opinion this should not be done on autoloading time, but as a own
method inside the class for two reasons.

1. Not every class is loaded with autoload-functions, but although
directly with include_once or required_once functions

2. The initialization of needed things inside the class should be in the
domain of the class itself and not of someone outside. Thats why I
proposed to make it a private magic method not a public one. To do by
autoload or by calling it inside the included file after
class-definition like

class B {
    ...
} B::__static();

would require to make it public and means to give the responsibility to
do the necessary initialization to someone else.

> 
> Marco Pivetta
> 
> http://twitter.com/Ocramius
> 
> http://ocramius.github.com/
> 

Regards,
-- 
DerOetzi

---

## #84605 — Rowan Collins — 2015-03-12T00:10:15+00:00

URL: https://externals.io/message/84602#84605 · In reply to: #84602

> So now I want to do my first own proposal for a new function in PHP and
> I hope doing it right with starting a discussion here first.
>
> The purpose of this suggestion is to introduce a static constructor,
> which is called before the first call to class either static or
> non-static to initialize some static properties which are needed by the
> class.

Can you give an example use case for when this would be useful? I'm 
struggling to think of one for which there isn't already an established 
coding pattern...

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #84609 — Levi Morrison — 2015-03-12T04:17:30+00:00

URL: https://externals.io/message/84602#84609 · In reply to: #84605

> 
> > […]
>
>
> Can you give an example use case for when this would be useful? I'm
> struggling to think of one for which there isn't already an established
> coding pattern...

Notably, user-land enums. You don't want public constructors because
you don't want it instantiated except for each enum property. You also
need it to run on class creation, not afterwards.

I think we'd be better off adding language-level enums than static
constructors though.

---

## #84612 — Patrick Schaaf — 2015-03-12T08:14:56+00:00

URL: https://externals.io/message/84602#84612 · In reply to: #84602

On Thursday 12 March 2015 00:21:34 Johannes Ott wrote:
>
> The purpose of this suggestion is to introduce a static constructor,
> which is called before the first call to class either static or
> non-static to initialize some static properties which are needed by the
> class.

We are doing this in our private codebase, implemented as a feature of our 
autoloader: after having loaded a class, check whether it has a static method 
called 'init§class()', and call that.

At the moment, 63 of our 397 classes have that, so it's definitely a success 
for us.

One issue to think about, is whether to call that function when it's just 
inherited. We do, and in several places, then check if (get_called_class() == 
__CLASS__). It's a bit tedious in places, but in other places it permits 
setting up of subclass static::$properties from a shared baseclass initializer 
method.

In principle none of that is neccessary, because one can put code outside the 
class definition. One more line to write. In practise, it's a bit annoying, as 
it must go after the whole class definition, or it breaks for subclasses in 
funny ways when the parent class is not already defined...

Something like your version 2 proposal, a new __magic method, would be my 
prefered choice, too.

best regards
  Patrick

---

## #84613 — Alexey Zakhlestin — 2015-03-12T08:24:18+00:00

URL: https://externals.io/message/84602#84613 · In reply to: #84602

> 
> 
> So now I want to do my first own proposal for a new function in PHP and
> I hope doing it right with starting a discussion here first.
> 
> The purpose of this suggestion is to introduce a static constructor,
> which is called before the first call to class either static or
> non-static to initialize some static properties which are needed by the
> class.
> 
> I think about two different possible syntax to realize that purpose:
> 
> Version 1 (similar to Java):
> 
> class A {
>    private static $var;
> 
>    static {
>         //Do some code here to initialize self::$var;
>    }
> 
> }
> 
> Version 2 (a new magic method):
> 
> class B {
>    private static $var;
> 
>    private static function __static() {
>        //Do some code here to initialize self::$var;
>    }
> }
> 
> My prefered code would be version 2 at the moment.
> 
> Looking forward to your feedback,

What about inheritance?
I think dynamic class-constructor would make much more sense.
A function which can analyse real class and do initialisation.

class A
{
    protected static function __class_construct()
    {
        echo `get_called_class()`.” class is defined\n";
    }
}

class B extends A
{
}

#### output ####
A class is defined
B class is defined

-- 
Alexey Zakhlestin
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc

---

## #84615 — Patrick Schaaf — 2015-03-12T08:40:35+00:00

URL: https://externals.io/message/84602#84615 · In reply to: #84605

On Thursday 12 March 2015 00:10:15 Rowan Collins wrote:
> 
>
> > […]
> 
> Can you give an example use case for when this would be useful? I'm
> struggling to think of one for which there isn't already an established
> coding pattern...

It's useful everywhere you now have more than one method starting

	if (!static::$is_initialized) static::initialize_me();

Some examples from our codebase:

- a session wrapper class, hiding $_SESSION behind setter/getter methods, 
where the static class initialization determines which cookie to use, 
depending on some global feature flags, and which session backend to use, 
depending on current availability. (main purpose, apart from clean calling 
side code just using the setters/getters, is to get the lazy_write 
functionality Yasuo tried to introduce recently)

- computation of some class properties from others, like doing an array_flip 
on one to get a reverse mapping.

- definition of computed constants, in various places. Partly obsolete now 
that class constants support constant expressions, but needed as soon as these 
are not really constant.

- setting up some class properties used by various methods, that should depend 
on some global feature flags (defined by the users of the class, usually 
toplevel scripts)

- invariant checks on subclasses, in various places, where concrete subclasses 
set up some static properties of a configuration nature, and I want to make 
sure in the base class, as early as possible, that the values are consistent 
and make sense, avoiding checks spread all over the place in various methods.

Of course, most of this could be done by code outside the class definition, in 
the same file. But that has proven, in the past, a fountain of joy wrt. 
placement, with variations needed for APC and opcache, and general frustration 
all around.

best regards
  Patrick

---

## #84616 — Johannes Ott — 2015-03-12T08:54:12+00:00

URL: https://externals.io/message/84602#84616 · In reply to: #84609

Am 12.03.2015 um 05:17 schrieb Levi Morrison:
> 
> > […]
> 
> Notably, user-land enums. You don't want public constructors because
> you don't want it instantiated except for each enum property. You also
> need it to run on class creation, not afterwards.
> 
> I think we'd be better off adding language-level enums than static
> constructors though.
> 

Yes indeed user-land enums are one of the use cases I use this feature
at the moment. But there some other use cases as well:

1. Nearly all of my classes have a static LogAdapter $LOG which has to
be intialized with Classname once.

class A {
    private static $LOG;

    public static function __static() {
        self::$LOG = LogAdapter::getLogger(self::class);
    }
} A::__static();

The LogAdapter by it selfs although have a __static() method to prepare
the Log4PHP-Framework I'm using.

2. Some Config classes which are intelligent wrapper-classes to some
ini-files and database have to read in some things first.

class Config {

    private static $ini;

    public static function __static() {
	self::$ini = parse_ini_file(...);
	// or
        // Read from Database

    }

} Config::__static();

3. For a multilanguage system I determine the user language by useragent
and fallback to default-language if user language ist not supported.

class Text {
    private static $defaultLang;

    private static $userLang;

    public static function __static() {
        self::$defaultLang = //read from Database
        self::setUserLanguageOrFallback();
    }

    private static function setUserLanguageOrFallback() {
        ...
    }
} Text::__static();

4. Already prepare some PDO-statements which needed all over the class

class Example {
   private static $stmts = [];

   public static function __static() {
	self::$stmts['select1'] = new DBSelect('SELECT * FROM table WHERE
`col1`=:clause');
   }
} Example::__static();

That are the examples I can found on a quick search over my code.

Regards,

-- 
DerOetzi

---

## #84623 — Johannes Ott — 2015-03-12T09:38:45+00:00

URL: https://externals.io/message/84602#84623 · In reply to: #84613

> 
> What about inheritance?
> I think dynamic class-constructor would make much more sense.
> A function which can analyse real class and do initialisation.
> 
> class A
> {
>     protected static function __class_construct()
>     {
>         echo `get_called_class()`.” class is defined\n";
>     }
> }
> 
> class B extends A
> {
> }
> 
> #### output ####
> A class is defined
> B class is defined
> 

I think class-constructor and static-constructor are two different
things. I even think that a inherited class-constructor is a dangerous
thing because you have huge depencies between all subclasses.

For a quick and dirty example:

abstract class A {
    protected static $value;

    protected static function __class_construct() {
        switch (get_called_class()):
           case 'B':
                self::$value = 1;
                break;
           case 'C':
                self::$value = 2;
                break;
           default:
                self::$value = 3;
    }
}

class B extends A {
    public static function isOne() {
        return self::$value == 1;
    }

}

class C extends A {
    public static function isTwo() {
        return self::$value == 2;
    }
}

That not wellformed code for three reasons:

1. Class A must know about all of it's subclasses, so you can not easily
reuse this class A in other projects because you have to refactor the
complete __class_constructor.

2. Huge dependcies between all subclasses. If you want to implement a
class D although extending class A you have to look in each other class
for sideeffects of the the changes you have todo in the
__class_construct for this class D

3. As you can see in the quick example you have a depency of class
loading order as well the result of B::isOne() and C::isTwo() depends in
which order you have loaded your classfiles. Even worst for example
You are using only class B for the beginn B::isOne() giving you true,
later  you load class C for another reason and suddenly B::isOne() gives
you false.

A static constructor however encapsulate the initialization to each
class and should only initialize private members which can be accessed
by protected getters by the subclass.

For the example:


abstract class A {
    private static $one;

    private static function __static() {
        self::$one = 1;
    }

    protected static function getOne() {
        return self::$one;
    }
}

class B extends A {
    public static function isOne() {
        return self::getOne() == 1; //Now always true
    }

}

class C extends A {
    public static function isTwo() {
        return self::getOne() == 2; //Now always false
    }
}

Regards,

-- 
DerOetzi

---

## #84628 — Crypto Compress — 2015-03-12T11:16:42+00:00

URL: https://externals.io/message/84602#84628 · In reply to: #84602

Hello Johannes,

class Foo {
     private static function __static() {
         throw new Exception("boom");
     }
}

while(true) {
     try {
         $foo = new Foo;
     } catch (Exception ex) {}
}

Would this code be valid?

---

## #84629 — Johannes Ott — 2015-03-12T11:33:23+00:00

URL: https://externals.io/message/84602#84629 · In reply to: #84628

Am 12.03.2015 um 12:16 schrieb Crypto Compress:
> Hello Johannes,
> 
> class Foo {
>     private static function __static() {
>         throw new Exception("boom");
>     }
> }
> 
> while(true) {
>     try {
>         $foo = new Foo;
>     } catch (Exception ex) {}
> }
> 
> Would this code be valid?

Have to think about this issue, but on the first look I would say yes!

Because the meaning of the static constructor is to do some necassary
initialize for the class it should be able to throw an Exception if it
cannot do it's work correctly. For example if it needs to read some
configuration from a Database and is not able to connect.

For the caller I although would say, that the error inside the static
constructor should be catchable, for the simple fact that every Error
should be catchable for user-errorhandling.

What is your point of view for this? I'm open for discussion about this.

Regards
-- 
DerOetzi

---

## #84630 — Niklas Keller — 2015-03-12T11:40:48+00:00

URL: https://externals.io/message/84602#84630 · In reply to: #84629

2015-03-12 12:33 GMT+01:00 Johannes Ott <mail@deroetzi.de>:

> Am 12.03.2015 um 12:16 schrieb Crypto Compress:
> > […]
>
> Have to think about this issue, but on the first look I would say yes!
>
> Because the meaning of the static constructor is to do some necassary
> initialize for the class it should be able to throw an Exception if it
> cannot do it's work correctly. For example if it needs to read some
> configuration from a Database and is not able to connect.
>

How would it behave for the second call? If the first initialize fails due
to some exception, should that static constructor be executed again?


> For the caller I although would say, that the error inside the static
> constructor should be catchable, for the simple fact that every Error
> should be catchable for user-errorhandling.
>
> What is your point of view for this? I'm open for discussion about this.
>
> Regards
> --
> DerOetzi
>
> --
> 
> 
>
>
Regards, Niklas

---

## #84632 — Rowan Collins — 2015-03-12T12:22:53+00:00

URL: https://externals.io/message/84602#84632 · In reply to: #84615

Patrick Schaaf wrote on 12/03/2015 08:40:
> On Thursday 12 March 2015 00:10:15 Rowan Collins wrote:
> > […]
> It's useful everywhere you now have more than one method starting
>
> 	if (!static::$is_initialized) static::initialize_me();

I suspect that most places where this occurs, there are other ways to 
eliminate it than adding magic pre-initialisation. If a class has lots 
of static methods all depending on some state being initialised, maybe 
they just shouldn't be static - they should be instance members of a 
Singleton or Dependency Injected object. Or maybe they're accessing 
members directly which would be better hidden behind an accessor method 
which loads some data and "caches" its result.


> Some examples from our codebase:
>
> - a session wrapper class, hiding $_SESSION behind setter/getter methods,
> where the static class initialization determines which cookie to use,
> depending on some global feature flags, and which session backend to use,
> depending on current availability. (main purpose, apart from clean calling
> side code just using the setters/getters, is to get the lazy_write
> functionality Yasuo tried to introduce recently)

This sounds like a job for a Singleton or Dependency-Injected object. 
The initialisation is a specific action with its own parameters (which 
you're currently grabbing from global configuration).


> - computation of some class properties from others, like doing an array_flip
> on one to get a reverse mapping.
>
> - definition of computed constants, in various places. Partly obsolete now
> that class constants support constant expressions, but needed as soon as these
> are not really constant.

This is the only case that seems valid to me: enums and other types of 
"computed constant", where the class is just there as a container.


> - invariant checks on subclasses, in various places, where concrete subclasses
> set up some static properties of a configuration nature, and I want to make
> sure in the base class, as early as possible, that the values are consistent
> and make sense, avoiding checks spread all over the place in various methods.

The question is, why is this whole hierarchy static? If these were 
instances not definitions, the initialisation is a well-defined event 
(the constructor), and you can check validity there.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #84634 — Rowan Collins — 2015-03-12T12:32:44+00:00

URL: https://externals.io/message/84602#84634 · In reply to: #84616

Johannes Ott wrote on 12/03/2015 08:54:
> Am 12.03.2015 um 05:17 schrieb Levi Morrison:
> > […]
> Yes indeed user-land enums are one of the use cases I use this feature
> at the moment. But there some other use cases as well:

Most of these examples are just crying out to be real objects, not 
static classes. You might not want to be creating them every time you 
use them, but that's what patterns like Singletons and Dependency 
Injection are for.


> 1. Nearly all of my classes have a static LogAdapter $LOG which has to
> be intialized with Classname once.
>
> class A {
>      private static $LOG;
>
>      public static function __static() {
>          self::$LOG = LogAdapter::getLogger(self::class);
>      }
> } A::__static();
>
> The LogAdapter by it selfs although have a __static() method to prepare
> the Log4PHP-Framework I'm using.

This particular example could be achieved with a static getLogger() 
method, which does the initialisation check the first time the logger is 
needed, rather than the first time class A is needed.


To my mind, the creation of a class in memory should not have 
side-effects - you should be able to assume that all your classes exist 
at the same time, before any of your code runs. The only justification 
for not acting that way would be Python-style metaclasses, where the 
creation of a class definition was the responsibility of some other 
object, and that's a power to be wielded very carefully.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #84633 — Crypto Compress — 2015-03-12T12:33:14+00:00

URL: https://externals.io/message/84602#84633 · In reply to: #84629

Am 12.03.2015 um 12:33 schrieb Johannes Ott:
> Am 12.03.2015 um 12:16 schrieb Crypto Compress:
> > […]
> Have to think about this issue, but on the first look I would say yes!
>
> Because the meaning of the static constructor is to do some necassary
> initialize for the class it should be able to throw an Exception if it
> cannot do it's work correctly. For example if it needs to read some
> configuration from a Database and is not able to connect.
>
> For the caller I although would say, that the error inside the static
> constructor should be catchable, for the simple fact that every Error
> should be catchable for user-errorhandling.
>
> What is your point of view for this? I'm open for discussion about this.
>
> Regards

If it's valid code then caching thrown exception and rethrow as 
wrapped-inner-exception on each subsequent access on Foo, seems 
feasible. I like the idea but cannot wrap my head around this.

---

## #84638 — Johannes Ott — 2015-03-12T14:51:11+00:00

URL: https://externals.io/message/84602#84638 · In reply to: #84634

> 
> Most of these examples are just crying out to be real objects, not
> static classes. You might not want to be creating them every time you
> use them, but that's what patterns like Singletons and Dependency
> Injection are for.
> 

I really disagree to this. Singletons are a typical FactoryPattern, none
of the examples except the LogAdapter itself are doing implementation of
a factory. They are just initialize some computed static variables once
in the live time of the class mostly for internal usage of the class.
That is nearly like initializing a class constant, but in my opinion a
constant should not have a "complex" algorithm (For example conditions
or read from filesystem). That should be encapsulated inside a proper
method body.

In use case 1 Dependency Injection maybe another solution but does not
exactly do what I want to do.

> 
> > […]
> 
> This particular example could be achieved with a static getLogger()
> method, which does the initialisation check the first time the logger is
> needed, rather than the first time class A is needed.
> 

yes that would be another valid pattern. And would be prefered for me if
I use the Logger in 1 or 2 out of 10 class methods, which are not used
very often. But mostly I'm using it in 9 or 10 of 10 methods, which are
invoked several times through lifetime. So doing a null check each time
is a overhead of calculation which can be avoided with this static
constructor pattern.

> 
> To my mind, the creation of a class in memory should not have
> side-effects - you should be able to assume that all your classes exist
> at the same time, before any of your code runs. 


I agree the real creation(/parsing) of the class should have no
side-effects. But the static constructor is not executed at the
creation-time of the class but directly before first access on the
class. That are two totally different moments in the lifecycle of the
class and does not block the possibility to first read all classes
without any side-effects.

> The only justification
> for not acting that way would be Python-style metaclasses, where the
> creation of a class definition was the responsibility of some other
> object, and that's a power to be wielded very carefully.
> 

The static constructor or sometimes although called class constructor is
a well known OOP-pattern implemented by different languages like C#
or Java.

Regards,

-- 
DerOetzi

---

## #84640 — Johannes Ott — 2015-03-12T15:10:28+00:00

URL: https://externals.io/message/84602#84640 · In reply to: #84630

Am 12.03.2015 um 12:40 schrieb Niklas Keller:

> 
> How would it behave for the second call? If the first initialize fails due
> to some exception, should that static constructor be executed again?
> 

I think there a two different solutions and I do not know which one I
prefer at the moment:

1. No second call can raise an fatal.

2. Yes should be executed again

As an internal implementation, we can do a flag which is at creation
time of class false and set after sucessful run of the static
constructor to true.

Do avoid deadlocks in loops like in the example maybe we can implement a
combination of both solutions. We can implement the flag not as a
boolean but as an integer counter. Raising a FATAL after X retries.

Regards,
-- 
DerOetzi

---

## #84641 — Rowan Collins — 2015-03-12T15:57:49+00:00

URL: https://externals.io/message/84602#84641 · In reply to: #84638

Johannes Ott wrote on 12/03/2015 14:51:
> That is nearly like initializing a class constant, but in my opinion a
> constant should not have a "complex" algorithm (For example conditions
> or read from filesystem). That should be encapsulated inside a proper
> method body.

I agree, but as such, I think that method should be called somewhere by 
the code, even if only by a DI container, not happen automagically and 
slurp in data from global state.

Consider your "prepare some SQL queries" example - it has a dependency 
on a database connection, so that now has to be global state; if that in 
turn is lazily initialised, it needs to get the connection string from 
yet more global state, and so on. By using the class constructor, you 
are forced to hard-code those dependencies - there's no parameters to 
pass them in, and you can't pre-initialise them from outside the class, 
because nothing on the class can run before the class constructor.


> So doing a null check each time
> is a overhead of calculation which can be avoided with this static
> constructor pattern.

Presumably the engine would need to perform some implicit equivalent of 
"if ( ! self::$initialised )" on each call to decide if the static 
constructor needs to be called or not, so the overhead is not completely 
eliminated.


> I agree the real creation(/parsing) of the class should have no
> side-effects. But the static constructor is not executed at the
> creation-time of the class but directly before first access on the
> class. That are two totally different moments in the lifecycle of the
> class and does not block the possibility to first read all classes
> without any side-effects.

OK, I misunderstood this part. So this is like the private constructor 
of a Singleton, a lazy initialisation the first time you use it. (Sorry 
to bang on about Singletons; they're what I know, so I'm trying to 
understand the similarities and differences.)


Incidentally, note that a recent RFC to add the ability to declare a 
class as static failed by 12 votes to 5 - 
https://wiki.php.net/rfc/abstract_final_class - and much of the 
discussion was around static implementations being generally inferior to 
instances, so I'm not alone in challenging designs that rely on them.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #84642 — Larry Garfield — 2015-03-12T16:28:02+00:00

URL: https://externals.io/message/84602#84642 · In reply to: #84641

> Johannes Ott wrote on 12/03/2015 14:51:
> > […]
>
> I agree, but as such, I think that method should be called somewhere by
> the code, even if only by a DI container, not happen automagically and
> slurp in data from global state.
>
> Consider your "prepare some SQL queries" example - it has a dependency
> on a database connection, so that now has to be global state; if that in
> turn is lazily initialised, it needs to get the connection string from
> yet more global state, and so on. By using the class constructor, you
> are forced to hard-code those dependencies - there's no parameters to
> pass them in, and you can't pre-initialise them from outside the class,
> because nothing on the class can run before the class constructor.
>
>
> > […]
>
> Presumably the engine would need to perform some implicit equivalent of
> "if ( ! self::$initialised )" on each call to decide if the static
> constructor needs to be called or not, so the overhead is not completely
> eliminated.
>
>
> > […]
>
> OK, I misunderstood this part. So this is like the private constructor
> of a Singleton, a lazy initialisation the first time you use it. (Sorry
> to bang on about Singletons; they're what I know, so I'm trying to
> understand the similarities and differences.)
>
>
> Incidentally, note that a recent RFC to add the ability to declare a
> class as static failed by 12 votes to 5 -
> https://wiki.php.net/rfc/abstract_final_class - and much of the
> discussion was around static implementations being generally inferior to
> instances, so I'm not alone in challenging designs that rely on them.
>
> Regards,

I thought it sounded familiar.  Also check the list archive for "A 
modest proposal: __constructStatic" from a month ago.  It was rejected 
then, too.

Really, I cannot think of any cases where I want to have a static class 
self-initialize with global data (because all statics are just globals 
with a fancy dress) where I wouldn't slap myself for being stupid and 
not just making a proper object, factory, DI, or any number of other 
options are are 10x more testable and reusable and verifiable.  Sure 
there's places you could use it; there's just much better options 
already available in the language and have been for a decade.

--Larry Garfield

---

## #84643 — Patrick Schaaf — 2015-03-12T16:36:37+00:00

URL: https://externals.io/message/84602#84643 · In reply to: #84642

Am 12.03.2015 17:28 schrieb "Larry Garfield" <larry@garfieldtech.com>:
>
> I thought it sounded familiar.  Also check the list archive for "A modest
proposal: __constructStatic" from a month ago.  It was rejected then, too.

That proposal was about a completely different issue.

But you are right, it was dismissed using the same "I don't like static,
use objects" nonargument.

best regards
  Patrick

---

## #84645 — Johannes Ott — 2015-03-12T17:05:01+00:00

URL: https://externals.io/message/84602#84645 · In reply to: #84641

Am 12.03.2015 um 16:57 schrieb Rowan Collins:
> Johannes Ott wrote on 12/03/2015 14:51:
> > […]
> 
> I agree, but as such, I think that method should be called somewhere by
> the code, even if only by a DI container, not happen automagically and
> slurp in data from global state.
> 

It is called somewhere in the code namely inside the static constructor :D

> Consider your "prepare some SQL queries" example - it has a dependency
> on a database connection, so that now has to be global state; if that in
> turn is lazily initialised, it needs to get the connection string from
> yet more global state, and so on. By using the class constructor, you
> are forced to hard-code those dependencies - there's no parameters to
> pass them in, and you can't pre-initialise them from outside the class,
> because nothing on the class can run before the class constructor.
> 

Okay that is a point each developer should be aware and decide by his self.

> > […]
> 
> Presumably the engine would need to perform some implicit equivalent of
> "if ( ! self::$initialised )" on each call to decide if the static
> constructor needs to be called or not, so the overhead is not completely
> eliminated.
> 
Yes you are right but I think it can be done more efficiently inside the
interpreter using some struct flags then have to parse each time inside
a coded part in the application.

> Incidentally, note that a recent RFC to add the ability to declare a
> class as static failed by 12 votes to 5 -
> https://wiki.php.net/rfc/abstract_final_class - and much of the
> discussion was around static implementations being generally inferior to
> instances, so I'm not alone in challenging designs that rely on them.
> 

I will check the rfc later but "static class" sounds strange.

> Regards,


Regards,
-- 
DerOetzi

---

## #84646 — Alexey Zakhlestin — 2015-03-12T17:19:22+00:00

URL: https://externals.io/message/84602#84646 · In reply to: #84642

> 
> 
> I thought it sounded familiar.  Also check the list archive for "A modest proposal: __constructStatic" from a month ago.  It was rejected then, too.
> 
> Really, I cannot think of any cases where I want to have a static class self-initialize with global data (because all statics are just globals with a fancy dress) where I wouldn't slap myself for being stupid and not just making a proper object, factory, DI, or any number of other options are are 10x more testable and reusable and verifiable.  Sure there's places you could use it; there's just much better options already available in the language and have been for a decade.

I guess it’s just “dreaming” about classes, which are first-class citizens, like in smalltalk/ruby/python :-)
But this is just an approximation, anyway.

Real class-objects probably would never happen in PHP.

-- 
Alexey Zakhlestin
https://github.com/indeyets
PGP key: http://indeyets.ru/alexey.zakhlestin.pgp.asc

---

## #84648 — Rowan Collins — 2015-03-12T17:55:52+00:00

URL: https://externals.io/message/84602#84648 · In reply to: #84645

Johannes Ott wrote on 12/03/2015 17:05:
> Am 12.03.2015 um 16:57 schrieb Rowan Collins:
> > […]
> It is called somewhere in the code namely inside the static constructor :D

What I meant is that it is not executed by any piece of code the user 
writes, but directly by the engine based on a magic hook.


> > […]
> Yes you are right but I think it can be done more efficiently inside the
> interpreter using some struct flags then have to parse each time inside
> a coded part in the application.

Yes, point taken.


> > […]
> I will check the rfc later but "static class" sounds strange.

Basically, all your examples imply classes that consist only of static 
members - they're not using static helpers to create instances, they're 
using them *instead of* instances. This was what was mean by "static 
class" in that proposal. Personally, I was in favour of that, since I 
think such classes do exist, and a syntax for declaring them would be 
useful, but the most common argument against was that we should be 
finding ways for people to not need such classes, rather than supporting 
them better. This proposal sounds like it's adding facilities to classes 
that belong on objects, or ... somewhere else.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #84649 — Patrick Schaaf — 2015-03-12T18:40:56+00:00

URL: https://externals.io/message/84602#84649 · In reply to: #84648

Am 12.03.2015 18:56 schrieb "Rowan Collins" <rowan.collins@gmail.com>:
>
> Johannes Ott wrote on 12/03/2015 17:05:
>
> > […]
>
> Yes, point taken.

I don't think such a flag is neccessary at all. Any class. at the moment,
comes from one or another file that is included / required. And all of the
code in these files outside the class definition, is then immediately
executed. The only thing neccessary would be to check, just before that
execution begins, which of the new classes have such an initializer method,
and then call that, before the execution of the file itself begins.
Incidentally that is something that cannot be emulated with the
autoloader-does-it approach, because the autoloader can only do that after
the include/require is complete - i.e. code within the file will not yet
see the class as initialized (in that approach).

(I wrote "at the moment" above,  because the currently proposed anonymous
class thing would need extra thought when the anonymous class has such an
initializer method...)

best regards
  Patrick

---

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