我可以使用没有include或require语句的类吗?

时间:2013-01-18 20:35:25

标签: php namespaces

我有一个index.php:

<?php

include_once('X\X.php');

$y= new X\X();
$y->HelloWorld();

?>

并说index.php在ROOT文件夹中,然后在ROOT \ X中我有一个名为:X.php的文件:

<?php 
namespace X;
     class X{
        public function HelloWorld(){
            echo 'Hello!';
        }
    }
?>

我的问题是,这只有在我的index.php中包含_('X \ X.php')时才有效。无论如何要说你好!不包含文件?

我正在尝试学习命名空间以及实际使用它们的方式。 如果我已经包含了该文件,那为什么还要使用命名空间?

2 个答案:

答案 0 :(得分:3)

您可以使用不包含的名称空间。这不是真的推荐,但可以做到。

给定的PHP文件必须是完全命名空间或根本不是命名空间。因此,如果您要在文件中使用名称空间,则必须使用名称空间声明启动(即第一行代码)。

一旦你拥有了它,它是合法的(虽然我会再次说,不推荐)在同一个文件中进一步改变名称空间(当然,显然不在任何类或函数之外)。

我真的建议花时间学习PHP的Autoload机制,作为同一个学习练习的一部分。它与命名空间很好地结合在一起,并允许您将代码拆分为每个类的单独文件(根据最佳实践建议),但无需手动包含所需的每个文件。

答案 1 :(得分:1)

了解spl_autoload_register()和朋友,或者更好地了解Spl Autoload机制以及include_path ini指令。这很酷的东西,将为您节省许多麻烦! :)

然而,自动加载并不神奇。它只是一个“钩子”机制,Zend引擎在访问之前未包含的用户定义类时调用。 autoload方法的参数是classname。该方法必须使用include或require(* _once)将类名解析为文件名并包含它

假设在您的情况下,文件X.php将位于类路径中的某个文件夹X中,您可以像这样解析名称:

// define your autoloader
function the_autoloader($classname) {
    // $classname  will 'X\X' in the example
    $filename = str_replace('\\', '/', $classname) . '.php';
    require $filename;
}

// register the autoloader
spl_autoload_register('the_autoloader');


// from this point you are free to instantiate every class
// that can be resolved by the_autoloader() without writing 
// an explicit include statement

$y= new X\X();
$y->HelloWorld();

如您所见,虽然自动加载可以减少类的使用并且包含“背景”文件,但仍然需要包含它们。所以问题的答案是:在使用之前你必须包含类文件