A community in which webmasters can ask for help with topics such as PHP coding , MySQL , IT jobs, web design, IT security.
Current location:homephp forumphp talk in 2008 yearBest solution for __autoload - page 1
User InfoPosts
Best solution for __autoload#1
As our PHP5 OO application grew (in both size and traffic), we decided to revisit the __autoload() strategy.

We always name the file by the class definition it contains, so class Customer would be contained within Customer.php. We used to list the directories in which a file can potentially exist, until the right .php file was found.

This is quite inefficient, because you're potentially going through a number of directories which you don't need to, and doing so on every request (thus, making loads of stat() calls).

Solutions that come to my mind...

-use a naming convention that dictates the directory name (similar to PEAR). Disadvantages: doesn't scale too great, resulting in horrible class names.

-come up with some kind of pre-built array of the locations (propel does this for its __autoload). Disadvantage: requires a rebuild before any deploy of new code.

-build the array "on the fly" and cache it. This seems to be the best solution, as it allows for any class names and directory structure you want, and is fully flexible in that new files just get added to the list. The concerns are: where to store it and what about deleted/moved files. For storage we chose APC, as it doesn't have the disk I/O overhead. With regards to file deletes, it doesn't matter, as you probably don't wanna require them anywhere anyway. As to moves... that's unresolved (we ignore it as historically it didn't happen very often for us).

Any other solutions?

posted date: 2008-12-11 07:57:00


Re: Best solution for __autoload#2
I had made out the solution of this problem. click to view my topic...

hope that hepls.

posted date: 2008-12-11 07:57:01


Re: Best solution for __autoload#3
CodeIgniter does something similar with the load_class function. If I recall correctly, it is a static function that holds an array of objects. The call to the function is: load_class($class_name, $instansiate);so in your case load_class('Customer', TRUE);and this would load an instance of the Customer class into the objects array.The function was pretty straight forward. Sorry I cant remember the name of the class it was in. But I do recall there being several classes that get loaded such as I think the Routing class, the Benchmark class and the URI class.

posted date: 2008-12-11 08:14:00


Re: Best solution for __autoload#4
Have you investigated using Zend_Loader (with registerAutoload()) instead of just the native __autoload()? I've used Zend_Loader and have been happy with it, but haven't looked at it from a performance perspective. However, this blog post seems to have done some performance analysis on it; you could compare those results to your in-house performance testing on your current autoloader to see if it can meet your expectations.

posted date: 2008-12-11 08:27:00


Re: Best solution for __autoload#5
I've also been playing with autoload for quite some time, and I ended up implementing some sort of namespaced autoloader (yes, It works also for PHP5.2).The strategy is quite simple:First I have a singleton class (loader) which has a call that simulates import. This call takes one parameter (the full class name to load) and internally calculates the file name it was called from (using debug_backtrace()). The call stores this information in an associative array to use it later (using the calling file as the key, and a list of imported classes for each key).Typical code looks like this:<?php loader::import('foo::bar::SomeClass'); loader::import('foo::bar::OtherClass'); $sc = new SomeClass();?>When autoload is fired, the full class name that was stored in the array gets transformed to a real filesystem location (double colons are replaced with directory separators), and the resulting filename is included.I know that It's not exactly what you were asking for, but it may solve the directory traversal issue, as the loader directly knows where the file exactly is (with the added feature that you could have your classes organized in directories, with no apparent performance penalty).I could provide you some working examples, but I'm too shy to show my crappy code to the public. Hope the above explanation was useful...

posted date: 2008-12-11 08:50:00


Re: Best solution for __autoload#6
If you're using APC, you should enable opcode caching. I believe this would have more benefit to performance, and be a more transparent solution, than any class/file strategy you employ.The second suggestion is to use whatever class/file strategy is easiest to develop against, but on your production site, you should concatenate the classes used most frequently into one file and make sure that's loaded during every request (or cached with APC). Do some performance experiments with increasing sets of your classes. You will probably find that the benefit of reducing file I/O is so significant, that stuffing all the classes together into one file is a net win, even if you don't need all the classes during every request.

posted date: 2008-12-11 09:49:00


Re: Best solution for __autoload#7
There is 2 general approaches that work well.First is using PEAR standard class naming structure so you just need to replace '_' with / to find the class.http://pear.php.net/manual/en/pear2cs.rules.phpOr you can search directories for php classes and map class name to file. You can save the class map to cache to save searching directories every page load.Symfony framework uses those approach.Generally its better to follow the standard structure as its simpler and you don't need to cache anything, plus you are then following recommended guidelines.

posted date: 2008-12-11 17:36:00


Re: Best solution for __autoload#8
function __autoload( $class ){ $patterns = array( '%s.class.php', '%s.interface.php' ); foreach( explode( ';', ini_get( 'include_path' ) ) as $dir ) { foreach( $patterns as $pattern ) { $file = sprintf( $pattern, $class ); $command = sprintf( 'find -L %s -name "%s" -print', $dir, $file ); $output = array(); $result = -1; exec( $command, $output, $result ); if ( count( $output ) == 1 ) { require_once( $output[ 0 ] ); return; } } } if ( is_integer( strpos( $class, 'Exception' ) ) ) { eval( sprintf( 'class %s extends Exception {}', $class ) ); return; } if ( ! class_exists( $class, false ) ) { // no exceptions in autoload :( die( sprintf( 'Failure to autoload class: "%s"', $class ) ); // or perhaps: die ( '<pre>'.var_export( debug_backtrace(), true ).'</pre>' ); }}You could also find some other, less posix dependent way to iterate directories, but this is what i've been using.It traverses all the directories in the include_path (set in php.ini or .htaccess) to find a class or interface.

posted date: 2008-12-12 06:32:00


Re: Best solution for __autoload#9
OMG, that's horrible. You call find for every dir in the INCLUDE_PATH, for every class you load, on every PHP request?!?

posted date: 2008-12-12 09:15:00


Re: Best solution for __autoload#10
As to the second point, given the amount of classes, the benefit is cancelled by the fact that we're loading way more than neccessary. Also, it's really inconvenient to rebuild it every time you want to deploy something.

posted date: 2008-12-12 09:17:00


Re: Best solution for __autoload#11
And your path separator is ';' (which means this code runs only on Windows) but you rely on a posix tool like find?

posted date: 2008-12-12 09:18:00


Re: Best solution for __autoload#12
I concur... this is horribly inefficient. Why not file_exists()? That's what we have at the moment.

posted date: 2008-12-12 09:20:00


select page: « 1 2 »
Copyright ©2008-2017 www.momige.com, all rights reserved.