ole wrote:Can you explain that in more depth. With some example code perhaps. What is a stub anyway?
I generally consider __autoload() more of an error handling functionality than something magical.
A stub, in this case, is a dynamically created class that fills the requirement for the namespace requested to be filled. My stubs overload a few of the magic methods supported by PHP 5.1. In this way it can handle property and method requests similar to the expected class. It allows PHP to continue execution without breaking fatally because I or a third party forgot to include the proper file or call the ServiceLocator.
I can't show actual code right now as my ServiceLocator is in a massive state of flux, but I'll show you the basics of what my __autoload() does.
Code: Select all
function flash($var)
{
if($var === null)
{
return 'null';
}
elseif(is_array($var))
{
$c = 0;
$o = 'array(';
foreach($var as $k => $v)
{
$o .= ($c > 0 ? ',' : '') . ($k == $c ? '' : flash($k) . '=>') . flash($v);
$c++;
}
$o .= ')';
return $o;
}
elseif(is_scalar($var))
{
return var_export($var,true);
}
elseif(is_object($var))
{
return 'object ' . get_class($var);
}
elseif(is_resource($var))
{
return 'resource ' . get_resource_type($var);
}
else
{
return 'unknown';
}
}
function flashOver($aForetext = null, $aArgs = null)
{
$trace = debug_backtrace();
//var_dump($trace);
if (isset($trace[1]))
{
$line = (isset($trace[1]['line']) ? intval($trace[1]['line']) : '??');
$file = (isset($trace[1]['file']) ? $trace[1]['file'] : 'Unknown file');
$prefix = '(' . $line . ')' . $file . ': ';
}
else
{
$prefix = '';
}
if (func_num_args() == 2 and is_string($aForetext) and is_array($aArgs))
{
$call = $aForetext;
$args = $aArgs;
}
else
{
$call = (!empty($trace[1]['class']) ? $trace[1]['class'] . $trace[1]['type'] : '') . $trace[1]['function'];
$args = $trace[1]['args'];
}
$args = '(' . implode(', ', array_map('flash', $args)) . ')';
return $prefix . $call . $args;
}
if (!function_exists('__autoload'))
{
function __autoload($aClassName)
{
$code =<<<STOP
class {$aClassName}
{
private \$store;
public function __construct()
{
\$this->store = array();
echo flashOver(), PHP_EOL;
}
public function __destruct()
{
echo flashOver(), PHP_EOL;
}
private function __set(\$aVar, \$aValue)
{
echo __CLASS__, (isset(\$this) ? '->' : '::'), \$aVar, ' = ' . flash(\$aValue), PHP_EOL;
\$this->store[\$aVar] = \$aValue;
}
private function __get(\$aVar)
{
echo __CLASS__, (isset(\$this) ? '->' : '::'), \$aVar, PHP_EOL;
return \$this->store[\$aVar];
}
private function __call(\$aFunction, \$aArgs)
{
echo flashOver(__CLASS__ . (isset(\$this) ? '->' : '::') . \$aFunction, \$aArgs), PHP_EOL;
return null;
}
}
STOP;
echo flashOver(), PHP_EOL;
eval($code);
}
}
$a = new UnknownClassName('arg1','arg2');
could possibly kick out:
Code: Select all
(133)/tests/stubTest.php: __autoload('UnknownClassName')
(133)/tests/stubTest.php: UnknownClassName->__construct('arg1', 'arg2')
(??)Unknown file: UnknownClassName::__destruct()
Now, this is just a rough example, but it's a working one.
