如何在具有自动加载功能的项目中开始使用作曲家?

how to start using composer at a project that has autoload function?

我有一个项目是在没有名称空间的情况下开发的,并且 "private framework" 当时由我的团队编写。所述框架依赖于自动加载功能,该功能包括框架内的文件并自动在项目内查找文件,这意味着在项目内我们有 0 includes/requires。每个文件都遵循特定规则并被我的函数包含。

每次我们使用第三方库时,我们都会下载文件并将它们放在特定位置,然后努力加载文件 属性。

这周我发现了一个我想使用的新库,所以我决定通过 composer 安装它。现在我的自动加载功能不存在并且我的框架在开始时停止执行丢失的文件。

如何保持我的自动加载(包括我的项目和我的框架中没有名称空间的文件)并仍然使用作曲家?有可能还是我死了?


编辑:向问题添加一些文件。

frameworkBootstrap - 此文件加载框架(工作正常)。

<?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';
?>

自动加载功能 - 此功能正在被替换。

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;
}

第 3 方库

https://github.com/alexshelkov/SimpleAcl

你应该走稍微长一点的路线,用 Composer 的自动加载替换你自己的自动加载。

短期内您可以使用 classmap 功能自动加载每个现有代码:

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

class映射应该包含您拥有 class 的每个目录,并且路径应该是您放置自己的 composer.json 的顶级目录的相对路径。

然后您将删除您自己的 __autoload 函数(只能定义一个,如果您这样做,您不能同时激活另一个库自动加载 - 自动加载的方式甚至很长在 Composer 使用 "spl_autoload" 功能之前),您还需要删除框架 bootstrap 中的每个 require 语句,并将其替换为 require "vendor/autoload.php";。包含自动加载后,您可以访问您自己代码的 class 映射中的每个 class,以及您添加的每个库。

您必须 运行 composer install 一次才能创建 class 地图。

如果您在此之后创建新的 classes,您必须再次 运行 composer dump-autoload 来刷新地图。如果这让您感到厌烦,请考虑改为使用 PSR-0 自动加载。我认为你的代码库已经可行了,但我不愿意在不知道你的 class 命名约定真正是什么的情况下提出建议。

例如,自动加载器将假定名称中包含 "Template" SOMEWHERE 的任何 class 都位于 "class/view/template" 文件夹中。这包括 TemplateHomepage 以及 HomepageTemplatePageTemplateHome。您的自动加载器允许加载多个名称,但我想您只使用了一种方案。

尝试用 spl_autoload_register();

替换 __autoload

为什么?

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

此函数可能会与 composer 使用的 spl_autoload_register() 发生冲突。

spl_autoload_register('my_autoload', false, true);  

然后将__autoload替换为my_autoload.