Php namespace vs require

时间:2016-02-29 09:53:18

标签: php symfony

快速问题,我正在使用HttpFoundation组件(Symfony),我不清楚。我正在看的教程显示了这段代码

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$input = $request->get('name', 'World');

$response = new Response(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));

$response->send();

现在,这有效,没有问题,但是我试图让它在没有'use'关键字的情况下工作,所以包括(php require)Request类本身,然后我得到一个未找到的类,这是如此奇怪对我来说,当我使用use关键字并使用命名空间时,找到了类,但是当我包含类文件本身时,我得到的类没有找到..

因此,为了说明,这将返回“未找到的类”..

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__.'/vendor/symfony/http-foundation/Request.php';

$request = new Request();

有人可以帮我清楚吗? 提前谢谢!

P.S。我是红色的use关键字不包括任何东西,只是声明命名空间或什么?所以它对我来说非常奇怪它与用例一起工作,因为它甚至不包括文件,当我直接包含文件时它会返回'未找到类'...

3 个答案:

答案 0 :(得分:4)

如果使用use,则为完全限定名称(fqn)创建类似基于文件的别名。因此,如果您使用Symfony\Component\HttpFoundation\Request,则可以编写Request而不是fqn。如果您不想包含use语句,则必须每次都编写整个类名。

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';

$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();

$input = $request->get('name', 'World');

$response = new \Symfony\Component\HttpFoundation\Response(sprintf('Hello %s', htmlspecialchars($input, ENT_QUOTES, 'UTF-8')));

$response->send();

use - 语句本身与类加载无关。类加载的东西是由自动加载器完成的,它从它的类名解析出包含的php类的文件名。

清除您的问题代码:

// framework/index.php
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__.'/vendor/symfony/http-foundation/Request.php';

$request = new Request();

包含Class \ Symfony \ Component \ HttpFoundation \ Request,但是您想要创建类\ Request的新对象,这是不同的。

答案 1 :(得分:3)

命名空间不是关于加载类,而是关于命名。

<?php
$response = new Response();

我们告诉PHP使用\Response类。因此,如果此时未加载\Response类,您将收到错误。

<?php

use Symfony\Component\HttpFoundation\Response;

$response = new Response();

在这里(使用new Response()语句)我们告诉它使用Symfony\Component\HttpFoundation\Response类。因此,如果此时未加载Symfony\Component\HttpFoundation\Response类,您将收到错误。

基本上use Some\Namespaced\ClassName表示use Some\Namespaced\ClassName as ClassName,将其视为文件上下文中的别名。

http://php.net/manual/en/language.namespaces.basics.php了解详情。

答案 2 :(得分:1)

有两件事:

  1. 加载(包括,要求)实际的源代码文件
  2. 别名名称
  3. use专门建立别名 use Symfony\Component\HttpFoundation\Request;
    的简写 use Symfony\Component\HttpFoundation\Request as Request;
    这意味着它唯一能做的就是它允许你用速记Symfony\Component\HttpFoundation\Request来引用课程Request(这是班级&#39;实际的完全限定名称)。

    首次尝试对类执行某些操作时,自动加载器会加载源代码文件,例如在其上调用方法或实例化它。

    当您手动require文件时,您已经加载了代码(不必要,因为您还要加载自动加载器,这会为您处理),但是您已经#39} ;不是通过它的实际完全限定名称来处理类,因此PHP不知道你正在谈论什么类。班级&#39;名称为Symfony\Component\HttpFoundation\Request,而非Request