Jump to content

About class autoload...


Hall of Famer

Recommended Posts

Well PHP5 has a function __autoload() which makes it possible to load classes when needed, thereby eliminating excessive lines of include() or require(). Now I have a question about this feature, lets assume we have a class file like this:

 

interface Shop{
   public function getshop();
   public function displayshop();
   public function purchase($name);
   public function sell($name);
   public function rent($name);
}

class Foodshop implements Shop{
  // codes here
}

class Bookshop implements Shop{
   // codes here
}

class Electronicshop implements Shop{
  // codes here
}

class Petshop implements Shop{
  // codes here
}

class Auction implements Shop{
  // codes here, note the class name auction does not contain shop substring...
}

 

If I instantiate an object from one of these classes that implement (or extend) an interface(or an abstract class), how should I design my __autoload() function so that this class file will be loaded properly? Please help.

Link to comment
Share on other sites

function __autoload($class){
    include_once $class.".php";
}

 

However, the autoload function may be depreciated in future versions of PHP as mentioned on the PHP website (www.php.net/autoload). I'ts better to define your own function and register it as an autoload function; also explained on the same page.

Link to comment
Share on other sites

To use autoloaders, it is best to have strict naming standards. For example, all files lowercase and all classes start with uppercase. You'll also have to use only one class per file, because with an autoloader you load the class based on the file name.

 

I always name my class files with an uppercase first letter such as MyClass.php then when I do an Autoload, I do something like this:

 

function __autoload($class){
$file = "path/to/files/$class.php";
if(is_file($file))
	require_once $file;	
}

Link to comment
Share on other sites

Okay, so if you have these two files:

shop.php

interface Shop{
   public function getshop();
   public function displayshop();
   public function purchase($name);
   public function sell($name);
   public function rent($name);
}

 

foodshop.php

class Foodshop implements Shop{
  // codes here
}

 

And then your autoloader:

function __autoload($class)
{
require strtolower($class) . '.php';
}

 

And then instantiate:

$foodshop = new Foodshop;

 

Since both "Foodshop" and "Shop" are not yet loaded, both classes are passed to __autoload() and then loaded.

Link to comment
Share on other sites

function __autoload($class)
{
require strtolower($class) . '.php';
}

 

Might want to use require_once, require will attempt to load it again. if it already has been loaded you will get an error, since you would then be trying to redefine a class.

 

Using require_once  is not necessary as __autoload is only called if a class doesn't already exist in scope.

Link to comment
Share on other sites

@The little guy:

 

Oh really? But my coding convention is to have classes that implement the same interface, or extend from same abstract/parent class into one single class file. Are you saying this is a bad habit?

 

@Scootstah:

I know this is the common way of using class autoload, but I may end up having hundreds of class files if I only write one class in each file. There is really no way for PHP to detect or load interface or abstract/parent class?

Link to comment
Share on other sites

@The little guy:

 

Oh really? But my coding convention is to have classes that implement the same interface, or extend from same abstract/parent class into one single class file. Are you saying this is a bad habit?

 

Somewhat.  The idea behind one class per file is to keep the code easy to read and maintain.  With everything split up it is easy to find where a class is (file is named after the class) and you don't have to wade through hundreds/thousands of lines of code to find the particular class your interested in.

 

This also lets you be more selective of what you include and not waste time including a bunch of unnecessary classes just to load one.  It's not uncommon in large projects to have a single base class which many classes will extend from.

 

@Scootstah:

I know this is the common way of using class autoload, but I may end up having hundreds of class files if I only write one class in each file. There is really no way for PHP to detect or load interface or abstract/parent class?

 

You use a standard naming convention for your files and classes following a set of rules that you can implement in your autoloader to find the required class.  It will be called for each class/interface/trait that needs to be loaded if it has not already been defined. 

 

For instance, I name all my files for classes in a format of ClassName.class.php, interfaces as InterfaceName.interface.php, and traits (unused as of yet but would be) TraitName.trait.php.  Currently I just have them all in a single file but in future projects which may include namespaces I would have a directory for each namespace.

 

Given that, my autoload function looks a little something like:

<?php

function __autoload($name){
$suffixList = array('.class.php', '.interface.php', '.trait.php');
$classDir = '/path/to/files';

foreach ($suffixList as $sf){
	$file = "{$classDir}/{$name}{$sf}";
	if (file_exists($file)){
		require $file;
	}
}
}

 

Link to comment
Share on other sites

@The little guy:

 

Oh really? But my coding convention is to have classes that implement the same interface, or extend from same abstract/parent class into one single class file. Are you saying this is a bad habit?

 

@Scootstah:

I know this is the common way of using class autoload, but I may end up having hundreds of class files if I only write one class in each file. There is really no way for PHP to detect or load interface or abstract/parent class?

 

If you have all your classes in one file, why do you even need an autoloader? Just include the one file and all the classes will be loaded.

 

You're going against pretty much every OOP standard, though. Split them up.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.