[PHP-DEV] [RFC] Static Constructor

Hello everybody.

I found myself wanting this feature (that I first encountered when programming in C#) for removing a workaround from a codebase I work from time to time.

I searched internals and found a discussion from almost a decade ago. That discussion did not end well, mostly because of insulting accusations.
I then decided to do some research on this subject and found out that it’s a pretty common feature in other OOP languages.
Also, as I started studying the php-src (and missed the days when I used to program in C in my main job), I decided to do an implementation myself even before presenting the RFC.
The implementation link can also be found at the RFC.

You can read the RFC here:
https://wiki.php.net/rfc/static_constructor

Regards,

Erick

Hi Erick,

śr., 19 cze 2024 o 14:35 Erick de Azevedo Lima <ericklima.comp@gmail.com> napisał(a):

Hello everybody.

I found myself wanting this feature (that I first encountered when programming in C#) for removing a workaround from a codebase I work from time to time.

I searched internals and found a discussion from almost a decade ago. That discussion did not end well, mostly because of insulting accusations.
I then decided to do some research on this subject and found out that it’s a pretty common feature in other OOP languages.
Also, as I started studying the php-src (and missed the days when I used to program in C in my main job), I decided to do an implementation myself even before presenting the RFC.
The implementation link can also be found at the RFC.

You can read the RFC here:
https://wiki.php.net/rfc/static_constructor

Regards,

Erick

I like the idea of having a static initializer.
I think we could propose a better naming, method name function __staticConstructor is a concatenation of the words static and constructor while constructor is used as an initializer when building constructing objects.
Have you considered naming it for example shortly function __static() ?
It is somehow similar to https://wiki.php.net/rfc/static_constructor#java in static-block.

Cheers,
Michał Marcin Brzuchalski

Hi, Michał.

Have you considered naming it for example shortly function __static() ?

I have considered some names, actually. I just chose this one for the implementation because
I tried to design it to be as close as possible to the C# implementation and they call it “static constructor”.
But the name can be changed to another one without any problem at all.

Regards,
Erick

On Wed, Jun 19, 2024, at 7:33 AM, Erick de Azevedo Lima wrote:

Hello everybody.

I found myself wanting this feature (that I first encountered when
programming in C#) for removing a workaround from a codebase I work
from time to time.
I searched internals and found a discussion from almost a decade ago.
That discussion did not end well, mostly because of insulting
accusations.
I then decided to do some research on this subject and found out that
it's a pretty common feature in other OOP languages.
Also, as I started studying the php-src (and missed the days when I
used to program in C in my main job), I decided to do an implementation
myself even before presenting the RFC.
The implementation link can also be found at the RFC.

You can read the RFC here:
PHP: rfc:static_constructor

Regards,

Erick

Unsurprisingly, I have concerns. :slight_smile: Perhaps surprisingly, I don't outright hate it. In particular, the examples you show are on the edge of what I'd consider valid use cases: More complex initialization of things like lookup tables or "dynamic constants" (like if you wanted to record "now" to use for later comparisons).

For that reason, therefore, I don't like the current approach, especially for this line: "Programmers have the option to call the __staticConstruct method to reset static properties values if desired."

It's screwy enough that you can explicitly call __construct(). I wouldn't want to perpetuate that weirdness. It also feels like it leaves the door open to more abuse than is tolerable. As some of the comments note, half the use cases would necessarily involve reaching out to some global state (file system, DB, etc.), which is already problematic, especially for testing.

Which also brings up another question: How would one even mock this? If I can't test it, I can't use it.

I would favor the "Java 2" style: Referencing a static method that will be called to initialize the value. That makes it clearer what is happening and encourages the intended path/use case: Lazy property initialization. It also avoids a "big blob" function in favor of small, specific functions. It also allows the author to more easily decide if they want to expose that logic to child classes for overriding: Make it private or protected, as they prefer. (Public I am fine with forbidding.)

A few other notes:

Your examples would be clearer if you leveraged the ??= operator, which would reduce your initializeMinDate() methods to a single line.

I also take issue with this paragraph:

Object-oriented languages like Java, which adhere more strictly to object-oriented principles, include static properties and offer mechanisms for their initialization with non-trivial expressions. Java uses method calls or static blocks for this purpose, as will be demonstrated later in this text, illustrating that even in environments stricter about OOP principles than PHP, static properties are sometimes useful and require appropriate initialization methods.

Not because other languages are wrong to reference; I do so very frequently, and do consider "everyone else is doing it" to be a useful (though not always winning) argument. What I object to is holding up Java as being "stricter about OO principles." OO principles are not a uniform, monolithic thing. In fact, the person who invented the term Object-Oriented has said before that C++ and Java are *not* what he had in mind. "Class based programming" is not what OOP was intended to be. OOP is about "message passing," which is often forgotten or misunderstood or ignored. Also, my day job is now working in Kotlin, which means I am faced with a lot of Java code I have to interact with. To be polite, holding up "Java style" design as anything to emulate is... a categorical error.

Referencing other languages is fine, do that (and I appreciate that you did; I didn't realize this was so common a feature, and that does help make me amenable to it), but please do not in any way suggest that Java is the definition of "good and proper OOP." It is extremely not.

I'm still not sold on the idea, but... I think I could be, which is more than I expected from the title.

--Larry Garfield

On Jun 19, 2024, at 8:33 AM, Erick de Azevedo Lima <ericklima.comp@gmail.com> wrote:

Hello everybody.

I found myself wanting this feature (that I first encountered when programming in C#) for removing a workaround from a codebase I work from time to time.
I searched internals and found a discussion from almost a decade ago. That discussion did not end well, mostly because of insulting accusations.
I then decided to do some research on this subject and found out that it’s a pretty common feature in other OOP languages.
Also, as I started studying the php-src (and missed the days when I used to program in C in my main job), I decided to do an implementation myself even before presenting the RFC.
The implementation link can also be found at the RFC.

You can read the RFC here:
https://wiki.php.net/rfc/static_constructor

Regards,

Erick

  1. I noticed you did not include an example for Go so I wrote one up for you in a Go playground. Hopefully you can include Go’s approach in your RFC?

https://goplay.tools/snippet/6lvAQdye9P9

  1. Also, in the past I made frequent use of “on_load()” methods that I would call immediately after the class code. I always wanted a static initializer — and even discussed it with Ben Ramsay at an after-event for Atlanta PHP meetup years ago — but I never proposed in as an RFC and cannot remember if I ever discussed here on the list.

Even though I no longer actively use or maintain the following library I wanted to provide you with links for each of the different use-case where I had an on_load() method and would have used a static initializer had it been available in hopes they may inspire you to enhance your RFC with new use-cases. I am also sharing for others to see the different use-cases:

  1. One thing about “best practices” for static initializers. When using a package-level variable in Go initializations and for those PHP static classes with on_load() methods I found it problematic to add anything that could fail in a reasonable use-case, and I would recommend that this would become the advice given as a best practice for using static initializers.

In my PHP examples above I do happen to assume the database is open and exists but only because the library is for use with WordPress as a must-load plugin, and if the database is not available my plugin will never get loaded.

In Go I never use database access code or remote API calls, or anything that could generate an error. I instead create “initialize” methods and call them explicitly in main() or some other func that main() calls.

In PHP you can have a syntax error at runtime, but in that case it will error as soon as you try to autoload the PHP file so I do not think syntax errors should be real concern here, only runtime errors.

  1. To elaborate more about “best practices” where I see static initializers being especially valuable it when you want to initialize immutable data, and especially when that data is in complex form such as an object vs. just a simple value. Here is one such example of this which initializes the default labels for a WordPress post-type: https://github.com/wplib/wplib/blob/master/modules/posts/posts.php#L54-L64

  2. Another use-case is registering “hooks” defined by a framework, such as the wp_loaded hook in WordPress: https://github.com/wplib/wplib/blob/master/modules/posts/posts.php#L68C28-L68C37

  3. Yes another use-case would be to make a framework more robust and to provide guidance to a user for what they are doing wrong. Here I am actually throwing an error when the it is clear the classes are being initialized out-of-order: https://github.com/wplib/wplib/blob/master/wplib.php#L157

  4. Still another is loading related .PHP files that are required so as not to have to rely on the autoloader.
    https://github.com/wplib/wplib/blob/master/wplib.php#L167.

Here I would also suggest guidance about not including any code that can fail at load time during the normal course of execution meaning syntax errors are okay but the loaded code should really never generate a runtime errors.

  1. A big use-case too is allowing static classes to register themselves as being able to provide a service to another class defined by the application or framework. This allows a class to self-describe its behavior and capabilities such as how my library allows the registration of the class as a “Helper” for the main class and how it allows registering a class as representing a “Role” in the framework: https://github.com/wplib/wplib/blob/master/modules/posts/posts.php#L48 https://github.com/wplib/wplib/blob/master/modules/role-administrator/role-administrator.php#L37

This is much like how a pub-sub system allows others to subscribe to the publisher and the publisher does not need to know in advance all the subscribers to the system.

  1. Regarding Larry’s concern for test mocking, if the only things that static initialize functions are doing is initializing immutable data, registering hooks, pre-loading non-error generating .PHP files, and/or registering classes for special use-cases then there is #fyi (little or?) no need to mock them for testing purposes.

For developers following said guidance I do not see static initializers as creating a challenge for testing.

-Mike

P.S. I think it would be great if static initializers threw a runtime error if they attempted to do anything that could throw an error — at least not without a try-catch to absorb the error — but as I cannot envision how that would be possible and still be acceptably performant I think the only approach should be provide the community with guidance on how and how not to use static initializers. #fwiw

Hi

On 6/19/24 16:03, Erick de Azevedo Lima wrote:

I have considered some names, actually. I just chose this one for the
implementation because
I tried to design it to be as close as possible to the C# implementation
and they call it "static constructor".
But the name can be changed to another one without any problem at all.

I would suggest `__constructStatic()`. This matches the existing naming pattern of `__callStatic()` being the companion to `__call()`.

Best regards
Tim Düsterhus

Hi Erick

On Wed, Jun 19, 2024 at 2:34 PM Erick de Azevedo Lima
<ericklima.comp@gmail.com> wrote:

You can read the RFC here:
PHP: rfc:static_constructor

I see that you're using zend_class_init_statics() as a hook to call
__static_construct(). This makes the initialization order
unpredictable, because static properties are initialized lazily when
the class is first used (when instantiated, when accessing constants,
etc.). Essentially, this recreates the same problem described in the
"new in initializer" RFC:

https://wiki.php.net/rfc/new_in_initializers#unsupported_positions

New expressions continue to not be supported in (static and non-static) property initializers and class constant initializers. The reasons for this are twofold:
[snip]
For static property initializers and class constant initializers a different evaluation order issue arises. Currently, these initializers are evaluated lazily the first time a class is used in a certain way (e.g. instantiated). Once initializers can contain potentially side-effecting expressions, it would be preferable to have a more well-defined evaluation order. However, the straightforward approach of evaluating initilizers when the class is declared would break certain existing code patterns. In particular, referencing a class that is declared later in the same file would no longer work.

Lazy evaluation might be ok if order is clearly defined. Making the
order undefined makes it hard (or impossible) to understand which
symbols declared in the current file may be used from
__static_construct(). The alternative mentioned above (calling
__static_construct() at class-declaration-time) likely breaks too much
existing code (because it would also require calling static
initializers just before that, which may reference symbols declared
later on), and is further complicated by early-binding. I'm not sure
what the best approach is here.

Ilija

On Jun 19, 2024, at 2:36 PM, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

On Wed, Jun 19, 2024 at 2:34 PM Erick de Azevedo Lima
<ericklima.comp@gmail.com> wrote:

New expressions continue to not be supported in (static and non-static) property initializers and class constant initializers. The reasons for this are twofold:
[snip]
For static property initializers and class constant initializers a different evaluation order issue arises. Currently, these initializers are evaluated lazily the first time a class is used in a certain way (e.g. instantiated). Once initializers can contain potentially side-effecting expressions, it would be preferable to have a more well-defined evaluation order. However, the straightforward approach of evaluating initilizers when the class is declared would break certain existing code patterns. In particular, referencing a class that is declared later in the same file would no longer work.

Lazy evaluation might be ok if order is clearly defined.

Consider that some uses for a static function need to always occur no matter whether or not any other method of the class is called. My previous email [1] covered several.

Here [2] is a discussion on StackOverflow of “hooks” that should be eagerly loaded.

Thus I think it important that if lazy evaluation is used for static initializers then it should be an option, and ideally one that is opt-in vs. opt-out, e.g.:

class Foo {
private static lazy function __staticConstruct():void {
// Do initialization stuff here
}

}

-Mike
[1] https://externals.io/message/123675#123684
[2] https://stackoverflow.com/a/2400206/102699

On Wed, Jun 19, 2024 at 11:57 PM Mike Schinkel <mike@newclarity.net> wrote:

On Jun 19, 2024, at 2:36 PM, Ilija Tovilo <tovilo.ilija@gmail.com> wrote:

On Wed, Jun 19, 2024 at 2:34 PM Erick de Azevedo Lima
<ericklima.comp@gmail.com> wrote:

New expressions continue to not be supported in (static and non-static) property initializers and class constant initializers. The reasons for this are twofold:
[snip]
For static property initializers and class constant initializers a different evaluation order issue arises. Currently, these initializers are evaluated lazily the first time a class is used in a certain way (e.g. instantiated). Once initializers can contain potentially side-effecting expressions, it would be preferable to have a more well-defined evaluation order. However, the straightforward approach of evaluating initilizers when the class is declared would break certain existing code patterns. In particular, referencing a class that is declared later in the same file would no longer work.

Lazy evaluation might be ok if order is clearly defined.

Consider that some uses for a static function need to always occur no matter whether or not any other method of the class is called. My previous email [1] covered several.

Here [2] is a discussion on StackOverflow of “hooks” that should be eagerly loaded.

Thus I think it important that if lazy evaluation is used for static initializers then it should be an option, and ideally one that is opt-in vs. opt-out, e.g.:

class Foo {
private static lazy function __staticConstruct():void {
// Do initialization stuff here
}

}

-Mike
[1] https://externals.io/message/123675#123684
[2] https://stackoverflow.com/a/2400206/102699

Seeing an extra keyword made me think of:

class Foo
{
public constructor __construct() {}
public destructor __destruct() {}
public static constructor __construct() {}
public static destructor __destruct() {} // probably doesn't make sense right now
}

This syntax would allow named constructors in the future, or even omitting the default name.


class Foo
{
public constructor() {}
public destructor() {}

public constructor create(int $id)
{
$this->id = $id; // no need to call the default __construct, nor needs to return
}
}

Not sure if this is even a desired path to take, just wanted to throw the idea out there.

Hi all.

Answering to Larry:

More complex initialization of things like lookup tables or “dynamic constants” (like if you wanted to record “now” to use for later comparisons).
Those are my use cases, to be honest.

For that reason, therefore, I don’t like the current approach, especially for this line: “Programmers have the option to call the __staticConstruct method to reset static properties values if desired.”

I just laughed at myself when I read this. As I said, my main inspiration was the C# implementation and there, the static constructor can only be called by the engine.
And that was my intention, but then I remembered that the “__construct” method can be called on an already constructed object and I implemented it this way.
If it’s a consensus to remove it, I’ll gladly do it. :slight_smile:

Your examples would be clearer if you leveraged the ??= operator, which would reduce your initializeMinDate() methods to a single line.
Yes, it’s true. As a former teaching assistant, I tend to give examples that might be longer than necessary, with the intention of being as clear as possible.
In this case, it was to emphasize the fact that we must implement a logic to check (the “if” at the beginning of the method) if the property was already initialized.

What I object to is holding up Java as being “stricter about OO principles.” OO principles are not a uniform, monolithic thing.
In fact, the person who invented the term Object-Oriented has said before that C++ and Java are not what he had in mind.
“Class based programming” is not what OOP was intended to be.

To be honest, when I wrote this part, I was indeed thinking about “class based” programming.
And Java is stricter than PHP and C++ in this sense: It does not have loose functions, everything must be inside a class.
And even though “Class based programming” is not what OOP was intended to be, it’s what’s mostly found out there: OOP = Class based programming
But my main point here is to show that this feature is often provided because it’s proven to be useful for programmers of multiple programming languages.

Answering to Mike:

I noticed you did not include an example for Go so I wrote one up for you in a Go playground. Hopefully you can include Go’s approach in your RFC?
No, I’m not familiar enough with Go to provide examples, so I did not consider it. As you provided the example, I’ll gladly include it. Thank you!

To elaborate more about “best practices” where I see static initializers being especially valuable it when you want to initialize immutable data,
and especially when that data is in complex form such as an object vs. just a simple value.

Yes, I think that’s “the” use case.

Tim:

I would suggest __constructStatic(). This matches the existing naming
pattern of __callStatic() being the companion to __call().
Noted. I’m not really attached to any name and your point makes a lot of sense.

Ilija:

I see that you’re using zend_class_init_statics() as a hook to call __static_construct().
Yes, I thought that lazy initialization would cover most of the use-cases for initializing static variables, so that seemed the best place to do it.

This makes the initialization order
unpredictable, because static properties are initialized lazily when
the class is first used (when instantiated, when accessing constants, etc.).
From my tests, the static variables initialization is even lazier: The “zend_class_init_statics” is only called when you try to access a static variable.
See this example:

class C1
{
private static \DateTimeInterface $v1;

public function __construct()
{
echo METHOD . PHP_EOL;
}

private static function __staticConstruct()
{
self::$v1 = new \DateTimeImmutable(‘2024-06-19 00:00:00’);
echo 'calling ’ . METHOD . PHP_EOL;
echo C2::USING_SYMBOL_DECLARED_LATER . PHP_EOL;
}

public static function getV1()
{
echo ‘Before accessing C1::$v1 variable’ . PHP_EOL;

return self::$v1;
}
}

class C2
{
public const USING_SYMBOL_DECLARED_LATER = ‘C2::USING_SYMBOL_DECLARED_LATER’;
}

$obj1 = new C1(); //should not trigger zend_class_init_statics()

echo C1::getV1()->format(‘Y-m-d’) . PHP_EOL; //

This example prints:

C1::__construct
Before accessing C1::$v1 variable
calling C1::__staticConstruct
C2::USING_SYMBOL_DECLARED_LATER
2024-06-19

Lazy evaluation might be ok if order is clearly defined. Making the
order undefined makes it hard (or impossible) to understand which
symbols declared in the current file may be used from __static_construct()

Can you provide an example for that? I’m not sure if I understood everything correctly.

… is further complicated by early-binding. I’m not sure what the best approach is here.

One of my first thoughts was to perform this at the end of class linking (on function zend_do_link_class()),
but then I came to a conclusion that performing it during the already existing lazy init would cover most use cases.

Mike again:

Consider that some uses for a static function need to always occur no matter
whether or not any other method of the class is called. My previous email [1] covered several.

Here [2] is a discussion on StackOverflow of “hooks” that should be eagerly loaded.

Yes, I considered this approach before. But then I realized that for covering the properties initialization,

this already existing lazy loading mechanism would suffice. At the end of the RFC,
I consider future scope to create an early-init. In my opinion, as it covers a more general use for this init,
it should be implemented maybe using another magic method, like “__load” or “__link”,
which would be hooks on class loading process and not specific to static variables initialization

Lynn:

Not sure if this is even a desired path to take, just wanted to throw the idea out there.
Looking at the idea, I like the new “method modifiers”. But it would be a much bigger scope to tackle right now.

Best regards,
Erick

Hi Erick,

It would be useful to include the example of Singleton implementation with a static constructor.

Kind regards,

Jorg

On Jun 20, 2024, at 9:01 AM, Erick de Azevedo Lima <ericklima.comp@gmail.com> wrot

Mike again:

Consider that some uses for a static function need to always occur no matter
whether or not any other method of the class is called. My previous email [1] covered several.

Here [2] is a discussion on StackOverflow of “hooks” that should be eagerly loaded.

Yes, I considered this approach before. But then I realized that for covering the properties initialization,

this already existing lazy loading mechanism would suffice. At the end of the RFC,
I consider future scope to create an early-init. In my opinion, as it covers a more general use for this init,
it should be implemented maybe using another magic method, like “__load” or “__link”,
which would be hooks on class loading process and not specific to static variables initialization

Well, that sure is depressing to hear.

Looking back on all my uses for static methods, my primary use-case when building WordPress websites was to wire up hooks thus what excited me most about the prospect of getting “static constructors” in PHP was for wiring up said hooks.

I get the lack of desire to support a lazy keyword, especially giving the lazy loading thread happening on the list, and I agree that lazy loading is better for the use-cases that motivated you, but it is depressing because the likelihood of someone else after so many years would have the passion and motivation to propose a __load method AND to have the skills to implement it is slim-to-none IMO.

So IOW, a __load method it’s almost certainly never going to happen. Such is life I guess.

Well at least let me submit a parting bikeshed on the name. Rather than any form of “construct” can you at least name it __init or __initialize? It is not construction, and even in your comment where you wrote unprompted “…not specific to static variables initialization” you christened it to be “initialization.”

P.S. I do think lazy-loading without an explicit keyword will be counter-intuitive to many, and will result in many a StackOverflow question asking “Why are my __staticConstruct (or __init as proposed) methods not being called?!?” So if it were me I would implement them w/o default lazy loading so there would be motivation in the future to address it another way.

That, or go ahead and also propose a __load method as part of this RFC.

On Jun 20, 2024, at 4:57 AM, Lynn <kjarli@gmail.com> wrote:

Seeing an extra keyword made me think of:

class Foo
{
public constructor __construct() {}
public destructor __destruct() {}
public static constructor __construct() {}
public static destructor __destruct() {} // probably doesn't make sense right now
}

This syntax would allow named constructors in the future, or even omitting the default name.


class Foo
{
public constructor() {}
public destructor() {}

public constructor create(int $id)
{
$this->id = $id; // no need to call the default __construct, nor needs to return
}
}

Not sure if this is even a desired path to take, just wanted to throw the idea out there.

I do like the constructor/destructor vs. function naming, but as I wrote above I think “__init” — and for your approach Lynn: “initializer” — would be more applicable for static classes methods, with or without an explicit prefixed static keyword.

#fwiw

-Mike

On 19/06/2024 13:33, Erick de Azevedo Lima wrote:

I searched internals and found a discussion from almost a decade ago. That discussion did not end well, mostly because of insulting accusations.

If you're talking about the March/April 2015 thread, I don't think that's a fair summary. There were some slightly ill-mannered comments about the use cases, but mostly even those instinctively against were willing to discuss the details of the proposal.

The discussion ended not because of any bad feelings, but because the person proposing it had to put it on pause because of things happening in their personal life, and evidently did not pick it back up again: New RFC draft "static class constructor" - Externals

- Initial thread: static constructor - Externals
- RFC draft thread: New RFC draft "static class constructor" - Externals
- RFC draft: PHP: rfc:static_class_constructor

Digging through the archives, I actually found some even older threads, though none of them seems to have reached a full proposal:

- 2004 - Static Constructors - Externals
- 2010 - Static initialization block support in Class? - Externals
- 2013 - __init magic method - Externals

So, there's definitely desire out there, but also some challenges. A few things look to have come up again and again (other than whether the use cases are justified):

- Naming (yay bikeshedding!)
- Whether it should be declared the same way as other magic methods, or have special rules (e.g. different syntax, private even though it's called by the engine, error if you explicitly call it)
- Exactly when it should run (on class load? on first access?). (Like Ilija, I was also reminded of Nikita's comments on the "new in initializers" RFC, which touch on this point)
- Concerns about implementation details and interaction with other features

Personally, I'm on the fence. I've never had a particular desire for it myself, and worry that it would be hard to understand or debug exactly when it was triggered, but can see there is both a desire and a precedent.

Regards,

--
Rowan Tommins
[IMSoP]

On 19/06/2024 19:25, Tim Düsterhus wrote:

Hi

On 6/19/24 16:03, Erick de Azevedo Lima wrote:

I have considered some names, actually. I just chose this one for the
implementation because
I tried to design it to be as close as possible to the C# implementation
and they call it "static constructor".
But the name can be changed to another one without any problem at all.

I would suggest `__constructStatic()`. This matches the existing naming pattern of `__callStatic()` being the companion to `__call()`.

Best regards
Tim Düsterhus

Why can't it just be `public static function __construct()`?

Cheers,
Bilge

On 2024-08-28 09:51, Bilge wrote:

On 19/06/2024 19:25, Tim Düsterhus wrote:

Hi

On 6/19/24 16:03, Erick de Azevedo Lima wrote:

I have considered some names, actually. I just chose this one for the
implementation because
I tried to design it to be as close as possible to the C# implementation
and they call it "static constructor".
But the name can be changed to another one without any problem at all.

I would suggest `__constructStatic()`. This matches the existing naming pattern of `__callStatic()` being the companion to `__call()`.

Best regards
Tim Düsterhus

Why can't it just be `public static function __construct()`?

Cheers,
Bilge

Two functions with the same name in the same class?

Hello, everyone.

I’m sorry for not being active for a time on the internals, including about this RFC of mine.

I just had a huge house-related problem and recently also health problems with my family.
So, I’ll have to stay away for some time. But I’ll go ahead with the talks about this RFC as soon as possible.

Thank you!


Erick