0
votes

I have a project that was developed without namespaces and with a "private framework" written by my team at the time. Said framework depends on an autoload function that includes files from within the framework and automatically finds files inside the project, which means that inside the project we have 0 includes/requires. Every file follows a specific rule and gets included by my function.

Everytime we would use third-party library, we would download the files and place them at a specific place and work on getting the files property loaded.

This week I found a new library I wanted to use, so I decided to install it via composer. Now my autoload function doesn't exist and my framework stops any execution at the begin for missing files.

How do I go about keeping my autoload as is (that includes files without namespaces from my project and my framework) and still use composer? Is it possible or I'm dead?


Edit: Adding some files to the question.

frameworkBootstrap - This file loads the framework (works just fine).

<?php

$dir = dirname(__FILE__);
// Database Package
require $dir . '/nav/database/NavDao.php';
require $dir . '/nav/database/NavDatabase.php';
require $dir . '/nav/database/NavTable.php';

// General
require $dir . '/nav/general/NavLanguage.php';
require $dir . '/nav/general/NavProject.php';
require $dir . '/nav/general/NavController.php';

// Tool
require $dir . '/nav/tool/NavValidator.php';
require $dir . '/nav/tool/NavLogger.php';
require $dir . '/nav/tool/NavListener.php';
require $dir . '/nav/tool/NavFile.php';
require $dir . '/nav/tool/NavEmail.php';
require $dir . '/nav/tool/NavException.php';

// View
require $dir . '/nav/view/NavPage.php';
require $dir . '/nav/view/NavTemplate.php';
require $dir . '/nav/view/NavView.php';

// Request
require $dir . '/nav/request/NavRequest.php';
require $dir . '/nav/request/NavAccess.php';
require $dir . '/nav/request/NavResponse.php';
require $dir . '/nav/request/NavSession.php';

// Plugin
NavProject::plugin(
        array(
            'NavMail' => $dir . '/nav/plugin/email/NavMail.php',
            'NavXPertMailer2006' => $dir . '/nav/plugin/email/NavXPertMailer2006.php',
            'NavLog' => $dir . '/nav/plugin/log/NavLog.php',
            'NavImage' => $dir . '/nav/plugin/file/NavImage.php',
            'NavMysql' => $dir . '/nav/plugin/dbms/NavMysql.php',
            'NavOracle' => $dir . '/nav/plugin/dbms/NavOracle.php',
            'NavTranslate' => $dir . '/nav/plugin/translate/NavTranslate.php'
));

require $dir . '/vendor/autoload.php';
?>

Autoload funciton - This funciton is being replaced.

function __autoload($className) {
    $file = '';

    // Auto Load Template
    if (strpos($className, 'Template') !== false)
        $file = NavProject::path() . 'class/view/template/' . $className . '.php';

    // Auto Load Project Tools
    else if (strpos(strtolower($className), strtolower(NavProject::name())) !== false)
        $file = NavProject::path() . 'class/tool/' . $className . '.php';

    // Auto Load Controllers
    else if (strpos($className, 'Controller') !== false)
        $file = NavProject::path() . 'class/control/' . $className . '.php';

    // Auto Load Nav Plugin
    else if (strpos($className, 'Nav') === 0) {
        $list = NavProject::plugin();
        foreach ($list as $plugin => $location)
            if ($plugin == $className)
                $file = $location;

        // Auto Load Model
    } else {
        $file = NavProject::path() . 'class/model/' . $className . '.php';
    }

    if (is_file($file))
        require $file;
}

3rd-party library

https://github.com/alexshelkov/SimpleAcl

3
Can you show us code of auto loading and including auto loader...VeeeneX
@VeeeneX I just edited the main question. Is that what you had in mind?Marco Aurélio Deleu
Yes, and where did you added composer autoload file?VeeeneX
@VeeeneX sorry about that. I added it at the end of the FrameworkBootstrap (after the plugins) require $dir . '/vendor/autoload.php'; . The file that has my autoload function is the NavRequest, also loaded by the FrameworkBoostrap (5th group, 1st file).Marco Aurélio Deleu
Ok, no try replacing __autoload with spl_autoload_register();VeeeneX

3 Answers

2
votes

You should go the slightly longer route and replace your own autoloading with that of Composer.

Short-term you'd be able to use the classmap feature to autoload every existing code:

"autoload": {
    "classmap": 
        ["class/view/template/","class/tool/","class/control/","class/model", "nav/"]
}

The classmap should contain every directory that you have classes in, and the path should be relative from the top level directory where you place your own composer.json.

You'd then remove your own __autoload function (there can be only one defined, and if you do, you cannot have another libraries autoloading active at the same time - the way to do autoloading even long before Composer was to use the "spl_autoload" feature), and you'd also remove every require statement in your framework bootstrap, and replace it with require "vendor/autoload.php";. After autoloading is included, you have access to every class in the classmap of your own code, and to every library you add.

You have to run composer install once to create the classmap.

If you create new classes after this, you again have to run composer dump-autoload to refresh the map. If this gets annoying to you, think about switching to using PSR-0 autoloading instead. I think it's doable with your code base already, but I'm reluctant to suggest something without knowing what your class naming conventions really are.

For example, the autoloader will assume that any class that has "Template" SOMEWHERE in it's name is located in the "class/view/template" folder. This includes TemplateHomepage as well as HomepageTemplate as well as PageTemplateHome. Your autoloader allows for a multitude of names to be loaded, but I suppose you are only using one scheme.

1
votes

Try replacing __autoload with spl_autoload_register();

Why?

__autoload(); is discouraged and may be deprecated or removed in the future from docs.

This function can collide with spl_autoload_register() which is used by composer.

0
votes
spl_autoload_register('my_autoload', false, true);  

Then replace __autoload to my_autoload.