【问题标题】:trying to use Symfony component and having name space issues尝试使用 Symfony 组件并遇到名称空间问题
【发布时间】:2013-11-05 18:55:39
【问题描述】:

所以我开始了一个新项目并想使用一些 Symfony 组件。我以前没有在 PHP 中使用过名称空间,我对我在 java 中的工作很熟悉这个概念。

我有这段简单的代码,当我运行它时,我得到了错误: PHP 致命错误:在第 52 行的 /home/me/scrapes/Symfony/Component/CssSelector/CssSelector/CssSelector.php 中找不到类“Symfony\Component\CssSelector\XPath\Translator”

我认为这是我对命名空间的了解不足。 /home/me/scrapes/Symfony/Component/CssSelector/CssSelector/XPath/Translator.php 确实存在。

<?php
set_include_path('/home/me/html/inc');
require 'functions.php';
require 'Symfony/Component/DomCrawler/Crawler/Crawler.php';
require 'Symfony/Component/CssSelector/CssSelector/CssSelector.php';

use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\CssSelector\CssSelector;

$crawler = new Crawler();
$crawler->addContent('<html><body><p>Hello World!</p></body></html>');
print $crawler->filter('body > p')->text();

curl_close($ch);    

require 'cleanup.php';
?>

感谢您的帮助

【问题讨论】:

    标签: symfony


    【解决方案1】:

    我认为这是因为,如果您查看所需的文件(例如 Symfony/Component/DomCrawler/Crawler/Crawler.php),您会发现这些文件使用了它们自己的 use 语句(以加载其他类)。

    命名空间

    让我们从命名空间开始。命名空间用于在不同的包中轻松创建具有相同名称的类。假设我有一个名为Foo 的包和一个名为Bar 的包。这两个包都包含一个 Client 类,用于执行一些客户端工作(例如,一个调用 Google Maps API,另一个调用 Facebook Graph API)。我们还假设两个包都没有使用命名空间。

    如果我执行以下代码:

    <?php
    require 'Foo/Client.php';
    require 'Bar/Client.php';
    

    这是行不通的,因为两个包都声明了一个Client 类。糟糕,如果您这样做,PHP 将如何知道要使用哪个 Client 类?

    <?php
    $client = new Client();
    

    它不知道要使用哪个Client,所以它放弃并抛出错误。

    如果您使用命名空间(在文件顶部使用 PHP 中的 namespace 关键字声明,位于 &lt;?php 正下方),您可以防止这种情况发生。 Foo 包可以在Foo 命名空间中创建Client 类,在Bar 命名空间中创建Bar 包。现在我们可以 实际使用这两个文件并创建一个客户端:

    <?php
    require 'Foo/Client.php'
    require 'Bar/Client.php'
    
    $fooClient = new Foo\Client();
    $barClient = new Bar\Client();
    

    这会很好用。

    我想您可能在旧的 PHP 库中遇到过 Foo_Client 符号。这是在 PHP 原生支持命名空间之前创建命名空间的旧方法。

    “但是”,我听到你说,“每次我想实例化一个类的时候都写Foo\Bar\Baz\Client()很麻烦”。

    是的,这就是 use 关键字的用处。当使用 use 关键字时,我可以告诉 PHP 我想使用特定的客户端并只使用类名,如下所示:

    <?php
    require 'Foo/Bar/Baz/Client.php'
    use Foo\Bar\Baz\Client;
    
    $client = new Client();
    

    如果您使用 use Foo\Bar\Baz\Client 语句,这将起作用,因为您告诉 PHP “好的,我想使用 Foo\Bar\Baz 命名空间中的 Client 类,以便在我使用 Client 类时使用。

    自动加载

    现在,如果您使用许多不同的类并将它们分成几个文件(您应该这样做),会发生什么情况。您会在文件顶部看到许多不同的 requireuse 语句。这就是自动加载的作用。

    在 PHP 中存在 spl_register_autoloader 函数已经有一段时间了。当您实例化一个未知的类时,PHP 使用此函数找出要使用哪些文件,因为您没有require 文件。这个函数在创建类时使用,或者,这是关键部分当你use一个类时

    这就是您的代码中正在发生的事情。您没有注册可以将文件中的use 语句转换为实际类声明的自动加载器。

    很好,我该如何解决?

    要修复它,我建议您阅读PHP-FIGPSR-4。这些人创建了标准(您可以遵循但没有义务)。创建易于使用的库,例如 Symfony 组件。完成后,继续阅读Composer。完成此操作后,您可以从代码中删除 require 语句并使用 Composer 自动加载您需要的所有类。

    【讨论】:

      猜你喜欢
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多