Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Release] PHP 5.4+ Simple dependecy injection

Experienced Elementalist
Joined
Jul 23, 2012
Messages
201
Reaction score
128
Maybe some one will find this DI example useful...

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

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

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

        /**
         * Returns component class reference
         *
         *   [USER=1333357818]param[/USER] string $name Class short name
         *
         *   [USER=850422]return[/USER] 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', $PackageComponentName, false);
                                        }
                                        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', $HookName, false);
                }
                elseif(is_array($HookName))
                {
                    array_map(function ($value)
                    {
                        self::create('Hooks', $value, false);
                    }, $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
         *
         *   [USER=850422]return[/USER] array
         */
        public static function listOfComponents()
        {
            return array_keys(self::$KernelObject);
        }

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

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

    /**
     *   [USER=1333357818]param[/USER] $name
     *
     *   [USER=850422]return[/USER] 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];
        }
    }

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

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

    /**
     *   [USER=1333357818]param[/USER] $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
     *
     *   [USER=850422]return[/USER] 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:
$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:
namespace Application\Components
{
    class TestComponent extends \KernelContainer
    {
        public function __autorun()
        {
            echo 'Hello';
        }
    }
}

Full Debuged Source:
 
Last edited:
Back
Top