【问题标题】:Php namespace vs requirePHP 命名空间与要求
【发布时间】:2016-02-29 09:53:17
【问题描述】:

快速提问,我正在使用 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需要)Request类本身,然后我得到一个找不到的类,这太奇怪了对我来说,当我使用 use 关键字并使用命名空间时,找到了类,但是当我包含类文件本身时,我得到了一个找不到类..

为了说明,这将返回一个“找不到类”..

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

$request = new Request();

谁能帮我解决这个问题? 提前致谢!

附:我已经红色了 use 关键字不包含任何内容,只是声明了命名空间或其他内容?所以它对我来说太奇怪了,它适用于用例,因为它甚至不包含文件,当我直接包含文件时,它返回一个“找不到类”......

【问题讨论】:

    标签: php symfony


    【解决方案1】:

    如果您使用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();
    

    类\Symfony\Component\HttpFoundation\Request 被包括在内,但是你想创建一个类\Request 的新对象,这是不同的。

    【讨论】:

      【解决方案2】:

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

      <?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 了解更多信息。

      【讨论】:

      • @deceze 那显然是为了new Response() 声明。不过我会更新的,好的。
      【解决方案3】:

      有两个不同的东西:

      1. 加载(包括,要求)实际的源代码文件
      2. 别名

      use专门建立一个别名。
      use Symfony\Component\HttpFoundation\Request;
      use Symfony\Component\HttpFoundation\Request as Request;的简写,
      这意味着它唯一能做的就是允许您通过简写 Request 来引用类 Symfony\Component\HttpFoundation\Request(这是类的实际完全限定名)。

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

      当您手动 require 文件时,您已经加载了代码(不必要,因为您还加载了自动加载器,它会为您解决这个问题),但您并没有通过它来处理类实际的完全限定名称,因此 PHP 不知道您在说什么类。类的名称是Symfony\Component\HttpFoundation\Request,而不是Request

      【讨论】:

        猜你喜欢
        • 2011-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-14
        • 1970-01-01
        • 2011-09-04
        • 2010-11-27
        • 2016-05-24
        相关资源
        最近更新 更多