命名空间自动加载在 Windows 下有效,但在 Linux 上无效

发布于 2024-09-02 05:12:49 字数 782 浏览 3 评论 0原文

我有以下 php 代码:

index.php

<?php
spl_autoload_extensions(".php");
spl_autoload_register();

use modules\standard as std;

$handler = new std\handler();
$handler->delegate();
?>

modules\standard\handler.php

<?php
namespace modules\standard {
    class handler {
        function delegate(){
            echo 'Hello from delegation!';
        }
    }
}
?>

在 Windows 7 下,运行 WAMP,代码会生成消息“Hello from Delegation!”但是在Linux下,我得到以下信息:

致命错误:spl_autoload():无法在第 15 行 /var/www/index.php 中加载类模块\standard\handler

Windows 在 WAMP 下运行 PHP 5.3.0,Linux 在 WAMP 下运行 5.3.2 dotdeb 包乌班图9.10。

这是我的 Linux 机器上的配置问题,还是只是不同操作系统上处理命名空间和自动加载的方式不同

I have the following php code:

index.php

<?php
spl_autoload_extensions(".php");
spl_autoload_register();

use modules\standard as std;

$handler = new std\handler();
$handler->delegate();
?>

modules\standard\handler.php

<?php
namespace modules\standard {
    class handler {
        function delegate(){
            echo 'Hello from delegation!';
        }
    }
}
?>

Under Windows 7, running WAMP, the code produces the message "Hello from Delegation!" however under Linux, I get the following:

Fatal error: spl_autoload(): Class modules\standard\handler could not be loaded in /var/www/index.php on line 15

Windows is running PHP 5.3.0 under WAMP, and Linux is running the 5.3.2 dotdeb package under Ubuntu 9.10.

Is this a configuration issue on my linux box, or just a difference in the way namespaces and autoloading is handled on the different operating systems

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

指尖微凉心微凉 2024-09-09 05:12:49

SPL 自动加载器非常原始 - 它不知道名称空间,因此它尝试加载名称中包含 \ 的文件,而在 Linux/Unix 上路径分隔符是 / 不是。

The SPL autoloader is extremely primitive - it has no knowledge of namespaces, so it tries to load a file with \ in it's name while on Linux/Unix the path separator is / not .

三月梨花 2024-09-09 05:12:49

Herman Radtke 表示他已提交补丁:

http:// www.hermanradtke.com/blog/hidden-features-with-spl_autoload-and-namespaces/

我希望它很快就能实现。

现在我使用这个解决方法:

<?php
set_include_path( './classes/' . PATH_SEPARATOR . get_include_path() );
spl_autoload_extensions( '.php , .class.php' );
spl_autoload_register();
function linux_namespaces_autoload ( $class_name )
    {
        /* use if you need to lowercase first char *
        $class_name  =  implode( DIRECTORY_SEPARATOR , array_map( 'lcfirst' , explode( '\\' , $class_name ) ) );/* else just use the following : */
        $class_name  =  implode( DIRECTORY_SEPARATOR , explode( '\\' , $class_name ) );
        static $extensions  =  array();
        if ( empty($extensions ) )
            {
                $extensions  =  array_map( 'trim' , explode( ',' , spl_autoload_extensions() ) );
            }
        static $include_paths  =  array();
        if ( empty( $include_paths ) )
            {
                $include_paths  =  explode( PATH_SEPARATOR , get_include_path() );
            }
        foreach ( $include_paths as $path )
            {
                $path .=  ( DIRECTORY_SEPARATOR !== $path[ strlen( $path ) - 1 ] ) ? DIRECTORY_SEPARATOR : '';
                foreach ( $extensions as $extension )
                    {
                        $file  =  $path . $class_name . $extension;
                        if ( file_exists( $file ) && is_readable( $file ) )
                            {
                                require $file;
                                return;
                            }
                    }
            }
        throw new Exception( _( 'class ' . $class_name . ' could not be found.' ) );
    }
spl_autoload_register( 'linux_namespaces_autoload' , TRUE , FALSE );
?>

