如何在自动加载中使用PHP命名空间?

Dav*_*nes 98 php autoload

当我尝试使用自动加载和名称空间时,我收到此错误:

致命错误:类"的Class1"中找不到/usr/local/www/apache22/data/public/php5.3/test.php线10

谁能告诉我我做错了什么?

这是我的代码:

Class1.php:

<?php

namespace Person\Barnes\David
{
    class Class1
    {
        public function __construct()
        {
            echo __CLASS__;
        }
    }
}

?>
Run Code Online (Sandbox Code Playgroud)

test.php的:

<?php

function __autoload($class)
{
    require $class . '.php';
}

use Person\Barnes\David;

$class = new Class1();

?>
Run Code Online (Sandbox Code Playgroud)

tan*_*kay 116

Class1不在全局范围内.

请参阅下面的工作示例:

<?php

function __autoload($class)
{
    $parts = explode('\\', $class);
    require end($parts) . '.php';
}

use Person\Barnes\David as MyPerson;

$class = new MyPerson\Class1();
Run Code Online (Sandbox Code Playgroud)

编辑(2009-12-14):

为了澄清,我使用"use ... as"是为了简化示例.

替代方案如下:

$class = new Person\Barnes\David\Class1();
Run Code Online (Sandbox Code Playgroud)

要么

use Person\Barnes\David\Class1;

// ...

$class = new Class1();
Run Code Online (Sandbox Code Playgroud)

  • @ user346665你必须使用`使用Person\Barnes\David\Class1;`来执行`$ class = new Class1();`.使用`使用Person\Barnes\David;`你必须要`$ class = new David\Class1();`.`use`关键字本身相当于`使用Person\Barnes\David\Class1作为Class1;`或`使用Person\Barnes\David作为David;`,分别用于每个示例. (4认同)

Kos*_*nos 26

如上所述Pascal MARTIN,您应该用DIRECTORY_SEPARATOR替换'\',例如:

$filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
include($filename);
Run Code Online (Sandbox Code Playgroud)

另外我建议你重新组织dirrectory结构,使代码更具可读性.这可能是另一种选择:

目录结构:

ProjectRoot
 |- lib
Run Code Online (Sandbox Code Playgroud)

文件: /ProjectRoot/lib/Person/Barnes/David/Class1.php

<?php
namespace Person\Barnes\David
class Class1
{
    public function __construct()
    {
        echo __CLASS__;
    }
}
?>
Run Code Online (Sandbox Code Playgroud)
  • 为您定义的每个命名空间创建子目录.

文件: /ProjectRoot/test.php

define('BASE_PATH', realpath(dirname(__FILE__)));
function my_autoloader($class)
{
    $filename = BASE_PATH . '/lib/' . str_replace('\\', '/', $class) . '.php';
    include($filename);
}
spl_autoload_register('my_autoloader');

use Person\Barnes\David as MyPerson;
$class = new MyPerson\Class1();
Run Code Online (Sandbox Code Playgroud)
  • 我使用php 5 recomendation进行自动加载器声明.如果您仍然使用PHP 4,请将其替换为旧语法:function __autoload($ class)


Pas*_*TIN 18

您的__autoload函数将收到完整的类名,包括命名空间名称.

这意味着,在您的情况下,该__autoload功能将接收' Person\Barnes\David\Class1',而不仅仅' Class1'.

因此,您必须修改自动加载代码,以处理那种"更复杂"的名称; 经常使用的解决方案是使用每个"级别"命名空间的一级目录来组织文件,并且在自动加载时,\将命名空间名称中的' ' 替换为DIRECTORY_SEPARATOR.


tik*_*ika 14

我这样做:看到这个GitHub示例

spl_autoload_register('AutoLoader');

function AutoLoader($className)
{
    $file = str_replace('\\',DIRECTORY_SEPARATOR,$className);

    require_once 'classes' . DIRECTORY_SEPARATOR . $file . '.php'; 
    //Make your own path, Might need to use Magics like ___DIR___
}
Run Code Online (Sandbox Code Playgroud)

  • 很好,很简单.如果一个人应该寻找那个.) (2认同)