【问题标题】:PHP - Doctrine - How to autoload entities classes using a single namespacePHP - Doctrine - 如何使用单个命名空间自动加载实体类
【发布时间】:2017-04-10 17:29:58
【问题描述】:

我有一组包含类(实体)的 PHP 文件。每个类都有相同的命名空间:

// src/App/Entity/Actions.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Actions
 *
 * @ORM\Entity
 */
class Actions
{
// SOME CODE

我使用 composer 自动加载包含类的 PHP 文件:

"autoload": {
    "psr-0": {
        "App": "src/"
    }
}

在我的 bootstrap.php 文件中,我添加了这一行:

 use App\Entity;

所以我想因为告诉应用程序使用 App\Entity 命名空间,我可以像这样调用实体类:$entity = new Actions();

但是当我尝试这样做时,我得到了这个错误:

致命错误:第 49 行的 C:\wamp64\www\spider\chebi2\inc\orm_tools.php 中找不到类“操作”

如果我这样做:

use App\Entity; use App\Repository;

if (class_exists('Actions')) { dump('exists'); } else { dump('not exists'); }

if (class_exists('\App\Entity\Actions')) { dump('exists'); } else { dump('not exists'); }

这是它的输出:

PS C:\wamp64\www\spider\chebi2> php .\get_actions.php
"not exists"
"exists"

所以它只有在我提供完整的命名空间时才能找到该类。奇怪的是,当我尝试这个时:

// Direct path to the Actions.php file
use App\Entity\Actions;

if (class_exists('Actions')) { dump('exists'); }
else { dump('not exists'); }

if (class_exists('\App\Entity\Actions')) { dump('exists'); }
else { dump('not exists'); }

我得到相同的结果:

PS C:\wamp64\www\spider\chebi2> php .\get_actions.php
"not exists"
"exists"

所以现在我更加困惑了。使用use App\Entity; 的意义何在?如果它实际上并没有使该命名空间中的类直接可用?为什么将直接路径分配给use App\Entity\Actions; 类甚至不起作用?

我在这里做错了吗?有没有正确的方法来使用我不理解的命名空间?

【问题讨论】:

    标签: php namespaces psr-0


    【解决方案1】:

    PSR-0 已弃用,您应该使用 PSR-4

    在 PSR-4 中

    composer.json

    "autoload": {
        "psr-4": {
             "App\\": "src/",
        }
     }
    

    在与composer.json同一级别的目录src/中添加目录Entity所以在路径src/Entity中添加类文件Actions

    namespace App\Entity;
    
    class Actions
    {
    
    }
    

    您也可以使用 composer dump-autoload 并检查 vendor/composer/autoload* 文件,看看是否在此处注册了命名空间。'

    关于class_exists() 它不适用于短名称或别名,您需要提供类的全名。我建议使用::class 运算符所以在你的情况下它会是:

    <?php
      use App\Entity\Actions;
    
      class_exists(Actions::class);
    

    【讨论】:

      【解决方案2】:

      谢谢!我将自动加载器更改为 psr-4,并将其附加到此:

        "psr-4": {
             "App\\": "src/"
        }
      

      dump-autoload 正是我想要的,但我没有看到列出的任何包含的文件或类:

          PS C:\wamp64\www\spider\chebi2> composer dump-autoload -vvv
          Reading ./composer.json
          Loading config file ./composer.json
          Checked CA file C:\Users\horse\AppData\Local\Temp\composer-cacert-12fdaece071ee9515fa28aabed5ab089876ae257833106e15a583e060eaff6b5.pem: valid
          Executing command (C:\wamp64\www\spider\chebi2): git branch --no-color --no-abbrev -v
          Executing command (C:\wamp64\www\spider\chebi2): git describe --exact-match --tags
          Executing command (C:\wamp64\www\spider\chebi2): git log --pretty="%H" -n1 HEAD
          Reading C:/Users/horse/AppData/Roaming/Composer/composer.json
          Loading config file C:/Users/horse/AppData/Roaming/Composer/composer.json
          Reading C:\wamp64\www\spider\chebi2/vendor/composer/installed.json
          Reading C:/Users/horse/AppData/Roaming/Composer/vendor/composer/installed.json
          Running 1.2.2 (2016-11-03 17:43:15) with PHP 5.6.25 on Windows NT / 10.0
          Generating autoload file
      

      我仍然找不到实体类。

      为了澄清,我应该有这样的文件夹结构:

       - src (contains only subdirectories)
           - Entity (contains the entity files)
           - Repositories
           - App (empty)
      

      【讨论】:

      • '/vendor/autoload.php';
      • autoload.php文件本身只有两行,但是我查看了vendor/composer/autoload_psr4.php文件,它列出了composer.json 文件,但没有列出任何应该使用 psr4 自动加载器自动加载的文件。在 autoload_namespaces.php 中,它没有列出我添加的任何命名空间。当我运行 composer diagnostic 时,其中的一行是:The property psr-4 is not defined and the definition does not allow additional properties
      • 所以经过一番阅读,我似乎误解了use some\namespace; 命令的作用。我认为use App\Entity; 会将该命名空间中的每个类的名称加载到全局变量中,但实际上所做的是创建为名为 Entity 的别名。因此,我需要像这样调用 \Entity\Actions 类。不过我不明白,因为看到我通过composer安装了很多不同的组件,我添加了use path\to\namespace;,然后我可以直接调用这些类。
      • 阅读 php.net/manual/pl/language.namespaces.basics.php 如果您在 App\Entity 中有类 A 并且声明 use App\Entity 这意味着您可以使用名称 Entity\A 的类没有完整的命名空间。如果你想使用单个类那么你需要写use App\Entity\A然后你可以使用A类而不需要声明完整或相对路径
      猜你喜欢
      • 2013-05-16
      • 2021-06-29
      • 1970-01-01
      • 2013-11-25
      • 2014-04-13
      • 2013-10-15
      • 2012-10-22
      • 2011-08-06
      相关资源
      最近更新 更多