我最近在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
语句并在__autoload
中声明需要文件一次的../src/
函数来使其工作。
<?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/
所以它有效,我可以继续使用该解决方案。我认为这是一种解决方法,而不是解决方案。我仍然相信我做错了什么,它可以被优化,但无法弄清楚如何...如果你有一些知识可以分享,我全都耳朵!
提前感谢一大堆,抱歉这个大帖子。如果您需要任何其他信息,请询问。
答案 0 :(得分:1)
问题是你在admin / index.php中做的完全相同,在这种情况下是错误的。
问题出在以下几行:
require_once 'bootstrap.php';
这告诉php首先查找文件bootstrap.php
相对于包含/要求文件的文件,如果失败,则在配置的包含路径中查找。
它未包含在您的目录结构中,但从其外观来看,bootstrap.php
与index.php
位于同一级别。要解决您的问题,请使用以下内容替换admin/index.php
中的上述行:
require_once '../bootstrap.php';