8

I have this autoload code :

function __autoload($class_name)
{
    //class directories
    $directorys = array(
        './Controls/',
        './Config/',
        './Utility/'
    );
    //for each directory
    foreach($directorys as $directory)
    {
        //see if the file exsists
        if(file_exists($directory.$class_name . '.php'))
        {
            require_once($directory.$class_name . '.php');
            //only require the class once, so quit after to save effort (if you got more, then name them something else
            return;
        }
    }
}

I have three directories that they're holding all of my classes and functions.

Can I create a single autoload file in Controls directory and use it to load all function or classes in other php files I mean for example index.php file in /portal/main/index.php

is it possible to load classes that are controls and config in index.php file without including any file in above of index.php file

I mean autoload automatically understands which file is requesting a class or function and include that file for it.

updated code :

function __autoload($class_name)
{
    //class directories
    $directorys = array(
        '/Controls/',
        '/Config/',
        '/Utility/'
    );
    //for each directory

    $ds = "/"; //Directory Seperator
    $dir = dirname(__DIR__); //Get Current file path
    $windir = "\\"; //Windows Directory Seperator
    $path = str_replace($windir, $ds, $dir);

    foreach($directorys as $directory)
    {
        //see if the file exsists
        if(file_exists( $path . $directory . $class_name . '.php'))
        {
            require_once( $path . $directory . $class_name . '.php');
            //only require the class once, so quit after to save effort (if you got more, then name them something else
            return;
        }
    }
}

I have updated the code and it include files, but the only problem that i have is that this function is not running automatically,

for example my autoload file is in : root/Controls/autoload.php and I need some classes and functions in :root/portal/index.php

when i define classes in index.php i get error that the file is not exists and i should manually call autoload.php file in index.php

how can i make autoload smart which i shouldn't have include it in each file for including classes ?

please help me out. thanks in advance

anonymox
  • 419
  • 1
  • 9
  • 32

2 Answers2

6
  1. Your program is only as smart as you. If you dream of solving a problem beyond a mainstream language's capability, problem is with your dream, not the language.

  2. To autoload PHP code, set auto_prepend_file in php.ini to your autoloader script. Alternatively you may make it the centralised entry point and direct traffic with mod_rewirte.

This is bad practice. Both methods relies on server config such as .htaccess, and is not always available. You may also override existing configs or fail to rewrite some paths.

You should manually centralise the PHP requests (and seal off non-entry points), or require_once in each entry points.

  1. PHP does not support autoloading function. Include all functions you might need if you can't bother to code their inclusions.

Look at Wikipedia, Magento, or WordPress. They have hundreds if not thousands global functions.

Do not worry about including - trust your disk cache and enable opcode cache. Static inclusion is pretty fast and with opcode cache it may be faster than conditional loads.

  1. If you have multiple classes / functions in a file, I know of no dynamic language that can magically pick the correct file to include. Your autoloader looks pretty standard.

You can dynamically define anything in PHP. PHP can never be confident what it will get unless it really runs the code. Auto loaders are simply trusting filenames as correct and complete declaration of what is in the file.

Since your autoloader scans all folders, you may want to make a static file map on first run, and use the map for subsequence loads. Assuming you are not going to create class files dynamically with PHP, of course.

Community
  • 1
  • 1
Sheepy
  • 17,324
  • 4
  • 45
  • 69
  • Thanks for the full explained answer, but according to your answer part 3 manually including files are ok and fast ? not doubt about speed but it's a wast of time to write every inclusion !!! what about symphony and codeigniter frameworks? they're also using autoloaders. and i'm creating my own framework which i want to use autoloader. – anonymox Nov 24 '15 at 09:52
  • the idea of using autoloader is to code and use classes anywhere in the project without bothering to include needed files or classes – anonymox Nov 24 '15 at 09:55
  • @anonymox Note that I said include the *functions*, not *classes*. Even the software I mentioned put most features in class. I assumed that your autoloader is auto loading single class files fine, once the loader itself is loaded. – Sheepy Nov 24 '15 at 10:14
  • yes it works fine when i manually call it, i'm a bit confuse here : if i load autoload file at the begining of my code for example if i include it in my index.php file the very first index file would it load all classes and etc for the rest of the files and pages ? instead of including it in php.ini – anonymox Nov 24 '15 at 10:27
  • @anonymox Unless your "other files and pages" are accessed *through* index.php, they won't have the loader in index.php. This is why most PHP programs is designed to force all requests to go through index.php - the "centralised entry point" I mentioned. This is like a house with one main door verses a house with exterior doors in every room. The later is a management / reconstruction nightmare. – Sheepy Nov 24 '15 at 10:32
  • so what's your solution/suggestion ? – anonymox Nov 24 '15 at 10:47
  • "You should (rewrite the app to) manually centralise the PHP requests, or require_once in each entry points." - in the worse case "entry points" mean all non-auto loaded PHP file. In such a worse case, modify php.ini or mod_rewrite - the linked article has detailed code example - may be more reliable. – Sheepy Nov 24 '15 at 11:29
6

Simple manual solution : put your autoload file in your project root and include it in your index file this will do the job.

but if you want to use htaccess or php.ini : Place a file called .user.ini into the document root and add the auto_prepend_file directive in there:

auto_prepend_file = /home/user/domain.com/init.php

The file must be inside PHP's include_path. So you must either set the file's directory to be in the include_path inside php.ini, or do it in the .htaccess with a php_value statement.

php_value include_path ".:/path/to/file_directory"
php_value auto_prepend_file "file.php

If you use the above method in .htaccess, be sure to copy the include_path from php.ini in and add the :/path_to/file_directory so you don't lose any already needed includes.

Alternatively, just add :/path/to/file_directory to include_path directly in the php.ini

Update

If you cannot modify the include_path, you might try specifying a relative path to the auto_prepend_file. This should work since the file path sent is processed identically as if it was called with require():

php_value auto_prepend_file "./file.php"
Mohammad_Hosseini
  • 2,481
  • 3
  • 30
  • 53
  • your simple solution worked but in every sub directory it needs to re include the autoload file – anonymox Nov 24 '15 at 11:59
  • @anonymox depends how did you structured/organized your code. If you took down the path of standard OOP and todays wab apps and/or frameworks out there you wouldn't need to re-include the autoload file all over the place. You would simply have a single PHP e.g. index.php "bootstrap" file through which all requests would flow, and only in that file you would need to include/require the autoload file. But if you are in your app accessing php files directly via URL e.g. than sure you would need to explicitly re-include autoload in such files. – Ivan Veštić Nov 28 '15 at 01:11
  • @IvanVeštić I created a index bootstrap but i think it's not what it should be, It includes autoload file in all first layer files and folders but when i go to subfolders and files for example : control/modules/text.php i have to require that autoload to make it work. – anonymox Nov 29 '15 at 05:39
  • should i create a dynamic path loader for all request? then send them to the autoload ? – anonymox Nov 29 '15 at 05:40