# A quick consensus on magic method idea

- Thread: https://externals.io/message/51425
- Original archive: https://news-web.php.net/php.internals/51425
- Started by Chris Stockton on 2011-02-04T04:30:38+00:00
- Messages: 7
- 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

---

## #51425 — Chris Stockton — 2011-02-04T04:30:38+00:00

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

Hello,

I haven't seen a magic method proposed in a while so I am not sure how
people feel about them, obviously adding them can break BC (although
it is recommended people should not use __). I'm sure a good amount of
use/desire needs to be shown for inclusion. Here is what I decided I
would like to have and just implemented:

Loader.php:
--
class Loader {
  static public function __compiled() {
    echo "I was ran at the end of zend_do_end_class_declaration";
  }
}

Run script:
<?php
include "Loader.php";

Prints:
I was ran at the end of zend_do_end_class_declaration

At first thought I figured this would be pretty simple to implement,
which it is.. for a basic use case. It seems I will need a bit more
work to handle issues when you do certain things inside __compiled. If
anyone has any interest I would fix it and make a clean patch, so
would anyone find this useful?

-Chris

---

## #51426 — Ben Schmidt — 2011-02-04T04:38:53+00:00

URL: https://externals.io/message/51425#51426 · In reply to: #51425

> Hello,
>
> I haven't seen a magic method proposed in a while so I am not sure how
> people feel about them, obviously adding them can break BC (although
> it is recommended people should not use __). I'm sure a good amount of
> use/desire needs to be shown for inclusion. Here is what I decided I
> would like to have and just implemented:
>
> Loader.php:
> --
> class Loader {
>    static public function __compiled() {
>      echo "I was ran at the end of zend_do_end_class_declaration";
>    }
> }
>
> Run script:
> <?php
> include "Loader.php";
>
> Prints:
> I was ran at the end of zend_do_end_class_declaration
>
> At first thought I figured this would be pretty simple to implement,
> which it is.. for a basic use case. It seems I will need a bit more
> work to handle issues when you do certain things inside __compiled. If
> anyone has any interest I would fix it and make a clean patch, so
> would anyone find this useful?

Do you yourself have any situation where this is useful? Does it solve
some problem? Does it enable you to do things better than before?

Ben.

---

## #51427 — Chris Stockton — 2011-02-04T04:49:28+00:00

URL: https://externals.io/message/51425#51427 · In reply to: #51426

Hello,

On Thu, Feb 3, 2011 at 8:38 PM, Ben Schmidt
<mail_ben_schmidt@yahoo.com.au> wrote:
>
> Do you yourself have any situation where this is useful? Does it solve
> some problem? Does it enable you to do things better than before?
>
> Ben.
>

It does not provide a solution to a currently unsolvable problem, it
is simply a convenience for situations when you want a class to
perform any kind of initialization directly after compilation/loading
(whatever term you find easier on the ears).

It provides a cleaner more encapsulated approach to a (not entirely
uncommon) case such as:

Foo.php:
class Foo {
  // class body
}

Foo::registerSomeStuff();


Just a idea I wanted to share,

-Chris

---

## #51428 — Rasmus Lerdorf — 2011-02-04T04:53:11+00:00

URL: https://externals.io/message/51425#51428 · In reply to: #51427

> Hello,
> 
> On Thu, Feb 3, 2011 at 8:38 PM, Ben Schmidt
> <mail_ben_schmidt@yahoo.com.au> wrote:
> > […]
> 
> It does not provide a solution to a currently unsolvable problem, it
> is simply a convenience for situations when you want a class to
> perform any kind of initialization directly after compilation/loading
> (whatever term you find easier on the ears).

This creates problems for opcode caches since the classes are all
precompiled and usually optimized to the point where the opcodes that
loads them are NOP'ed away and you just have the full class table cached
in memory for each op_array.  Walking through that class table on every
request and looking for these magic methods to call would be quite
annoying, especially since most of them wouldn't have such a method to
begin with.

-Rasmus

---

## #51429 — Chris Stockton — 2011-02-04T05:06:00+00:00

URL: https://externals.io/message/51425#51429 · In reply to: #51428

Hello,


>
> This creates problems for opcode caches since the classes are all
> precompiled and usually optimized to the point where the opcodes that
> loads them are NOP'ed away and you just have the full class table cached
> in memory for each op_array.  Walking through that class table on every
> request and looking for these magic methods to call would be quite
> annoying, especially since most of them wouldn't have such a method to
> begin with.
>

That is a good point and something I didn't think about. The pain that
would create immediately negates the small luxury it would add.

Thanks,

-Chris

---

## #51430 — Benjamin Eberlei — 2011-02-04T08:13:09+00:00

URL: https://externals.io/message/51425#51430 · In reply to: #51429

Couldn't you just write an autoloader that triggers this method if
available on any class autoloaded? This obviously only works if you are
using the one class in one file approach, but would be just as powerful
then.

On Thu, 3 Feb 2011 21:06:00 -0800, Chris Stockton
<chrisstocktonaz@gmail.com> wrote:
> Hello,
> 
> On Thu, Feb 3, 2011 at 8:53 PM, Rasmus Lerdorf <rasmus@lerdorf.com>
wrote:
> > […]
cached
> > […]
> 
> That is a good point and something I didn't think about. The pain that
> would create immediately negates the small luxury it would add.
> 
> Thanks,
> 
> -Chris

---

## #51431 — Stan Vass — 2011-02-07T15:39:26+00:00

URL: https://externals.io/message/51425#51431 · In reply to: #51428

> This creates problems for opcode caches since the classes are all
> precompiled and usually optimized to the point where the opcodes that
> loads them are NOP'ed away and you just have the full class table cached
> in memory for each op_array.  Walking through that class table on every
> request and looking for these magic methods to call would be quite
> annoying, especially since most of them wouldn't have such a method to
> begin with.
>
> -Rasmus
>

As a class is added to the table (on first execute of the opcodes) it can 
check at that point if the magic method exists, and put it in a separate 
compact list to call for every request. Walking all classes repeatedly is 
thus avoided.

However, a remaining problem is the user no longer controls when exactly are 
his classes initialized, and in what concrete order. We have the potential 
for race conditions, where classes B, and C rely on initialized class A, or 
on some other initialization routine called in userland, which has not been 
executed yet, producing "sometimes broken" code that's hard to debug.

Stan Vass
