PHP Autoload class. Why no autoload function?

I have: func1 dot php


function func1_do1() {}
function func1_do2() {}


function __autoload_func($func_name)
{
    // explode $func_name
    // include func1 dot php
}

$do = func_do2();

I know, autoload class only call when class doesn’t exists. Ok, I think autoload function same, too.

P/S: func dot php is a domain name :x

Hi,

Autoloading is only for classes, not functions. You will need to include the files with the functions using include()

I think PHP built-in functions (compiled, function is exists) should bypass.

Sorry but I dont really understand what you’re trying to say.

There is no __autoload_func function, and you cant autoload functions.

__autoload_func function. This is my idea :smiley:

include() function is exists before my own functions. Autoloading function does not call.

I’m still not sure what you’re trying to do or say exactly, but this may help.

You could pseudo auto load methods from within a class object like this:

<?php

class Loader
{
    public function __call($method, $args)
    {
        if (!function_exists($method)) {
            include "$method.php";
            return $method($args);
        }
        return false;
    }
}

$loader = new Loader();
$loader->foo();

Since foo() method does not exist in Loader it would include a file with the same name and call the function.

Seems pretty pointless in this implementation, but maybe relevant?

The reason autoload doesn’t do functions is because its not common to have one function to one file as it is with classes.

I disagree with you! Many functions can be group by function name prefix. Example: mymodule_

modules/mymodule dot php


function mymodule_do1() {}
function mymodule_do2() {}
function mymodule_do3() {}


function __autoload_func($func_name)
{
    static $call_count = 0;
    // explode $func_name
    // include func1 dot php
    if(... call ...) {
        echo '__autoload_func call';
        $call_count++;
    }
}


// $call_count = 0;
$do1 = mymodule_do1();
// autoload include modules/mymodule dot php
// mymodule_do2 and mymodule_do3 function is exists
$do2 = mymodule_do2();
$do3 = mymodule_do3();
// $call_count = 1 (not 3)

Sure…but it is uncommon for them to be on there own or not included into a master file or whatever. I didn’t say you couldn’t I just said its uncommon.

I have to agree. There is no technical reason, why there isn’t an autoload for floating functions.

I sometimes use a static class for auto-loading functions and classes.

 <?php
/**
 * LSPL autoloader static class
 * @package lspl
 * @subpackage main
 */
class lspl_loader {
	/**
	 * Configuration value
	 * @access private
	 * @var boolean
	 */
	private static $allow_search=true;
	/**
	 * Classes and functions
	 * @access private
	 * @var string
	 */	
	private static $file_extension='.php';
	
	/* folder paths */
	private static $locations=array();
	
	/* $s..['class/function-name.type']='path' */
	private static $shortcuts=array();
	
	/**
	 * Autoload a class/function {@link $type} with the name {@link $name}
	 * @param string $type
	 * @param string $name
	 * @return bool
	 */
	static function load($type,$name)
	{
		$type=strtolower($type);
		$name=strtolower($name);
		if(isset(self::$shortcuts[$name.'.'.$type]) && is_file(self::$shortcuts[$name.'.'.$type]))
		{
			require_once(self::$shortcuts[$name.'.'.$type]);
			if($type=='class' && class_exists($name,false))
			{
				return true;
			}elseif($type=='function' && function_exists($name)==true) {
				return true; 
			}
		}
		if(self::$allow_search==false) { return false; }
		foreach(self::$locations as $key=>$path)
		{
			$now=$path.'/'.$name.'.'.$type.self::$file_extension;
			if(is_file($now) && is_readable($now))
			{
				require_once($now);
				if( 
					($type=='function' && function_exists($name)==true) 
					|| ($type=='class' && class_exists($name)==true)
					)
				{
					self::$shortcuts[$name.'.'.$type]=$now;
					return true;
				}
			}
		}
		return false;
	}
	
	static function addLocation($path)
	{
		$path=lspl::cleanPath($path);
		if(!is_dir($path)) { return false; }
		self::$locations[]=$path;
		return true;
	}

	static function addShortcut($type,$name,$path)
	{
		if(is_file($path))
		{
			self::$shortcuts[$name.'.'.$type]=$path;
			return true;
		}
		return false;
	}
}
?>

and use it like

lspl_loader::load('function','someFunction');
lspl_loader::load('class','myClass');

or define the auto-load for functions…


if(!function_exists('__autoload'))
{
	function __autoload($name) { return lspl_loader::load('class',$name); }
}

I don’t put the code in __autoload directly because sometimes i need to add paths to folders to be searched later…

lspl_loader::addLocation('/core/' );

… and sometimes i pre-build the paths (i have a script that finds all classes and functions defined in a file) and use…

lspl_loader::addShortcut('class','lspl_storage','/core/lspl_config.class.php');

hope i’ve given you something to start on…

Even if such a feature existed, you’d want to consider using it sparingly if performance is a concern. So many filesystem hits can hurt performance.

What is “so many”?

You may define an __autoload function which is automatically called in case you are trying to use a class/interface which hasn’t been defined yet

Result of file system hits:

Fatal error: Call to undefined function not_exists() in func_test dot php on line 9

This seems like it’s going to wander into auto-loading namespaces eventually. :slight_smile:

prefix of function name == class name

:smiley: