[Release] PHP 5.4+ Simple dependecy injection

Results 1 to 1 of 1
  1. #1
    Digital Horizon KristiansJ is offline
    MemberRank
    Jul 2012 Join Date
    203Posts

    [Release] PHP 5.4+ Simple dependecy injection

    Maybe some one will find this DI example useful...

    KernelObject.php (DI Class)
    PHP Code:
    namespace System\Kernel
    {
        class 
    KernelObject
        
    {
            
    /**
             * Main dependency container.
             *
             * Contains all loaded components including private and public
             *
             *   [MENTION=1333430648]Var[/MENTION] array
             */
            
    public static $KernelObject NULL;

            
    /**
             * Check if component is loaded
             *
             *   [MENTION=1333357818]param[/MENTION] string $name
             *
             *   [MENTION=850422]return[/MENTION] bool
             */
            
    public static function has($name)
            {
                return isset(
    self::$KernelObject[$name]);
            }

            
    /**
             * Loads new components instance
             *
             *   [MENTION=1333357818]param[/MENTION] string $name
             *   [MENTION=1333357818]param[/MENTION] object $class
             */
            
    private static function add($name$class)
            {
                
    self::$KernelObject[$name] = $class;
            }

            
    /**
             * Returns component class reference
             *
             *   [MENTION=1333357818]param[/MENTION] string $name Class short name
             *
             *   [MENTION=850422]return[/MENTION] mixed
             */
            
    public static function ref($name)
            {
                return 
    self::$KernelObject[$name];
            }

            public static function 
    create($type$name$localObject true)
            {
                
    /*
                 * Check if object is already loaded and is requested as localObject.
                 */
                
    if(self::has($name) AND $localObject true)
                {
                    return 
    self::ref($name);
                }

                
    $ObjectReference NULL;

                
    /*
                 * Object Reference Resolving
                 */
                
    if($localObject == true)
                {
                    
    $ObjectReference = & self::$KernelObject[$name];
                }

                
    $Configuration configStore($type);

                
    /*
                 * Check if component exists
                 */
                
    if(isset($Configuration[$type][$name]))
                {
                    
    $config     $Configuration[$type][$name];
                    
    $Reflection = new \ReflectionClass($config['Class']);
                    
    /*
                     * Create actual object
                     */
                    
    $ObjectReference =
                        
    $Reflection->newInstanceArgs((isset($config['Arguments']) ? $config['Arguments'] : array()));
                    
    /*
                     * Inject object required packages
                     */
                    
    if(isset($config['Packages']))
                    {
                        if(
    $Reflection->isSubclassOf('KernelContainer'))
                        {
                            if(
    is_array($config['Packages']))
                            {
                                foreach(
    $config['Packages'] as $packageName)
                                {
                                    
    $Package configStore('Components')['Packages'][$packageName];
                                    
    /*
                                     * Check if package exists and is configured correctly
                                     */
                                    
    if(isset($Package) AND is_array($Package))
                                    {
                                        foreach(
    $Package as $package_items)
                                        {
                                            if(
    $package_items[0] == $name)
                                            {
                                                continue;
                                            }

                                            
    $PackageComponentName        $package_items[0];
                                            
    $PackageComponentPrivateName = (isset($package_items[1])) ? $package_items[1] : NULL;
                                            
    $PackageComponent            configStore('Components')['Components'][$PackageComponentName];

                                            if(isset(
    $PackageComponent['Visibility']) AND $PackageComponent['Visibility'] !== NULL)
                                            {
                                                if(isset(
    $PackageComponentPrivateName) == true AND $PackageComponent['Visibility'] == 'Public')
                                                {
                                                    throw new \
    KernelException("{$PackageComponentName} cannot be requested as private component!");
                                                }

                                                if(isset(
    $PackageComponentPrivateName) == false AND $PackageComponent['Visibility'] == 'Private')
                                                {
                                                    throw new \
    KernelException("{$PackageComponentName} cannot be requested as public component!");
                                                }
                                            }

                                            if(isset(
    $PackageComponentPrivateName))
                                            {
                                                
    $ObjectReference->{'0x01_' $PackageComponentPrivateName} = clone
                                                
    self::create('Components'$PackageComponentNamefalse);
                                            }
                                            else
                                            {
                                                
    $ObjectReference->{'0x00_' $PackageComponentName} =
                                                    
    self::create('Components'$PackageComponentName);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        throw new \
    KernelException("Object {$name} failed to load package {$packageName}.
                                                       Package do not exist or is incorrect format!"
    );
                                    }
                                }
                            }
                        }
                        else
                        {
                            throw new \
    KernelException("Object {$name} dependency injection has failed!
                                               Please check if object implements 'KernelContainer'!"
    );
                        }
                    }
                    if(
    $Reflection->hasMethod('__autorun'))
                    {
                        
    $autorun $Reflection->getMethod('__autorun');

                        
    $autorun->invoke($ObjectReference);
                    }
                }
                else
                {
                    throw new \
    KernelException("Component {$name} do not exists or not configured!");
                }

                return 
    $ObjectReference;
            }


            public static function 
    hook($event)
            {
                if(isset(
    configStore('EventDispatcher')[$event]))
                {
                    
    $HookName configStore('EventDispatcher')[$event];

                    if(
    is_string($HookName))
                    {
                        return 
    self::create('Hooks'$HookNamefalse);
                    }
                    elseif(
    is_array($HookName))
                    {
                        
    array_map(function ($value)
                        {
                            
    self::create('Hooks'$valuefalse);
                        }, 
    $HookName);
                    }
                    else
                    {
                        throw new \
    KernelException("Kernel Event Hook {$event} is not correct type!");
                    }
                }

                return 
    true;
            }

            
    /**
             * Initializes autorun components
             *
             */
            
    public static function initialise()
            {
                
    $Configuration configStore('Components');

                foreach(
    $Configuration['Autorun'] as $name)
                {
                    
    self::create('Components'$name);
                }
            }

            
    /**
             * Returns array list of public objects
             *
             *   [MENTION=850422]return[/MENTION] array
             */
            
    public static function listOfComponents()
            {
                return 
    array_keys(self::$KernelObject);
            }

            
    /**
             * Dumps information about kernel objects
             *
             *   [MENTION=850422]return[/MENTION] array
             */
            
    public static function debugKernelObjects()
            {
                
    var_dump(self::$KernelObject);
            }
        }

    KernelContainer.php (All components must extend this class)
    PHP Code:
    abstract class KernelContainer
    {
        
    /**
         *   [MENTION=1333430648]Var[/MENTION] array
         */
        
    private $container = array();

        
    /**
         *   [MENTION=1333357818]param[/MENTION] $name
         *
         *   [MENTION=850422]return[/MENTION] mixed
         */
        
    public function __get($name)
        {
            if(isset(
    $this->container['0x00_'.$name]))
            {
                return 
    $this->container['0x00_'.$name];
            }
            elseif(isset(
    $this->container['0x01_'.$name]))
            {
                return 
    $this->container['0x01_'.$name];
            }
            else
            {
                return 
    $this->container[$name];
            }
        }

        
    /**
         *   [MENTION=1333357818]param[/MENTION] $Name
         *   [MENTION=1333357818]param[/MENTION] $Value
         */
        
    public function __set($Name$Value)
        {
            
    $this->container[$Name] = $Value;
        }

        
    /**
         *   [MENTION=1333357818]param[/MENTION] $name
         *
         *   [MENTION=850422]return[/MENTION] bool
         */
        
    public function __isset($name)
        {
            return isset(
    $this->container['0x00_'.$name]) OR
            isset(
    $this->container['0x01_'.$name]) OR
            isset(
    $this->container[$name]);
        }

        
    /**
         *   [MENTION=1333357818]param[/MENTION] $name
         */
        
    public function __unset($name)
        {
            if(isset(
    $this->container['0x00_'.$name]))
            {
                unset(
    $this->container['0x00_'.$name]);
            }
            elseif(isset(
    $this->container['0x01_'.$name]))
            {
                unset(
    $this->container['0x01_'.$name]);
            }
            else
            {
                unset(
    $this->container[$name]);
            }
        }

        
    /**
         * Returns list of all currently active components
         *
         *   [MENTION=850422]return[/MENTION] array
         */
        
    public function containerList()
        {
            return 
    array_keys($this->container);
        }

        
    /**
         * Dumps information about all loaded components
         *
         */
        
    public function containerDump()
        {
            
    var_dump($this->container);
        }

    Configuration file
    PHP Code:
    $config['Packages']['Standart'] = array
    (
        [
    'Router']
    );

    $config['Autorun'] = array('TestComponent');

    $config['Components']['TestComponent'] = array
    (
        
    'Name'       => 'TestComponent',
        
    'Class'      => 'Application\Components\TestComponent',
        
    'Arguments'  => NULL,
        
    'Packages'   => ['Standart'],
        
    'Visibility' => NULL,
    );

    $config['Components']['Router'] = array
    (
        
    'Name'       => 'Router',
        
    'Class'      => 'Application\Components\Router',
        
    'Arguments'  => NULL,
        
    'Packages'   => NULL,
        
    'Visibility' => NULL,
    ); 
    Component Example

    PHP Code:
    namespace Application\Components
    {
        class 
    TestComponent extends \KernelContainer
        
    {
            public function 
    __autorun()
            {
                echo 
    'Hello';
            }
        }

    Full Debuged Source: https://github.com/KristiansJaunzems...licationEngine
    Last edited by KristiansJ; 24-09-14 at 04:52 PM.




Advertisement