2

我有一个使用 PDO 的 DB 包装类,并在构造函数中创建了一个 PDO 对象。包装类在我们的命名空间中,我们正在使用自动加载器。问题是在我们的命名空间中找不到 PDO 类,所以我尝试使用这里描述的全局命名空间。

//Class file
namespace Company\Common;
class DB {
    private function __construct(){
        $this->Handle=new PDO(...);
    }
}

有了这个,我得到了这个(如预期的那样):

Warning: require(...\vendors\Company\Common\PDO.class.php): failed to open stream

如果我这样做:

namespace Company\Common;
use PDO;

我明白了:

Fatal error: Class 'DB' not found in ...\includes\utils.php

并且 utils.php 在错误行中包含了这个,在实现命名空间之前它工作得很好:

DB::getInstance();

或者我试过这个:

namespace Company\Common;
class DB {
    private function __construct(){
        $this->Handle=new \PDO(...);
    }
}

它试图像最初那样在我们的命名空间中加载 PDO 类。

我该如何解决这个问题?我想通过这样做use PDO或者new \PDO它会加载全局 PDO 类,但它似乎不起作用?

4

5 回答 5

6

在命名空间 PHP 中,对类的引用必须包含该类的命名空间,除非您有use包含该类或其部分命名空间的语句。

因此,如果您没有use声明,则必须使用前导反斜杠引用 PDO 和其他全局类 - 即$obj = new \PDO();

如果您有一个use引用该类的语句,那么您可以仅通过类名来引用它:

use PDO;
....
$obj = new PDO();

如果您要引用许多全局类,use如果您想避免每次都使用反斜杠,则需要单独引用它们。

于 2013-01-11T16:43:45.340 回答
0

通常在我们的项目中,我们会设置这样的包含路径:

set_include_path('PATH_TO_GLOBAL_LIBS; PATH_TO_LIBRARY_1; PATH_TO_LIBRARY_X; PATH_TO_DOCUMENT_ROOT');

通过这个我们告诉 PHP (Apache) 在这些路径中搜索任何应该被自动加载器包含的类。

然后假设我们有一些Library_1/var/www/Libs/library_1并且这个路径被添加到 include_path 我们可以这样做:

namespace Company\Common;

Class DB {
    private function __construct() {
        $this->Handle = new \Library_1();
    }
}

这应该与

namespace Company\Common;

use \Library_1;

Class DB {
    private function __construct() {
        $this->Handle = new Library_1();
    }
}
于 2013-01-11T16:16:26.437 回答
0

解决了。我没有意识到命名空间的别名仅适用于当前文件,而不适用于任何未来包含的文件。在 PHP.net 上找到这个也适用于别名:

导入规则是基于每个文件的,这意味着包含的文件不会继承父文件的导入规则。

于 2013-01-11T16:40:55.913 回答
0

这行得通,你的问题是 elsewere。

索引.php

<?php
include('_db.php');
use Company\Common\DB;
new DB;

_db.php

<?php
namespace Company\Common;
use \PDO;

class DB {
    public function __construct() {
        $this->Handle = new PDO;
    }
}
于 2013-01-11T16:17:02.560 回答
0

要访问和之类的全局对象PDODateTime您需要在它们前面加上反斜杠。所以你有两个选择。

首先,use您希望在名称空间类文件中使用的类:

<?php
namespace Vendor;

use \PDO;
use \PDOException;

class MyClass
{
    public function __construct()
    {
        try {
            $db = new PDO($dsn, $user, $pass);
            $db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        }
        catch (PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }
}

或者只是在你的类中使用以反斜杠为前缀的声明:

<?php
namespace Vendor;

class MyClass
{
    public function __construct()
    {
        try {
            $db = new \PDO($dsn, $user, $pass);
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
        catch (\PDOException $e) {
            echo $e->getMessage();
            exit;
        }
    }
}

就个人而言,我更喜欢第一种方法。

于 2013-01-11T16:26:05.700 回答