Hall of Famer Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/ Share on other sites More sharing options...
cpd Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331803 Share on other sites More sharing options...
The Little Guy Posted March 28, 2012 Share Posted March 28, 2012 It is common practice to have 1 class in 1 file. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331951 Share on other sites More sharing options...
scootstah Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331956 Share on other sites More sharing options...
The Little Guy Posted March 28, 2012 Share Posted March 28, 2012 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; } Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331962 Share on other sites More sharing options...
Hall of Famer Posted March 28, 2012 Author Share Posted March 28, 2012 umm so theres no way for PHP to check if a class implements an interface, or extends from another class/abstract class? Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331976 Share on other sites More sharing options...
scootstah Posted March 28, 2012 Share Posted March 28, 2012 I'm pretty sure if you try to extend or implement a class that hasn't yet been called it will go through the autoloader. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331977 Share on other sites More sharing options...
Hall of Famer Posted March 28, 2012 Author Share Posted March 28, 2012 I'm pretty sure if you try to extend or implement a class that hasn't yet been called it will go through the autoloader. Interesting, mind elaborating? Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331982 Share on other sites More sharing options...
scootstah Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1331993 Share on other sites More sharing options...
The Little Guy Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332044 Share on other sites More sharing options...
trq Posted March 28, 2012 Share Posted March 28, 2012 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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332069 Share on other sites More sharing options...
Hall of Famer Posted March 30, 2012 Author Share Posted March 30, 2012 @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? Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332577 Share on other sites More sharing options...
kicken Posted March 30, 2012 Share Posted March 30, 2012 @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; } } } Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332583 Share on other sites More sharing options...
scootstah Posted March 30, 2012 Share Posted March 30, 2012 @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. Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332665 Share on other sites More sharing options...
Hall of Famer Posted March 30, 2012 Author Share Posted March 30, 2012 Well its not like I have all classes in one file, just those that have connections to each other. But fine, you have a good point so... Quote Link to comment https://forums.phpfreaks.com/topic/259856-about-class-autoload/#findComment-1332675 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.