Hi, Alex and Rowan! > I think this is actually the biggest challenge: what happens when objects are > passed between containers? > > To use the previous example: as an initialisation step, the WordPress plugin > might want to set up an API client inside its container; later, it might want > to make use of that API client, plus an object passed to it by a WordPress > hook. > > The containers are inside the same thread, so in principle there's no problem > referencing object handles which are "owned by" a different container. But > what is the type of those objects? How do they respond to get_class(), > instanceof, etc? > > Perhaps there are things we can learn from other languages like Java's > "isolated ClassLoader" which I mentioned on another thread? > https://www.javathinking.com/blog/what-is-an-isolated-classloader-in-java/
I actually really like the idea of some sort of "containers" in general, because it is quite a common problem in my practice when we have a more-or-less big monolithic app and eventually come to conflicting dependencies. As for passing objects between containers, it does not seem like an unsolvable problem. Even though our thoughts are very abstract for now, generally speaking there could be some matching of objects in inter-container usage. Like, if "my" container is now using \My\Namespace\SomeObject from my dependencies (let it be, say, myvendor/mylib: 1.0), when receiving such an object from another container, it could be known what exact dependency it is from. And if it is also myvendor/mylib: 1.0 - there should be no problems. If versions don't match, there could be some explicit inter-dependency mapping defined by the user, or an explicit runtime error if no mapping was provided. Such an inter-container mapping mechanism would require careful designing of course, but technically it does not look unsolvable. Generally speaking, we could have the mentioned \My\Namespace\SomeObject loaded both from v1.0 and say v1.1 so we could map one to another on the calling side. Here comes the quirk that PHP itself is not aware about the composer and its structure. But PHP can always know where exactly a specific class was sourced from, so we could use it as a distinguisher. I bet distinguishing by filename would be a very bad design though. But if PHP allowed to somehow "tag" loaded classes, it would be handy for containers AND composer. Like, when "starting" a new container, the only thing we need to provide is a class-loader, which would presumably "tag" the loaded classes in a known manner. In the case of composer, it could tag them by version. In our code, we could import all needed classes with some advanced syntax with specifying the "tag". As an example from the top of my head: use \My\Namespace\SomeObject tagged "..." [as SomeObjectV1], explicitly telling which version we need. And we could have both versions imported this way (and map one to another, accordingly). Autoload will receive this "tag" (if provided) and load a corresponding class. The power of containers would come with carefully designed defaults for these class versions when no version was explicitly stated (but container-based autoloader already knows where it is rooted from). These are still very rough thoughts though, but with deeper thinking, I believe it can evolve what Alex and you are suggesting. Regards, Alexander Egorov.
