Let\'s say I release a code library as a standalone PHP class. Someone then uses version 1.0 of that library in their application. Later, I release version 2.0 of the libr
Let the user select a version, then according to that load your api file
The file name should be dynamically determinable, for example:
include('/lib/api-'.$versionId.'/library.php');
if version -1.0 as wise
Be careful to ensure that the user input is converted into a single decimal float
and nothing nefarious.
I decided on a slightly alternate route. The namespace method works, but you need a different namespace for each version of the class. So it's not really scalable, because you have to pre-define the number of available namespaces.
Instead, I've settled on a specific naming schema for the classes and a version loader/instantiater.
Each class will take the following format:
<?php
if( ! class_exists( 'My_Library' ) ) { class My_Library { } }
if( ! class_exists( 'My_Library_1_0' ) ) :
class My_Library_1_0 extends My_Library {
... class stuff ...
}
endif;
The parent My_Library
class will actually end up containing a few identifiers specific to the library - purpose, compatibility statements, etc. That way I can perform other logical checks to make sure the right My_Library
exists before moving forward and claiming that My_Library_1_0
is really version 1.0 of the library I want.
Next, I have a loader class that I'll be using in my main project:
<?php
class Loader {
static function load( $file, $class, $version ) {
include( $file );
$versionparts = explode('.', $version);
foreach($versionparts as $part) $class .= '_' . $part;
return new $class();
}
}
Once this is done, you can use Loader
to load both instances of the class or simple references if you want to use static methods:
$reference = Loader::load( 'library.php', 'My_Library', '1.0' );
$loader = new Loader();
$instance = $loader->load( 'library.php', 'My_Library', '1.0' );
Not quite the same as the namespace version I was shooting for, but it works and alleviates my concerns about breaking things for the end user. I am assuming that two different versions of My_Library_1_0
would be the same, though ... so there's still a dependence on third party developers knowing what they're doing.
So is there a way to dynamically create a namespace, include a file, and instantiate the class contained within that file in a uniquely-named variable?
Yes, such method exists. You can do anything you want with eval and stream handlers. But it is bad practice and wrong approach - you can try to use factory method (the code is not tested - it only shows example):
<?php
if (!class_exists('Library')) {
class Library
{
public static function create($version)
{
if (class_exists($c = 'Library' . $version))
return new $c();
return null;
}
}
}
class Library1
{
}
class Library2
{
}
...