Say I'm releasing a code library as a separate PHP class. Then someone uses version 1.0 of this library in their application. Later I release version 2.0 of the library, and the same someone for some reason should use both 1.0 and 2.0 side by side in their application, because either he or I violated compatibility with the new version.
If the class names are different, just include and create an instance of both, because there is no name conflict. But if the class names remain the same, we run into problems:
include /lib/api-1.0/library.php; $oldlibary = new Library(); include /lib/api-2.0/library.php; $newlibrary = new Library();
This just won't work, because we cannot load two classes named Library . One alternative from another developer suggested using namespaces. The following should work:
namespace old { include /lib/api-1.0/library.php; } namespace new { include /lib/api-2.0/library.php; } $oldlibary = new old\Library(); $newlibrary = new new\Library();
Unfortunately, this is not very scalable. It will work with the situation with two instances (which, I hope, I will not need to use in the first place), but for scaling up to 3, 4, 5 or more instances you will need to have additional namespaces defined and configured. If you are not using these namespaces in the first place, this is a bunch of unnecessary code.
So, is there a way to dynamically create a namespace, include a file, and create an instance of the class contained in this file in a variable with a unique name?
Let me add a few more explanations ...
I am creating a set of libraries that will be used by other developers who create plugins / modules for several CMS platforms. Ideally, everyone will always use the latest version of my library, but I cannot guarantee this, and I cannot guarantee that the end user will always update their modules when new versions become available.
An example of the use I'm trying to work with is one where the end user installs two different modules by two different developers: name them Apple and Orange . Both modules use version 1.0 of my library, which is great. We can instantiate once, and both sets of code can take advantage of the functionality.
Later I released a small patch to this library. It is version 1.1 because it does not violate compatibility with the 1.x branch. An Apple developer immediately updates his local version and pushes a new version of his system. Developer Orange is on vacation and not worried.
When the end user updates Apple , she receives the latest release of my library. Since this is a maintenance release, it is assumed that it will completely replace version 1.0. Thus, the code only creates version 1.1 and Orange from the service patch, although the developer never bothered to update his release.
Later, I decided to update my API in order to add some Facebook hooks for some reason. New features and API extensions have a big impact on the library, so before version 2.0 I deliver it as potentially not backwards compatible in all situations. Once again, Apple enters and updates its code. Nothing broke, he just replaced my library in his /lib folder with the latest version. Orange decided to return to school to become a clown and stopped supporting his module, so he does not receive any updates.
When the end user updates Apple with the new version, it automatically receives version 2.0 of my library. But Orange had a code in its system that already added Facebook hooks, so there would be a conflict if, by default, 2.0 was loaded into its library. Therefore, instead of completely replacing it, I create an instance of 2.0 for Apple and, side by side, I create version 1.0 that ships with Orange so that it can use the correct code.
The whole point of this project is that third-party developers can create systems based on my code, regardless of being reliable and updating their code when they should. Nothing should break for the end user, and updating my library when used inside some other system should be a simple file replacement that does not go through and does not change all class references.