【问题标题】:PHP namespaces in project subfolders项目子文件夹中的 PHP 命名空间
【发布时间】:2014-04-14 03:36:11
【问题描述】:

我最近在 PHP 中的命名空间方面遇到了一些问题。以面向对象的方式开始一个新项目,我想将项目从结构到功能都准备得井井有条。

正如我所说,它是用面向对象的 PHP 开发的。使用Doctrine作为ORM,项目的全局结构如下:

/admin
  |- /index.php
/css
/fonts
/img
/js
/src
  |- /controller
  |- /model
  |- /system
    |- /utils
      |- /Singleton.php
  |- /view
/vendor
/index.php

好的,让我们举个简单的例子。

我有位于以下路径的 Singleton 类:src/system/utils/Singleton.php

<?php

namespace system\utils;

/**
 * Base class for singleton use cases
 */
class Singleton 
{
    /**
     * Returns the *Singleton* instance of this class.
     * @staticvar Singleton $instance The *Singleton* instance of this class.
     * @return Singleton the *Singleton* instance.
     */
    public static function getInstance() {
        static $instance = null;
        if ($instance === null) {
            $instance = new static();
        }
        return $instance;
    }

   // Private constructor, only local construction allowed
    protected function __construct() {
    }

    // Private cloner, only current instance 
    private function __clone() {
    }

    // Private wakeup function, to prevent unserializing
    private function __wakeup() {
    }
}

如您所见,此类使用命名空间system\utils。 然后,在主文件夹的/index.php 文件中,要使用这个类,我执行以下操作:

<?php
  require_once 'bootstrap.php';
  use system\utils\Singleton;

  $singleton = Singleton::getInstance();
  var_dump($singleton);
?>

(注意:bootstrap.php 是 Doctrine 的配置文件。我知道它使用某种自动加载,这可能是我在这里公开的问题的一部分,所以你可以找到内容在本文末尾)

这个例子工作得很好。伟大的。 但。如果我不是在/index.php 而是/admin/index.php 中进行完全相同的测试,它会失败并且PHP 说它找不到类Singleton。

我在这里真的很困惑,因为我认为命名空间是项目架构中每个类的某种“唯一”标识符,然后可用于在项目结构中的任何位置检索一个类。显然,我错了,谷歌搜索对我没有任何帮助。

我最好的猜测是自动加载和类似的东西,因为我知道 Doctrine 使用它。也许我在配置 ORM 时错过了一些东西。正如我之前所说,这是我的/bootstrap.php 的内容,其中包含所有配置设置。

<?php
// bootstrap.php
use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

require_once "vendor/autoload.php";

// Create a simple "default" Doctrine ORM configuration for Annotations
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/src/model/entities/"), $isDevMode);

// database configuration parameters
$conn = array(
    'driver' => 'pdo_mysql',
    'host' => 'host',
    'port' => 'port',
    'charset' => 'utf8',
    'dbname' => 'database',
    'user' => 'database',
    'password' => 'database'
);

// obtaining the entity manager
$entityManager = EntityManager::create($conn, $config);

我不知道这是否有帮助,但我可以在 /src 文件夹中的任何位置正确使用命名空间,但它似乎在主目录的另一个子文件夹中不起作用。

如果有人对这里发生的事情以及应如何在 PHP 中管理命名空间以及最终如何对我的代码进行更正有明确的解释,那么您将非常高兴分享您的知识。


编辑:

好的,所以它肯定与自动加载有关。我设法通过为命名空间编写正确的use 语句并在../src/ 中声明需要文件一次的__autoload 函数来使其工作。

<?php
    use system\utils\Singleton;

    $singleton = Singleton::getInstance();
    $singleton->manageSession();

    function __autoload($className)
    {
        echo "Autoloading $className.php in ../src/";
        require_once("../src/$className.php");
    }

    require_once '../bootsrap.php';
?>

这会输出Autoloading system\utils\Singleton.php in ../src/

所以它有效,我可以继续使用该解决方案。问题是我认为这是一种解决方法,而不是解决方案。我仍然认为我做错了什么并且可以对其进行优化,但不知道如何...如果您对此有一些知识可以分享,我全神贯注!


在此先感谢您,并为这篇大文章感到抱歉。如果您需要任何其他信息,请尽管询问。

【问题讨论】:

    标签: php doctrine-orm namespaces autoload


    【解决方案1】:

    问题是您在 admin/index.php 中所做的完全相同,在这种情况下是错误的。

    问题出在下面一行:

    require_once 'bootstrap.php';
    

    这告诉 php 首先相对于包含/需要该文件的文件查找文件 bootstrap.php,如果失败,则在配置的包含路径中查找。

    它不包含在您的目录结构中,但从外观上看,bootstrap.phpindex.php 处于同一级别。要解决您的问题,请将admin/index.php 中的上述行替换为以下内容:

    require_once '../bootstrap.php';
    

    【讨论】:

    • 我太笨了。 index.php 确实与bootstrap.php 处于同一水平。它在我编辑帖子时与我的自定义自动加载功能一起使用,因为我确实需要引导文件为../bootstrap.php 而不是bootstrap.php,正如你所说。所以,实际上,我已经在不知不觉中应用了你的修复......但那一刻我真的很笨,或者我的大脑有点放屁。可以肯定的是,使用../bootstrap.php 重试它,我在其中删除了我的自定义_autoload 函数,它运行良好。非常感谢您抽出宝贵时间并考虑帮助像我这样迷失的灵魂!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 2019-05-11
    • 2017-03-17
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多