Loading multiple versions of the same class

前端 未结 3 1633
一整个雨季
一整个雨季 2020-12-17 01:05

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

相关标签:
3条回答
  • 2020-12-17 01:33

    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.

    0 讨论(0)
  • 2020-12-17 01:38

    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.

    0 讨论(0)
  • 2020-12-17 01:44

    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
    {
    
    }
    
    ...
    
    0 讨论(0)
提交回复
热议问题