working on a project that needed to load different tools (about 6 of them and never all of them), and using many modules, by demand, i needed to make a consistent call method to be used by all methods or other callers, and not affecting other.

Solution was using magic method in an parent class. i was already using __construct/__destruct methods; but now i needed __call, and, by a consistent way of doing things, __set and __get, but these will be covered some other time.

Anyway let’s get started.

I wanted to load a tool , that might have a config file (location of config is predetermined), and is located in the default zone or specified in a path in config, and has a default name or a name specified in config of the class.

let’s create a class :

class Object
{
//putting a __construct
	function __construct($root_path)
	{
		$this->root_path= $root_path;
	}

for the magic method :

public function __call($name, $params = null)
{
        $isStatic = !(isset($this) && get_class($this) == __CLASS__);

Exploding name that we received :

		$parts  = explode('_', $name);
		$action = array_shift($parts);

Switching through different posibilities :

		switch ($action){
			case "loadtools":
				//loading config
				$className = array_shift($parts);
				$param_name = array_shift($parts);

We have all config based in the CONFIG_PATH dir, and have a default name. We parse it.

				//all configs are based 
				if (file_exists($this->root_path.CONFIG_PATH.$className.'.cfg.ini'))
				{
					$cfg  =   parse_ini_file($this->root_path.CONFIG_PATH.$className.'.cfg.ini', true);
				}else
				{
					$cfg = null;
				}

Now loading the tool of config values or default values.

				if (!class_exists($className))
				{
					if ($cfg['path'] && $cfg['name'])
					{
						include_once ($this->root_path.$cfg['path'].$cfg['name']);
						$className = $cfg['classname']?$cfg['classname']:$className;
					}
					else
					{
						include_once ($this->root_path.TOOLS_PATH.$className.'.class.php');
					}

				}

Setting the property of the class to store the newly created tool. Passing params or config to the Tool we needed.

$var = new $className($params?$params:$cfg);
if (!isset($var))
    {
        return false;
    }else
    {
        if (!$isStatic)
        {
            $this->$param_name = $var;		
            return true;
        }else
        {
            return $var;
        }
}
break;

Closing function:

			default:
				return false;
				break;
		}

	}

Loading tools wil be made by calling :
Object::loadtools_[className]_[propertyName_to_store]([params_to_pass_to_class]);
or using an instantiated object class. In static mode will return false or TheTool, in dynamicmode will return true/false, and the tool is stored inside the object.
This return false on failure, and keeps the tool inside the object variable.

BONUS:
Let’s say we need to call some static methods from a tool,and we don’t need to laod the whole tool, just add the next code to the switch statement. Of course it is normal that the toll has that method.

case 'customfunc':
    $param_name = array_shift($parts);
    $var->$parts[0]($params);
    if (!$isStatic)
    {
        $this->$param_name = $var;		
        return true;
    }else
    {
        return $var;
    }
break;

Calling that will be made by :
Object::customfunc_[className]_[propertyName_to_store]([params_to_pass_to_class]).
of course this has a static or dynamic mode.

Next time i will show, using the example above, how to use exception and return better responses.
Until then happy __calling.

PHP TUTORIALS