Pragmatism in the real world

Zend_Loader's autoloader deprecated in Zend Framework 1.8

Zend_Loader‘s autoloader has been deprecated in the upcoming Zend Framework version 1.8 and so you now get a notice if you use it:

Notice: Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /www/zf-tutorial/library/Zend/Loader.php on line 207

Notice: Zend_Loader::Zend_Loader::autoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /www/zf-tutorial/library/Zend/Loader.php on line 186

Notice: Zend_Loader::Zend_Loader::autoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /www/zf-tutorial/library/Zend/Loader.php on line 186

(and so on)

This is because you have the lines:

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

(or similar) somewhere in your bootstrap system.

The easiest solution is to change them to:

require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('App_');

Where ‘App_’ is the name of a directory on your include path that has classes within it that follow the Zend Framework naming convention, so change it as appropriate and add more if you need them.

If you need generic autoloading ability, for instance because your models directory is on your include path and you don’t namespace your model classes, then add this:

$loader->setFallbackAutoloader(true);

You should also add:

$loader->suppressNotFoundWarnings(false);

when in development mode as then the new autoloader will actually tell you what the syntax error is rather than showing you a white page :)

Now you should go and read the Zend_Loader_Autoloader documentation to learn how very useful it is!

Update: You should also read Matthew’s article on Zend_Loader_Autoloader as it explains this all in detail!