Herman Radtke says he has submitted a patch :

http://www.hermanradtke.com/blog/hidden-features-with-spl_autoload-and-namespaces/

:s

I'm hoping it'll be implemented soon.

For now I use this workaround :

<?php
set_include_path( './classes/' . PATH_SEPARATOR . get_include_path() );
spl_autoload_extensions( '.php , .class.php' );
spl_autoload_register();
function linux_namespaces_autoload ( $class_name )
    {
        /* use if you need to lowercase first char *
        $class_name  =  implode( DIRECTORY_SEPARATOR , array_map( 'lcfirst' , explode( '\\' , $class_name ) ) );/* else just use the following : */
        $class_name  =  implode( DIRECTORY_SEPARATOR , explode( '\\' , $class_name ) );
        static $extensions  =  array();
        if ( empty($extensions ) )
            {
                $extensions  =  array_map( 'trim' , explode( ',' , spl_autoload_extensions() ) );
            }
        static $include_paths  =  array();
        if ( empty( $include_paths ) )
            {
                $include_paths  =  explode( PATH_SEPARATOR , get_include_path() );
            }
        foreach ( $include_paths as $path )
            {
                $path .=  ( DIRECTORY_SEPARATOR !== $path[ strlen( $path ) - 1 ] ) ? DIRECTORY_SEPARATOR : '';
                foreach ( $extensions as $extension )
                    {
                        $file  =  $path . $class_name . $extension;
                        if ( file_exists( $file ) && is_readable( $file ) )
                            {
                                require $file;
                                return;
                            }
                    }
            }
        throw new Exception( _( 'class ' . $class_name . ' could not be found.' ) );
    }
spl_autoload_register( 'linux_namespaces_autoload' , TRUE , FALSE );
?>
三生殊途 2024-09-09 05:12:49
function __autoload($class_name) {
$paths[] = dirname(__FILE__) . "/../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/helpers/";
$paths[] = dirname(__FILE__) . "/../../libs/simpleimage/";

foreach($paths as $path)
    {
        if(file_exists($path.strtolower($class_name).'.class.php')){
        require_once($path.strtolower($class_name).'.class.php');
        }
    }
}
function __autoload($class_name) {
$paths[] = dirname(__FILE__) . "/../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/misc/";
$paths[] = dirname(__FILE__) . "/../../libs/helpers/";
$paths[] = dirname(__FILE__) . "/../../libs/simpleimage/";

foreach($paths as $path)
    {
        if(file_exists($path.strtolower($class_name).'.class.php')){
        require_once($path.strtolower($class_name).'.class.php');
        }
    }
}
扶醉桌前 2024-09-09 05:12:49
function __autoload($class_name)
{
    $class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name));

    include $class_name . '.php';
}

Apache 需要 srttolower,因为它区分大小写(与 IIS 不同)。

function __autoload($class_name)
{
    $class_name = strtolower(str_replace('\\', DIRECTORY_SEPARATOR, $class_name));

    include $class_name . '.php';
}

The srttolower is needed on Apache because it is (contrary to IIS) case sentive.

紫南 2024-09-09 05:12:49

这是自动加载时常见的问题。修复方法是在自动加载函数中使用 DIRECTORY_SEPARATOR 常量。

因此,您的自动加载函数将如下所示

<?php

spl_autoload_register(function($className) {

    $className = str_replace("\", DIRECTORY_SEPARATOR, $className);
    include_once $_SERVER['DOCUMENT_ROOT'] . '/class/' . $className . '.php';

});

如果您需要了解有关命名空间/类自动加载的更多信息,请访问 在这里

谢谢。

This is a common problem occurs when autoloading. The fix is to use DIRECTORY_SEPARATOR constant in the autoload function.

So your autoload function will look like following

<?php

spl_autoload_register(function($className) {

    $className = str_replace("\", DIRECTORY_SEPARATOR, $className);
    include_once $_SERVER['DOCUMENT_ROOT'] . '/class/' . $className . '.php';

});

If you need to learn more on namespace/class autoloading visit here

Thanks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文