所以我开始一个新项目,并希望使用一些Symfony组件.我之前没有使用PHP的名称空间,我熟悉java工作中的概念.
我有这段简单的代码,当我运行它时,我得到错误: PHP致命错误:类'Symfony\Component\CssSelector\XPath\Translator'找不到/ home/me/scrapes/Symfony/Component/CssSelector/CssSelector第52行的/CssSelector.php
我在想,我缺乏名称空间的知识./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';
?>
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助
我认为这是因为,如果你查看你需要的文件(例如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';
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为两个包都声明了一个Client类.哎呀,Client如果你这样做,PHP将如何知道要使用哪个类?
<?php
$client = new Client();
Run Code Online (Sandbox Code Playgroud)
它不会知道Client使用哪个,所以它放弃并抛出错误.
如果您使用名称空间(使用namespace文件顶部的PHP中的关键字声明,直接在下面<?php),您可以防止这种情况发生.该Foo包可以Client在Foo命名空间中创建一个类,在命名空间中创建Bar包Bar.现在我们可以实际使用这两个文件并创建一个客户端:
<?php
require 'Foo/Client.php'
require 'Bar/Client.php'
$fooClient = new Foo\Client();
$barClient = new Bar\Client();
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作.
我想你可能Foo_Client在旧的PHP库中遇到过这种表示法.这是在PHP本身支持它们之前创建命名空间的一种旧方法.
"但是",我听到你说," Foo\Bar\Baz\Client()每次我想要实例化一个类时写起来都很麻烦".
它就是use关键字所在的位置.当使用use关键字时,我可以告诉PHP我想使用特定的客户端并只使用类名,如下所示:
<?php
require 'Foo/Bar/Baz/Client.php'
use Foo\Bar\Baz\Client;
$client = new Client();
Run Code Online (Sandbox Code Playgroud)
如果您使用该use Foo\Bar\Baz\Client语句,这将有效,因为您告诉PHP"好的,我想在使用Client该类Foo\Bar\Baz时使用命名空间中的Client类.
现在,如果您使用许多不同的类并将它们分成几个文件(您应该这样做)会发生什么.你得到了很多的不同require,并use在文件的顶部声明.这就是自动加载的地方.
spl_register_autoloader在PHP中有相当长一段时间的功能.PHP使用此函数来查找在实例化由于您没有require该文件而未知的类时要使用的文件.在创建类时使用此函数,或者,这是您use在课时的关键部分.
这就是你的代码中发生的事情.您没有注册自动加载器,可以将use您需要的文件中的语句转换为实际的类声明.
为了解决这个问题,我建议你阅读PHP-FIG和PSR-4.这些人创造了标准(你可以遵循,但没有义务).创建易于使用的库,例如Symfony组件.完成后,请阅读Composer.完成此操作后,您可以require从代码中删除语句,并使用Composer自动加载所需的所有类.
| 归档时间: |
|
| 查看次数: |
738 次 |
| 最近记录: |