【问题标题】:Integrate Composer with existing project autoloader将 Composer 与现有项目自动加载器集成
【发布时间】:2021-03-23 17:28:38
【问题描述】:

我正在更新一个项目,我决定更新我的 Twig 版本。由于您现在需要使用 Composer,因此我过去故意没有更新它,但我最终屈服于这一点并决定安装更新的版本。

但是,它弄乱了我的 Autoload 功能并且没有正确加载 Twig,我真的不想使用它。在一个只有自动加载 Composer 的代码的空白文件中,它可以工作,所以我知道我的自动加载器发生了冲突。我可以看到我将不得不在某种程度上使用它,因为 Twig 现在需要它。我只对将它用于第三方代码感兴趣,我不想将它用于其他任何事情。所以我正在寻找的是我自己的自动加载器先尝试,然后如果我无法通过自己的方式加载类,则尝试使用 Composer 自动加载器。第三方代码存在于“Lib”的子目录中。所以对于 Twig,它位于 Lib/vendor/twig/twig/src 中。

目前,我正在检查命名空间的第一部分,如果它与我自己的不匹配,我正在尝试在 Lib/vendor/autoload.php 中加载 Composer autoload.php 文件,然后返回我的自动加载功能。但这似乎没有找到课程。

我正在尝试做的事情真的可能吗?我将如何处理这样的事情?

** 编辑 - 当前自动加载器 **

public static function autoloader($classname)
{
    /* Separate by namespace */
    $bits = explode('\\', ltrim($classname, '\\'));
    $vendor = array_shift($bits);

    /* If this doesn't belong to us, ignore it */
    if ($vendor !== 'Site')
    {
        // We don't want to interfere here
        if ($vendor == 'Forum')
            return;

        // Try to see if we can autoload with Composer, if not abort
        include_once(SITE_ROOT.'include/Lib/vendor/autoload.php');
print_r(spl_autoload_functions ( ));
        return;
    }

    $class = array_pop($bits);
    $namespace = empty($bits) ? 'Site' : ('Site\\'.implode('\\', $bits));

    $sources_dir = false;
    $path = SITE_ROOT.'include/';
    foreach (array_merge($bits, array($class)) as $i => $bit)
    {
        if ($i === 0 && $bit == 'Lib')
        {
            $bit = mb_strtolower($bit);
            $sources_dir = true;
        }
        else if (preg_match("/^[a-z0-9]/", $bit)) // Applications only contain lowercase letters
        {
            if ($i === 0)
                $path .= 'apps/';
            else
                $sources_dir = true;
        }
        else if ($i === 1 && ($bit == 'Api' || $bit == 'Cli' || $bit == 'Ajax')) // The API/CLI/AJAX interfaces have slightly different rules ....
        {
            $bit = mb_strtolower($bit);
            $sources_dir = true;
        }
        else if ($sources_dir === false)
        {
            if ($i === 0)
            {
                $path .= 'components/';
            }
            else if ($i === 1 && $bit === 'Application')
            {
                // Do nothing
            }
            else
            {
                $path .= 'sources/';
            }

            $sources_dir = true;
        }

        $path .= $bit.'/';
    }

    /* Load it */
    $path = \substr($path, 0, -1).'.php';
    if (!file_exists($path))
    {
        $path = \substr($path, 0, -4).\substr($path, \strrpos($path, '/'));
        if (!file_exists($path))
        {
            return false;
        }
    }

    require_once($path);

    if (interface_exists("{$namespace}\\{$class}", FALSE))
    {
        return;
    }

    /* Doesn't exist? */
    if (!class_exists("{$namespace}\\{$class}", FALSE))
    {
        trigger_error("Class {$classname} could not be loaded. Ensure it has been properly prefixed and is in the correct namespace.", E_USER_ERROR);
    }
}

【问题讨论】:

  • 您当前的自动加载效果如何?
  • 我已经更新了我的问题并添加了代码!

标签: php twig composer-php


【解决方案1】:

在自定义自动加载中加载 Composer 的 autoload.php 可能为时已晚。

您不必太担心性能问题,只需依次加载自定义自动加载器和 Composer 的自动加载器即可。您可以根据您将更频繁地加载哪些类(您自己的或通过 Composer 安装的类)对这些自动加载器进行优先级排序,从而进行一些优化。

此外,您自己的/自定义的自动加载器应该只关心成功加载,如果没有找到,则不要抛出错误。把它留给 PHP,这有助于与其他自动加载器的兼容性。

【讨论】:

    猜你喜欢
    • 2014-10-11
    • 2011-12-07
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 2013-08-09
    相关资源
    最近更新 更多