【问题标题】:Loading Classes without Composer (Autoloader) - Not found在没有 Composer 的情况下加载类(自动加载器) - 未找到
【发布时间】:2019-01-22 07:51:17
【问题描述】:

我不能使用作曲家,所以我必须以不同的方式来做,最初我使用 require_once 来加载每个单独的类,但也没有成功,所以现在我正在使用自动加载器,但我仍然面临相同或相似的问题:

它开始的页面:

<?php
declare(strict_types=1);

require __DIR__ . '/ERC20/autoload.php';
use ERC20\ERC20;
use ERC20\EthereumRPC;
$geth = new EthereumRPC('127.0.0.1', 8545);

这是自动加载文件:

<?php
spl_autoload_register(function($class){

    $path = __DIR__ . '/' . $class . '.php';

    if(file_exists($path))
        require $path;
});
?>

这些类存储在名为 ERC20 的文件夹中,该文件夹与客户端帐户 php 文件位于同一目录中。

这是它抛出的错误:

致命错误:未捕获的错误:类 'ERC20\EthereumRPC' 未在 /home/sewicumg/public_html/contenthourlies.com/wp-content/themes/seoexp/account_client.php:35

第 35 行是这一行:

$geth = new EthereumRPC('127.0.0.1', 8545);

文件 EthereumRPC.php 存在于 ERC20 文件夹中,我使用的是 PHP7.1

有人建议使用自动加载器,所以我就这么做了,但到目前为止无济于事。

【问题讨论】:

  • 附加 var_dump($path)
  • string(99) "/home/sewicumg/public_html/contenthourlies.com/wp-content/themes/seoexp/ERC20/ERC20\EthereumRPC.php"
  • 我也去掉了两条 use 行:use ERC20\ERC20;使用 ERC20\EthereumRPC;,这样它会打印正确的路径,但我仍然会遇到找不到类的错误。
  • 你能告诉我们命名空间是如何在你的以太坊类中定义的吗?
  • string(93) "/home/sewicumg/public_html/contenthourlies.com/wp-content/themes/seoexp/ERC20/EthereumRPC.php" 致命错误:未捕获错误:未找到“EthereumRPC”类在 /home/sewicumg/public_html/contenthourlies.com/wp-content/themes/seoexp/account_client.php:34 堆栈跟踪:#0 /home/sewicumg/public_html/contenthourlies.com/wp-includes/template-loader.php (74): include() #1 /home/sewicumg/public_html/contenthourlies.com/wp-blog-header.php(19): require_once('/home/sewicumg/...')

标签: php class autoloader


【解决方案1】:

我看到您已经通过其他方式解决了您的问题。不过我想我也可以添加一些东西。

afaik,当您将spl_autoload_register 与命名空间一起使用时,您将获得类名和命名空间。

这就是您在打印$path 时得到以下信息的原因:

/home/sewicumg/public_html/contenthourlies.com/wp-content/themes/seoexp/ERC2/ERC20\EthereumRPC.php

您可以在上面的粗体部分看到命名空间。

因此,维护与您的命名空间匹配的文件夹结构是一个很好的理由。您可以修改文件夹结构以匹配命名空间,而不是创建供应商目录和创建新的 autolader。这将为您提供一个更易于维护的漂亮文件夹结构。

所以在你的情况下,要解决它,你可以这样做:

假设您最初有这个文件夹结构;

.
├── ERC20
│   ├── autoload.php
│   └── EthereumRPC.php
└── index.php

现在,当您使用自动加载器时,它会收到 ERC20\EthereumRPC.php 的类名(显然加载失败)。因此,我将创建一个名为 classes 的文件夹,并将我的所有类文件放在相关文件夹中(以匹配它们的命名空间)。

.
├── classes
│   ├── autoload.php
│   └── ERC20
│       └── EthereumRPC.php
└── index.php

然后我会稍微修改我的index.php文件和autoload.php文件如下:

