SitePoint Sponsor

User Tag List

Results 1 to 21 of 21
  1. #1
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    using __autoload

    Hi guys

    Is it considered bad practice to load your required classes just using the __autoload function?

    So for example if your controller used a selection of library and model classes your autoload function would loop through each of the directories to find the required file?

  2. #2
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    Is it considered bad practice to load your required classes just using the __autoload function?
    No, though many people suggest you use spl_autoload_register() with a normal function instead.

  3. #3
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think it's a good catch in case you forget, but I try not to rely on it. I think ZF has a good implementation of it where you register the autoload, but in the different classes you still require the files as needed. I extended it to flag a notice whenever autoload is fired since autoload is an undeeded hit.

    Also, relying on autoload may make it harder for another developer to follow your code as it is ambiguous.
    MySQL v5.1.58
    PHP v5.3.6

  4. #4
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BrandonK View Post
    I think it's a good catch in case you forget, but I try not to rely on it. I think ZF has a good implementation of it where you register the autoload, but in the different classes you still require the files as needed. I extended it to flag a notice whenever autoload is fired since autoload is an undeeded hit.
    I recently read an interesting blog post describing removal of require_onces in favor of autoload for performance gains in Zend Framework. It might be worth a read.

    I rely on autoload as much as possible. I'm not worried about the possible perfomance costs and where the actual source files reside is no more ambiguous than with plain old requires if you have decent naming conventions such as Zend Framework does.

  5. #5
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's a very interesting article. I really suck when it comes to udnerstanding the different cache types and how to tweak a server for performance, so I am easily swayed in my opinions.

    That being said, even though he says that autoload is faster than require_once, he doesn't really go into why. The only thing I can think of is that require is slower than include, and ZF::__autoload uses include so it has a slight edge there.

    What contradicts him, is ZF's own documentation: http://framework.zend.com/manual/en/...nd.loader.load They recommend using require_once, but make no mention of performance.
    MySQL v5.1.58
    PHP v5.3.6

  6. #6
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by BrandonK View Post
    That being said, even though he says that autoload is faster than require_once, he doesn't really go into why. The only thing I can think of is that require is slower than include, and ZF::__autoload uses include so it has a slight edge there.
    Probably because the filesystem is queried each time you call require_once - autoload is only invoked when the class isn't already loaded. So even if it's slower, compared side-by-side, it wins in the longer run.

    I rely a lot on autoload, and I don't really care if it's the fastest option or not. The important thing is that it allows me to organise code better, than having require_once all over the place. If performance is an issue, there are probably other things that matters more than autoload.

  7. #7
    SitePoint Guru
    Join Date
    Dec 2005
    Posts
    982
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That's a very good point kyber, and I didn't even think about that. My understanding of require_once though is that it keeps a private array of files already included and checks that before trying the file system.
    MySQL v5.1.58
    PHP v5.3.6

  8. #8
    SitePoint Guru
    Join Date
    Nov 2004
    Location
    Plano
    Posts
    643
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    i use __autoload extensively. it's a great feature and i've also heard bad things performance-wise about using require_once.

  9. #9
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Wow, great response cheers guys.

    This is going to probably sound very dumb because I'm still getting to grips with patterns etc but what's the benefit of using a locator or registry object if you can just autload the class(es) you require?

  10. #10
    SitePoint Enthusiast
    Join Date
    Aug 2005
    Location
    Germany
    Posts
    25
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thats two different things. autoload just loads the file the class sits in - just like require.

    A registry can help you to instatiate a class only once, e.g. a database handler class most likely needs to be instantiated only once but is used by different other classes. So you can pass the registry around to satisfy the other classes prerequisites. So a registry is basically like a telephone book for commonly used objects.

  11. #11
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    .. what's the benefit of using a locator or registry object if you can just autload the class(es) you require?
    The purpose of a registry/locator is to share instances of classes (objects) between different parts of your application. It essentially serves the same purpose as global variables, but in a way that tries to solve some of the problems with global variables.

  12. #12
    SitePoint Guru
    Join Date
    Nov 2004
    Location
    Plano
    Posts
    643
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken View Post
    the Purpose Of A Registry/locator Is To Share Instances Of Classes (objects) Between Different Parts Of Your Application. It Essentially Serves The Same Purpose As Global Variables, But In A Way That Tries To Solve Some Of The Problems With Global Variables.
    QFT

    edit: lol it upper cased every word...

  13. #13
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok, I think this is making sense!!

    So,you would normally store the common objects IE db etc into a registry object in your index.php or you start page?

    But then how can I avoid passing the registry object as a parameter to each class that needs it, is this where to factory pattern comes in?

  14. #14
    SitePoint Guru Ize's Avatar
    Join Date
    Nov 2005
    Location
    The Netherlands
    Posts
    809
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    ok, I think this is making sense!!

    So,you would normally store the common objects IE db etc into a registry object in your index.php or you start page?

    But then how can I avoid passing the registry object as a parameter to each class that needs it, is this where to factory pattern comes in?
    Moreso the Singleton pattern.
    Always create a Registry object thru a static method and make sure there's always just the one Registry available, and you should be alright.

    Then you can call that static method from any class and it will always return the same object.

  15. #15
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    So,you would normally store the common objects IE db etc into a registry object in your index.php or you start page?

    But then how can I avoid passing the registry object as a parameter to each class that needs it, is this where to factory pattern comes in?
    I give the registry as the first parameter to all my controllers. Sometimes I'll pass it to mappers, or sometimes I'll just pass the db if thats all they need. I'd rather avoid singletons if at all possible.

  16. #16
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Singleton that's the one

    So in your controller for example you would have something like;

    $this->registry = Registry->getinstance();

    allspiritseve why do you avoid singletons

    Cheers for your replies tho guys

  17. #17
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    allspiritseve why do you avoid singletons
    A singleton is more global than passing through the constructor, and I can't mock them for testing.

  18. #18
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm trying to sort out a better solution as well for autoloading classes in my projects.

    I might use this method:

    PHP Code:
    <?php
    final class Loader {
        static private 
    $data = array();
        
        static public function 
    register($class$file) {
            
    self::$data[$class] = $file;
        }
        
        static public function 
    load($class) {
            if (isset(
    self::$data[$class])) {
                return include_once(
    self::$data[$class]);
            } else {
                return 
    FALSE;
            }
        }
    }

    function 
    __autoload($class) {
        return 
    Loader::load($class);
    }

    // Library
    Loader::register('session'DIR_LIBRARY 'session.php');
    Loader::register('config'DIR_LIBRARY 'config.php');

    // Model
    Loader::register('ModelProduct'DIR_MODEL 'product.php');

    // Controller
    Loader::register('ControllerProduct'DIR_CONTROLLER 'product.php');
    ?>
    Advantages:

    1. Using this method makes loading files more secure because it only allows files that are pre registered to be loaded.

    2. It keeps the locations of all files in one place and if files are moved to different directories it will be easy to update their location.

  19. #19
    . shoooo... silver trophy logic_earth's Avatar
    Join Date
    Oct 2005
    Location
    CA
    Posts
    9,013
    Mentioned
    8 Post(s)
    Tagged
    0 Thread(s)
    I ended up creating an automated way of indexing my class files and then creating a file called "load" in the root of the component directory.

    Example of my logging component load file: (using PHP 5.3 + namespaces btw)
    PHP Code:
    <?php namespace Logical::Log;

    function 
    __load $class )
    {
        static 
    $index;

        if ( empty( 
    $index ) ) {
            
    $index = array(
                
    'exception'       => '/exception.php',
                
    'ifilter'         => '/ifilter.php',
                
    'filter::message'  => '/filter/message.php',
                
    'filter::priority' => '/filter/priority.php',
                
    'filter::surpress' => '/filter/surpress.php',
                
    'iformatter'      => '/iformetter.php',
                
    'format::simple'   => '/format/simple.php',
                
    'format::xml'      => '/format/xml.php',
                
    'manager'         => '/manager.php',
                
    'writer'          => '/writer.php',
                
    'write::database'  => '/write/database.php',
                
    'write::mock'      => '/write/mock.php',
                
    'write::null'      => '/write/null.php',
                
    'write::stream'    => '/write/stream.php'
            
    );
            return 
    spl_autoload_register__FUNCTION__true );
        }

        if ( !empty( 
    $class ) && stripos$class__NAMESPACE__ ) !== false ) {
            
    $class str_replace__NAMESPACE__ '::'''strtolower$class ) );
            if ( isset( 
    $index$class ] ) ) {
                include 
    __DIR__ $index$class ];
            }

        }
    }

    __loadnull );
    Usage:
    PHP Code:
    <?php

    #future usage will utilize PHAR
    #require_once 'phar:///logical/log/load';

    require_once 'logical/log/load';
    use 
    Logical::Log::Write::Mock as MockWriter;
    use 
    Logical::Log;

    $log = new Log::Manager( new MockWriter );
    $log'info''Test Message' );
    Edit:


    Just found out, that the namespace separator is being changed from "::" to "\"
    Last edited by logic_earth; Nov 9, 2008 at 21:39.
    Logic without the fatal effects.
    All code snippets are licensed under WTFPL.


  20. #20
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    does any one think this is a good idea?

    PHP Code:
    <?php
    $model      
    factory::model('user/user_group');
    $view       factory::view('catalog/product'$data);
    $controller factory::controller('catalog/product');
    $mail       factory::library('common/mail');
    $db         factory::database('mysql''hostname''username''password''database''prefix''charset');
    ?>

  21. #21
    SitePoint Enthusiast
    Join Date
    Feb 2008
    Posts
    33
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    does any one think this is a good idea?

    PHP Code:
    <?php
    $model      
    factory::model('user/user_group');
    $view       factory::view('catalog/product'$data);
    $controller factory::controller('catalog/product');
    $mail       factory::library('common/mail');
    $db         factory::database('mysql''hostname''username''password''database''prefix''charset');
    ?>
    No, I think it's better to have a static factory in the class definition of the object it creates, i.e.

    PHP Code:
    <?php
    $model 
    model::factory('user/user_group');
    etc....
    that way you don't have to add to a monolothic factory class to add new types that can be created, plus it just makes more sense for an object to know how to instantiate itself (what if you change the constructor, with it in the same file you just edit the factory, otherwise you now have to go and find another file and modify that. You can also do thinks like make the constructor private/protected if not meant to be instantiated directly).


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •