【问题标题】:Instantiate Class using namespaces使用命名空间实例化类
【发布时间】:2013-07-11 06:41:43
【问题描述】:

我有一个函数文件,我在其中放置了一个 __autodload() 函数。对于我的课程,我想使用命名空间,因为我正在学习它们。在lib/ 文件夹中,我有一个 DB 类和一个 Test-User 类。代码如下:

DB.class.php

<?php
namespace App\Lib;

class DB
{
    public $db;

    function __construct($host, $username, $password, $database)
    {
        $this->db = new MySQLi($host, $username, $password, $database);
        if (mysqli_connect_error()) {
            die('Connect error');
        }
    }
}

用户.class.php

<?php

namespace App\Lib;

class User
{
    private $_db;

    function __construct($db)
    {
        $this->_db = $db;
    }

    public function test()
    {
        echo '<pre>';
        print_r($this->_db);
        echo '</pre>';
    }
}

此时,我的索引文件如下所示:

<?php

include 'functions.inc.php';

$db = new DB('localhost', 'root', '', 'test');
$user = new User($db);
$user->test();

我收到了错误Fatal error: Class 'DB' not found in C:\xampp\htdocs\tplsys\index.php on line 5

我也试过$db = new \App\Lib\DB()$db = new App\Lib\DB(),但结果总是一样...自动加载功能如下:

function __autoload($className)
{
    if (!file_exists('lib/' . $className . '.class.php')) {
        return FALSE;
    } else {
        require_once 'lib/' . $className . '.class.php';
    }
}

编辑

在 sectus 提供的帮助和链接的帮助下,我得到了它。现在的代码如下所示:

index.php

<?php
include 'functions.inc.php';

spl_autoload_register('autoload');

$db = new \Lib\DB('localhost', 'root', '', 'test');
$user = new \Lib\User($db);
$user->test();

自动加载功能:

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.class.php';

    require $fileName;
}

类:

<?php

namespace Lib;

class DB
{
    public $db;

    function __construct($host, $username, $password, $database)
    {
        $this->db = new \MySQLi($host, $username, $password, $database);
        if (mysqli_connect_error()) {
            die('Connect Error (' . mysql_connect_errno() . ') ' . mysqli_connect_error());
        }
    }

}

我不得不将命名空间重命名为 Lib\,因为它会查找 app/lib/class.php,否则...我只需要稍微尝试一下。谢谢你们的帮助,伙计们!

【问题讨论】:

  • 这不是你的整个index.php 文件,是吗?我认为我们在这里遗漏了一些重要的命名空间声明。
  • 改用 spl_register_autoload。
  • @deceze 我不好意思说是的,这是我的整个 index.php...我真的不知道它是如何正确完成的,这只是我解释 PHP 手册中的内容的方式...
  • 由于index.php 中没有namespace 声明,它应该寻找DB,而不是App\Lib\DB。这很奇怪。
  • @sectus 我只是这样做了,但这不是解决方案(不过我会保留它,所以感谢您的输入:))

标签: php oop namespaces


【解决方案1】:

您必须使用带有命名空间的类或aliases

<?php

include 'functions.inc.php';

$db = new DB('localhost', 'root', '', 'test');// your DB class has no namespace
$user = new \App\Lib\User($db);               // <--- namespace added
$user->test();

并且函数__autoload($className) 接收完整的类名(带有命名空间)。因此,当您的 __autoload 函数将执行时,它将收到字符串:'DB''App\Lib\User'

您应该阅读PSR-0 并使用此实现而不是您的实现。

【讨论】:

  • 如果我将命名空间添加到实例化中,它会给我与App\Lib\DB 相同的错误。而且我也不是很确定这个 PSR-0 是怎么实现的,抱歉,还在学习中……我是按照他们的描述写这个自动加载函数,然后使用 spl_autoload_register 注册它吗?
  • @PatrickManser,当你开始在 __autoload 函数中使用App\Lib\DB $className 时变成了App\Lib\DB,所以你试图包含文件'lib/App\Lib\DB.class.php'
  • 我使用了您提供的链接中描述的自动加载功能。它现在可以找到 DB 类(它实际上与 User 在同一个命名空间中......我不知何故忘记了这一点,我要再次编辑我的帖子......对不起......我很傻)......但它可以'找不到用户类...
  • 我忘记在函数中添加'.class.php'...现在它无法再次找到数据库...有时成为菜鸟令人沮丧
  • 好吧,我越来越近了……我想现在是自动加载功能的问题了:)
猜你喜欢
  • 1970-01-01
  • 2019-03-12
  • 2011-07-01
  • 2017-05-02
  • 2015-02-24
  • 1970-01-01
  • 2015-07-31
  • 2020-03-04
  • 1970-01-01
相关资源
最近更新 更多