gpt4 book ai didi

symfony - 尝试使用 Symfony 组件并遇到 namespace 问题

转载 作者:行者123 更新时间:2023-12-02 04:45:52 25 4
gpt4 key购买 nike

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

我有一段简单的代码,当我运行它时出现错误:PHP fatal error :在第 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/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类(class)。哎呀,PHP 怎么知道哪个 Client如果你这样做要使用的类?

<?php
$client = new Client();

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

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

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

$fooClient = new Foo\Client();
$barClient = new Bar\Client();

这会很好用。

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

“但是”,我听到你说,“每次我想实例化一个类时都写 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“好的,我想使用 Client 命名空间中的 Foo\Bar\Baz 类,以便在我使用 Client 类时使用。

自动加载

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

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

这就是您的代码中发生的事情。您没有注册可以翻译 use 的自动加载器实际类声明所需的文件中的语句。

很好,我该如何解决?

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

关于symfony - 尝试使用 Symfony 组件并遇到 namespace 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19796593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com