index.php

require __DIR__ . '/classes/autoload.php';

autoload.php

spl_autoload_register(function ($class) {

    $class = str_replace("\\", DIRECTORY_SEPARATOR, $class);
    $path = __DIR__ . '/' . $class . '.php';

    if (file_exists($path)) {
        require $path;
    }
});

这里唯一的区别是我用DIRECTORY_SEPARATOR替换了命名空间中的反冲。

就是这样,这应该可以正常工作:) 我希望它有所帮助。如果您有任何疑问,请随时询问!

【讨论】:

  • 谢谢,但我很高兴这部分是在谷歌搜索两天后完成的,并尝试了各种解决方案。现在是十六进制问题,但那是另一个线程,并在另一天先把自己弄乱了。我对 PHP 知之甚少,但通常足以完成任务,但是这个库的东西,以及我遇到的新 JSON 标头问题是完全不同的 :)
【解决方案2】:

鉴于您已经纠正了该问题,我发布此内容是为了创建一个更持久、更优雅的解决方案,希望它不会成为您反复出现的问题。

首先,看看the example autoloaders from the PSR-4 spec。您会注意到,在基于闭包的自动加载器和基于类的自动加载器中,它们都以对应用程序文件夹的永久相对引用(在相对于其声明,并且在类示例中手动传入),并扩展供应商/包对以源自随后命名的文件夹对相对于应用程序文件夹.

这意味着您需要做几件事:

1) 声明一个固定常量,表示您的应用程序根目录或供应商目录的路径在第一个加载的文件中

define('VENDOR_DIR', __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR);

2) 手动包含您的自动加载器声明文件并初始化自动加载器。例如,如果您使用来自PSR-4 spec 的类,那么您可以这样做:

包括 DIR 。 '/path/to/autoloader.php'; $autoloader = 新 \Psr4AutoloaderClass(); $autoloader->register();

3) 接下来,您将遍历所需的包并单独注册它们:

foreach (glob(VENDOR_DIR, GLOB_ONLYDIR) as $vendor)
{
    // Remaining valid directories are your vendor scope, by psr-4 spec
    foreach (glob($vendor, GLOB_ONLYDIR) as $package)
    {
        // This is your package scope, which needs to be contencated with the vendor name to create the base package namespace
        $pkg = $vendor . '\\' . $package;
        $path = VENDOR_DIR . DIRECTORY_SEPARATOR // The relative path from the first file
            . $vendor . DIRECTORY_SEPARATOR      // The vendor scope
            . $package . DIRECTORY_SEPARATOR;    // The package scope
        // Register the package
        $autoloader->addNamespace($pkg, $path);
}

// That's all, you're done.

您的目录结构应如下所示:

root
|-index.php
|-vendor
  |
  |-vendor_name
    |
    |-package_name

【讨论】:

    【解决方案3】:

    我通过创建一个名为Vendor 的新文件夹来修复它,将ERC20 文件夹移到该文件夹​​中,并将autoload.php 也移到那里。

    我还使用了在 Youtube 上找到的不同的自动加载,现在所有类都可以正常加载。

    这是自动加载代码:

    <?php
    
    spl_autoload_register(function($class){
    
        $prefix = 'ERC20\\';
        $length = strlen($prefix);
        $path = __DIR__ . '/ERC20/';
    
        if (strncmp($prefix, $class, $length) !==0) {
            return;
        }
    
        $relative_class = substr($class, $length); 
        $file = $path . str_replace ('\\', '/', $relative_class) . '.php';
    
        if(file_exists($file)) {
            require $file;
        }
    });
    
    ?>
    

    这就是我在页面中调用自动加载文件的方式:

    require 'vendor/autoload.php';
    

    【讨论】:

      猜你喜欢
      • 2017-02-28
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      • 2020-01-21
      • 2018-06-01
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      相关资源
      最近更新 更多