31 thoughts on “Zend_Loader's autoloader deprecated in Zend Framework 1.8

  1. Your title is a bit misleading, not the whole Zend_Loader is deprecated but the autoloading facilities.

    Zend_Loader::loadClass() for example is used by Zend_Loader_Autoloader.

  2. I liked

    require_once 'Zend/Loader.php';
    Zend_Loader::registerAutoload();

    it's simple, two lines, no messing around :)

  3. hey guys,

    this new method doesn't seem to work with my code… I used the autoloader just to autload zend_pdf (i replaced all require_once references and the autoloader requires automaticly the needed zend_pdf files..) can anybody help me with that? this is my old code:

  4. my code:

    // LOAD ZEND_PDF
    $path = '../system/plugins';
    set_include_path( get_include_path().PATH_SEPARATOR.$path );
    require_once $path.'/Zend/Loader.php';
    Zend_Loader::registerAutoload();

    Zend_Pdf::load('test.pdf');

  5. @mvug
    As mentioned above Zend_Loader::registerAutoload() is deprecated. So I dont think its useful to give hints for this feature since now ;)

  6. When you say:
    'If you need generic autoloading ability, for instance because your models directory is on your include path and you don't namespace your model classes, then add this:'

    What do you mean by namespacing model classes? What is the best practice here?

    Thanks.

  7. benr,

    Best practice for an article model in a CMS module would be to call it Cms_Model_Article or similar. This would make it less likely to conflict with another class when moving your CMS module to a different app.

    Regards,

    Rob…

  8. Maybe im an idiot, but I cant seem to get this working…

    My code looks like the following (note I have uncommented and commented different portions unsuccessfully)

    require_once "Zend/Loader/Autoloader.php";
    //require_once "doctrine/Doctrine.php";

    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('Wfm_');
    $autoloader->setFallbackAutoloader(true);

    //$autoloader->pushAutoloader(array('Doctrine', 'autoload'), 'Doctrine');

    I have a folder in my /library called Wfm with a number of classes, however, it fatals out on the first inclusion of a Wfm_ prefixed file. The path looks like…

    /library/Wfm/Layout/Controller/Plugin/Layout.php – However, it complains that it cannot find the file, or the class does not exist within the file. My PHP include path includes the library folder – am I just missing something obvious here?

  9. Ben,

    Assuming the class is called Wfm_Layout_Controller_Plugin_Layout within layout.php, I can't see anything obvious. Sorry.

    I'd double check the output of get_include_path() too.

    Regards,

    Rob…

  10. Rob,

    Thanks for the quick response. Unless ive gone absolutely mad, im 100% sure that the file is there. I copied the entire Wfm folder from another project where it worked without issue.

    It seems, at this point, to only be an issue with that file, as odd as that sounds, if I remove the line in the bootstrap:

    Zend_Layout::startMvc(array(
    'layoutPath' => APP_DIR . DS . 'layouts',
    'pluginClass' => 'Wfm_Layout_Controller_Plugin_Layout'
    ));

    Then it loads up saying it cant find the index controller which makes sense because its a new project – it doesnt fatal out, so I assume its working.

    The include path looks correct, here is the first portion of it… Warning: include() [function.include]: Failed opening 'WfmLayoutControllerPluginLayout.php' for inclusion (include_path='C:WorkspaceProjectsXXXXXXsitelibrary;

    Excluding other include path's – that one right there should cover it assuming the file is in C:WorkspaceProjectsXXXXXXsitelibraryWfmLayoutControllerPluginLayout.php

    I guess the last thing I can say is that this entire config, file structure, etc works on pre 1.8 applications without fail.

  11. Hi,
    Thanks for your tutorial. Found it really helpful.
    It's a shame the ZF manual doesn't explain this in such a simple, straight forward way.

  12. Hey Rob, thanks for your great article (again) :)

    I upgraded to 1.8.3 and got the above mentioned error message.

    Am I right when this:
    include_once('Zend/Loader/Autoloader.php');
    $loader = Zend_Loader_Autoloader::getInstance();
    $loader->setFallbackAutoloader(true);
    $loader->suppressNotFoundWarnings(false);

    Is the same as the previously used:
    include_once('Zend/Loader.php');
    Zend_Loader::registerAutoload();

    It appears to be that way in my current app.

  13. GP,

    Yes. I suspect that suppressNotFoundWarnings may be set to false by default nowadays, but it never hurts to be explicit.

    Regards,

    Rob…

  14. Recently I started to get familiar with the MVC and I was recomended to work with Zend Framework, but it has taken me several days trying to configure the Boostrap.php, the .htacces and index.php on public folder, so far it works for the IndexController and ErrorController, but when adding new controllers is not very clear how should I call them, because I can not even define who is the front controller, I need a basic setup to begin to develop an application, the base. Could someone help me?

  15. guelmismr>>>
    http://akrabat.com/zend-framework-tutorial/
    Try the new 1.8 version of Rob's Tutorial it looks fresh and easy, will begin to poke holes on my punch cards tomorrow before running the codes :-)

    By the way guelmismr it has taken me around 360 days (~12 months) to configure LAMP/WAMP, Bootstrapper, .htaccess, index.php, reading the basic chapters of ZFiA etc. etc.

    I still haven't been able to play with the HTML and CSS part yet, maybe tomorrow when my punch cards are hot and ready :-)

  16. I am currently redoing my website using zend framework and chose your book. The zf version is 1.9.7 . Page 71…The baseUrl View Helper. The getBaseUrl() now includes index.php in 1.9.7…so you need to strip it out in the view helper:
    i.e.
    class Places_View_Helper_BaseUrl
    {
    function baseUrl()
    {
    $fc = Zend_Controller_Front::getInstance();
    $baseUrlWithIndex = $fc->getBaseUrl();

    $base_url = substr($_SERVER['PHP_SELF'], 0, -9);
    return $this->_baseUrl = $base_url;
    }
    }

  17. Using ZF 1.10.1 and Zend_Tool.

    Listing 2.1 differs greatly from the index.php file that Zend_Tool places in the public folder.

    Have things changed that much since ZF 1.5? Can I still use this book?

  18. Frank,

    Yes the book is still useful for ZF development. However, the MVC chapters, (2, 3 & 4) are less useful nowadays. Essentially, you need to go through my tutorial and then look at how 2,3,4 differ.

    Regards,

    Rob…

  19. Site error: the file /affiliate/idevaffiliate.php requires the ionCube PHP Loader ioncube_loader_fre_4.3.so to be installed by the site administrator.

    When trying to see either book from http://www.zendframeworkinaction.com/.

    Thanks for the mvc tutorial. Will there be an up-to-date edition of the book (or an electronic version that is always up to date) soon?

  20. Thanks, Rob. I've worked through your excellent tutorial, but it's not apparent to me what changes are needed in chapters 2 through 4 of your book to make it compatible with ZF1.10.4.

    I've set up my virtual hosts to point to places:81, I know I've got that part right.

    Here's my public/index.php file:

    // places/public/index.php

    bootstrap()
    ->run();

    Here's my public/application/configs/appplication.ini file:

    ; ~/Sites/places/application/configs/application.ini

    [production]
    phpSettings.display_startup_errors = 0
    phpSettings.display_errors = 0
    includePaths.library = APPLICATION_PATH "/../library"
    includePaths.models = APPLICATION_PATH "/../models"
    bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
    bootstrap.class = "Bootstrap"
    appnamespace = "Application"

    resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
    resources.frontController.params.displayExceptions = 0

    db.adapter = PDO_MYSQL
    db.params.host = localhost
    db.params.username = nan
    db.params.password = cooper
    db.params.dbname = places
    date_default_timezone = "America/Los_Angeles"
    debug = 0

    [staging : production]

    [testing : production]
    phpSettings.display_startup_errors = 1
    phpSettings.display_errors = 1
    debug = 1

    [development : production]
    phpSettings.display_startup_errors = 1
    phpSettings.display_errors = 1
    resources.frontController.params.displayExceptions = 1

    db.params.dbname = places_test

    Here's my places/application/Bootstrap.php file:

    // ~/Sites/places/application/Bootstrap.php

    registerNamespace('Places_');
    //$loader->setFallbackAutoloader(true);
    //$loader->suppressNotFoundWarnings(false);

    // Load configuration
    Zend_Registry::set('configSection', $configSection);
    $config = new
    Zend_Config_Ini(ROOT_DIR.'/application/configs/application.ini',
    $configSection);
    Zend_Registry::set('config', $config);

    date_default_timezone_set($config->date_default_timezone);

    // configure database and store to the registery
    $db = Zend_Db::factory($config->db);
    Zend_Db_Table_Abstract::setDefaultAdapter($db);
    Zend_Registry::set('db', $db);
    }

    public function configureFrontController()
    {
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->setControllerDirectory(ROOT_DIR .
    '/application/controllers');
    }

    public function runApp()
    {
    // setup front controller
    $this->configureFrontController();

    // run!
    $frontController = Zend_Controller_Front::getInstance();
    $frontController->dispatch();
    }
    }

    My places/application/controllers/IndexController.php file:

    view->title = 'Welcome to Places to take the kids!';
    $placesFinder = new Places();
    $this->view->places = $placesFinder->fetchLatest();
    }
    }

    The places/tests/models/PlacesTest.php file:

    // places/tests/models/PlacesTest.php

    fetchAll();

    // Check that row count is correct
    $this->assertSame(3, $places->count());
    }

    public function testFetchLatestShouldFetchMostRecentEntriesInReverseOrder()
    {
    $placesFinder = new Places();
    $places = $placesFinder->fetchLatest(1);

    $this->assertSame(1, $places->count());

    $thisPlace = $places->current();
    $this->assertSame(2, (int)$thisPlace->id);
    }
    }

    And finally, places/tests/TestConfiguration.php:

    // places/tests/TestConfiguration.php

    date_default_timezone);

    // set up database
    $db = Zend_Db::factory($config->db);
    Zend_Db_Table::setDefaultAdapter($db);
    Zend_Registry::set('db', $db);

    }

    static function setupDatabase()
    {
    $db = Zend_Registry::get('db'); /* @var $db Zend_Db_Adapter_Abstract */

    $db->query(<<query(<<query(<<query(<<query(<<query(<<<EOT
    INSERT INTO reviews (places_id, body, rating, date_created, date_updated)
    VALUES
    (1, 'The facilities here are really good. All the family enjoyed it', 4, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(1, 'Good day out, but not so many big animals now.', 2, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(1, 'Excellent food in the cafeteria. Even my 2 year old ate her lunch!', 4, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(2, 'Good for teenagers!', 2, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(2, 'A great family day out, but lots of queues!', 2, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(2, 'A fun day was had by our family!', 2, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ,(3, 'Our children enjoyed learning some of the history!', 3, '2007-02-14 00:00:00', '2007-02-14 00:00:00')
    ;
    EOT
    );
    }
    }

    For the life of me, I can't figure out why running phpunit models_PlacesTest results in the following output:

    fd:tests frank$ phpunit models_PlacesTest
    PHP Warning: include_once(/Users/frank/Sites/places/tests): failed to open stream: No such file or directory in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110

    Warning: include_once(/Users/frank/Sites/places/tests): failed to open stream: No such file or directory in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110
    PHP Warning: include_once(): Failed opening '/Users/frank/Sites/places/tests' for inclusion (include_path='.:/usr/local/PEAR:/ZF/library:/opt/local/lib/php/library/Zend/Test') in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110

    Warning: include_once(): Failed opening '/Users/frank/Sites/places/tests' for inclusion (include_path='.:/usr/local/PEAR:/ZF/library:/opt/local/lib/php/library/Zend/Test') in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110
    PHP Notice: Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /Users/frank/Sites/places/library/Zend/Loader.php on line 266

    Notice: Zend_Loader::Zend_Loader::registerAutoload is deprecated as of 1.8.0 and will be removed with 2.0.0; use Zend_Loader_Autoloader instead in /Users/frank/Sites/places/library/Zend/Loader.php on line 266
    PHP Warning: include_once(/Users/frank/Sites/places/application/models): failed to open stream: No such file or directory in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110

    Warning: include_once(/Users/frank/Sites/places/application/models): failed to open stream: No such file or directory in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110
    PHP Warning: include_once(): Failed opening '/Users/frank/Sites/places/application/models' for inclusion (include_path='/Users/frank/Sites/places/application/models/:/Users/frank/Sites/places/library/:/Users/frank/Sites/places/library:.:/usr/local/PEAR:/ZF/library:/opt/local/lib/php/library/Zend/Test') in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110

    Warning: include_once(): Failed opening '/Users/frank/Sites/places/application/models' for inclusion (include_path='/Users/frank/Sites/places/application/models/:/Users/frank/Sites/places/library/:/Users/frank/Sites/places/library:.:/usr/local/PEAR:/ZF/library:/opt/local/lib/php/library/Zend/Test') in /usr/local/PEAR/PHPUnit/Util/Fileloader.php on line 110
    PHPUnit 3.4.13 by Sebastian Bergmann.

    ..

    Time: 0 seconds, Memory: 10.00Mb

    OK (2 tests, 3 assertions)

    include_once hasn't been used in any of the above files. And, all of the files and directories mentioned in /usr/local/PEAR/PHPUnit are present.

    Is there any chance you can update the code to work with ZF1.10?

    Thanks!

  21. This is driving me batty!

    How should we modify the following line of code for the Places application?:

    $loader->registerNamespace('App_');

  22. I created my project with ZF 1.11.5 (as in the zf-tutorial). My Bootstrap has the following lines of code:

    require_once 'Zend/Loader/Autoloader.php';
    $loader = Zend_Loader_Autoloader::getInstance();
    $loader->setFallbackAutoloader(true);
    $loader->suppressNotFoundWarnings(false);

    Pointing my browser to "places" results in the following PHP error:

    Fatal error: Call to a member function getDefaultModule() on a non-object in /Users/frank/Sites/places/library/Zend/Application/Bootstrap/Bootstrap.php on line 89

    What's up with that? Aren't I already using the "fallback" namespace?

    And can we PLEASE get updated code for ZF 1.11.5!

Comments are closed.