Is autoload the best practice in PHP now?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Is autoload the best practice in PHP now?

Post by Christopher »

Is using autoload (SPL's I assume) rather than require_once()/include_once() in libraries considered the best practice now? It certainly cleans up library code that is one class per file (with dependencies). And is the PHP Group's performance tuning heading toward making autoload the best choice?
(#10850)
wei
Forum Contributor
Posts: 140
Joined: Wed Jul 12, 2006 12:18 am

Re: Is autoload the best practice in PHP now?

Post by wei »

I say yes, unless you really need to squeeze the last drop out of PHP. Although if you very likely to know before hand how many files needs to be included before runtime for the most common cases, it can help if these files are combined into 1 file (via some automated calculation).
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Is autoload the best practice in PHP now?

Post by josh »

require statements are a smell to me because there's lots of legitimate reasons I would want to modify the file structure (like merging a large framework into one big file with 1,000s of classes in it, to reduce flippant abuse of my expensive hardware :D ). No point in wasting dev time figuring out includes when people end up stripping them out anyways.

requires_once I will use from time to time, in unit tests, or in cases where a file is not a class and is not easily autoloadable (ex. Zend style controllers, by default, get put in a controllers directory which doesn't match their class path. so require is needed there, unless you rework your file structure to something original)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Is autoload the best practice in PHP now?

Post by John Cartwright »

My only issue with using an auto loader and frameworks is if the framework is completely dependent on auto-loading, then using reusable components will not be possible without also including an auto-loader. However, in the scope of the framework itself, the benefits (lazy loading, less clutter, etc) outweigh the costs.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Is autoload the best practice in PHP now?

Post by Christopher »

Are there any hybrid solutions that solve the stand-alone component problem? For example if you do:

Code: Select all

if (! class_exists('Foo_Bar', true)) include 'Foo/Bar.php';
The class_exists() will trigger the autoload if defined. But wrapping the include() in an if defeats some of PHP's optimizations I think.
(#10850)
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Is autoload the best practice in PHP now?

Post by allspiritseve »

John Cartwright wrote:if the framework is completely dependent on auto-loading, then using reusable components will not be possible without also including an auto-loader.
That's not entirely true, is it? You could just include the files needed before you use them. That's what I've been doing for testing the Skeleton ORM, since it doesn't have inline includes and we don't have an autoloader set up for tests (as far as I know).
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Is autoload the best practice in PHP now?

Post by John Cartwright »

allspiritseve wrote:
John Cartwright wrote:if the framework is completely dependent on auto-loading, then using reusable components will not be possible without also including an auto-loader.
That's not entirely true, is it? You could just include the files needed before you use them. That's what I've been doing for testing the Skeleton ORM, since it doesn't have inline includes and we don't have an autoloader set up for tests (as far as I know).
In all circumstances, no it is not true. However, when these reusable components in turn use other classes, then problems will arise. Using the Zend Framework as an example (lets forget the fact they use inline includes for a second), each component will likely have a specific exception class. Exception classes are of course belong in their own file, and without being included manually/autoloaded, the component would throw a fatal error.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Is autoload the best practice in PHP now?

Post by josh »

Well, the programmer ought to be used to having to litter their code with includes if theyre not using auto loading.

I think if you don't put require statements you will definitely cut your audience, but it can be it's own form of technical debt. For instance now are you going to run your unit tests with and without the require statements stripped just to double check? And you have to figure out which requires are needed, and remember to remove them when they are no longer required (extra steps when re-factoring)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Is autoload the best practice in PHP now?

Post by Christopher »

The other possibility for releasing components from a larger framework is that the all of the stand-alone component's files could be put into a single file when released separately.

Any comments on wrapping include/require in a if (! class_exists() ) {
(#10850)
User avatar
daedalus__
DevNet Resident
Posts: 1925
Joined: Thu Feb 09, 2006 4:52 pm

Re: Is autoload the best practice in PHP now?

Post by daedalus__ »

i can't answer the oq but i like autoload i think its a really neat feature.

then again a lot of other languages have their analogues to include.
User avatar
allspiritseve
DevNet Resident
Posts: 1174
Joined: Thu Mar 06, 2008 8:23 am
Location: Ann Arbor, MI (USA)

Re: Is autoload the best practice in PHP now?

Post by allspiritseve »

arborint wrote:Any comments on wrapping include/require in a if (! class_exists() ) {
Seems like even more clutter than before.

I thought I remembered reading something about SwiftMailer having an autoloader built in that would work as long as you included one file. Is there any reason something like that wouldn't work for Skeleton (and any other standalone library)?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Is autoload the best practice in PHP now?

Post by alex.barylski »

thought I remembered reading something about SwiftMailer having an autoloader built in that would work as long as you included one file. Is there any reason something like that wouldn't work for Skeleton (and any other standalone library)?
Thats how I do it. If you include the Spectra_System class (which you pretty much always will) it's autoloader automatically registers itself and will include any Spectra_X classes. The tricky part was making it work with other autoloaders, which would probably be the case when people use a framework, along side their favorite libraries (Swift, AdoDB, Smarty whatever).
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Is autoload the best practice in PHP now?

Post by josh »

allspiritseve wrote: Seems like even more clutter than before.
agreed.
I thought I remembered reading something about SwiftMailer having an autoloader built in that would work as long as you included one file. Is there any reason something like that wouldn't work for Skeleton (and any other standalone library)?
exactly, I think theres 2 includes. One sets up the auto loader, the other is just a big list of calls to a dependency injection system that includes every class in the library. I choose to use neither, I just added that path to my existing auto loader, so I felt like I was not restricted in any way using Swift Mailer, I had 3 possible ways to handle the including

Here's how it works

Code: Select all

 
Swift_DependencyContainer::getInstance()
  -> register('transport.failover')
  -> asNewInstanceOf('Swift_Transport_FailoverTransport')
In dependency_maps.php he has some scripts that wire things up in this dependency container.

Then before he use's a dependency he does this:

Code: Select all

call_user_func_array(
      array($this, 'Swift_Transport_FailoverTransport::__construct'),
      Swift_DependencyContainer::getInstance()
        ->createDependenciesFor('transport.failover')
      );
This goes and looks up the "transport.failover" key in a map of classes. It finds all the classes a Transport_Failover needs to be instantiated. (dependency injection),

so there are never any if( !class_exists()) calls or includes/requires. I think it may have to use auto loading to achieve this though, haven't looked into it too much

Edit:
Ok yeah here's the auto loader:

Code: Select all

 
/*
 * This file is part of SwiftMailer.
 * (c) 2004-2009 Chris Corbyn
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
 
/**
 * General utility class in Swift Mailer, not to be instantiated.
 * 
 * @package Swift
 * 
 * @author Chris Corbyn
 */
abstract class Swift
{
  
  /** Swift Mailer Version number generated during dist release process */
  const VERSION = '4.0.5';
  
  /**
   * Internal autoloader for spl_autoload_register().
   * 
   * @param string $class
   */
  public static function autoload($class)
  {
    //Don't interfere with other autoloaders
    if (0 !== strpos($class, 'Swift'))
    {
      return false;
    }
 
    $path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php';
 
    if (!file_exists($path))
    {
      return false;
    }
 
    require_once $path;
  }
  
  /**
   * Configure autoloading using Swift Mailer.
   * 
   * This is designed to play nicely with other autoloaders.
   */
  public static function registerAutoload()
  {
    spl_autoload_register(array('Swift', 'autoload'));
  }
  
}
 
He put a comment by the part where it is "designed to play nicely with other auto loaders", If I remember I never used this file, I just added his path to my existing auto loader and instantiated the class I needed.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Is autoload the best practice in PHP now?

Post by Christopher »

So it seem like, following Josh's comments, that if you follow PEAR naming conventions then it is usually trivial for people to add a path to their autoloaders. But what about if they don't have an autoloader? What do people consider the cleanest and easiest ways to initialize autoloading. Is just including a script in the top level directory of the library the preferred solution?
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Is autoload the best practice in PHP now?

Post by josh »

I think that a default auto loader should be included with the distribution, as long as care is taken to follow "common auto loader convention". Usually converting _ to / suffices, and nothing more or less.

Chris' implementation could be used as a standard, I like it. It accounts for things I didnt think of too:

Code: Select all

 
public static function autoload($class)
{
    //Don't interfere with other autoloaders
    if (0 !== strpos($class, 'Swift'))
    {
      return false;
    }
 
    $path = dirname(__FILE__).'/'.str_replace('_', '/', $class).'.php';
 
    if (!file_exists($path))
    {
      return false;
    }
 
    require_once $path;
}
Last edited by John Cartwright on Wed Dec 09, 2009 5:39 pm, edited 1 time in total.
Reason: fixed code formatting
Post Reply