Loading multiple versions of the same class

白昼怎懂夜的黑 提交于 2019-11-29 07:19:35

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
{

}

...
Roshan Wijesena

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!