不使用Composer加载类(自动加载器)-找不到

时间:2018-08-15 12:23:58

标签: php class autoloader

我无法使用composer,所以我必须以不同的方式进行操作,最初我使用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

有人建议使用自动装带器,这就是我所做的,但到目前为止没有用。

3 个答案:

答案 0 :(得分:0)

我通过创建一个名为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';

答案 1 :(得分:0)

我看到您已经通过其他方法解决了您的问题。但是我认为我也可以添加一些东西。

afaik,当您将spl_autoload_register与名称空间一起使用时,您将获得类名称以及名称空间。

这就是打印$path时得到以下内容的原因:

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

您会在上方的粗体部分看到名称空间。

因此,有充分的理由来维护与您的命名空间匹配的文件夹结构。您可以只修改文件夹结构以匹配名称空间,而不是创建供应商目录并创建新的自动梯形图。这将为您提供一个很好的文件夹结构,并且也更易于维护。

因此,要解决此问题,可以执行以下操作:

假设您最初具有此文件夹结构;

.
├── 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替换了命名空间中的反冲。

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

答案 2 :(得分:0)

鉴于您已经纠正了该问题,我希望发布此消息是为了创建一个更永久,更优雅的解决方案,希望它不会对您造成重复性的问题。

首先,看看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