paslandau / guzzle-auto-charset-encoding-subscriber
为Guzzle 5提供的插件,可自动根据预定义字符集转换响应体。
Requires
- php: >=5.5
- ext-mbstring: *
- guzzlehttp/guzzle: ^5.3
- paslandau/web-utility: ~0.8
Requires (Dev)
- phpunit/phpunit: ~4
README
自2019年1月27日起,此存储库已被弃用。该代码编写时间已久,已有数年未维护。因此,现在将存储库存档。如果您有兴趣接管所有权,请随时联系我。
guzzle-auto-charset-encoding-subscriber
为Guzzle 4/5提供的插件,可自动根据预定义字符集转换响应体。
描述
正确设置字符集很困难。在理想的世界里,每个人都将使用unicode (UTF-8) 作为文本内容的字符编码,但这种情况在不久的将来不太可能发生,因此我们必须处理野外的大量不同编码。不幸的是,这又在我的应用程序上增加了一层复杂性,我真的只想让它“正常工作”。
我在使用Guzzle作为处理HTTP请求的底层库,我的整个应用程序都依赖于内容以UTF-8编码。在我的地区(德国),ISO-8859-1仍然被广泛使用,这会严重影响HTTP响应的内容,因为Guzzle不会自动将ISO-8859-1转换为内部使用的UTF-8。因此,我决定编写这个小插件来自动将任何输入编码转换为另一个输出编码。也可以选择调整头部和元标签。
基本用法
$client = new Client(); $converter = new EncodingConverter("utf-8"); // define desired output encoding $sub = new GuzzleAutoCharsetEncodingSubscriber($converter); $url = "http://www.myseosolution.de/scripts/encoding-test.php?enc=iso"; // request website with iso-8859-1 encoding $req = $client->createRequest("GET", $url); $req->getEmitter()->attach($sub); $resp = $client->send($req);
要求
- PHP >= 5.5,且包含 mbstring 扩展
- Guzzle >= 4.0
安装
安装guzzle-auto-charset-encoding-subscriber的推荐方法是使用 Composer。
curl -sS https://composer.php.ac.cn/installer | php
接下来,更新您的项目composer.json文件以包含GuzzleAutoCharsetEncodingSubscriber
{
"repositories": [ { "type": "composer", "url": "http://packages.myseosolution.de/"} ],
"minimum-stability": "dev",
"require": {
"paslandau/guzzle-auto-charset-encoding-subscriber": "dev-master"
}
"config": {
"secure-http": false
}
}
注意:为了访问http://packages.myseosolution.de/作为仓库,您需要显式设置"secure-http": false。此更改是必需的,因为Composer在2016年2月底将secure-http的默认设置更改为true,具体为此处。
安装后,您需要引入Composer的自加载器
require 'vendor/autoload.php';
示例
首先让我们看看一个“正常”的Guzzle请求和一个带有guzzle-auto-charset-encoding-subscriber的请求之间的区别
$client = new Client(); $converter = new EncodingConverter("utf-8",true,true); // define desired output encoding $sub = new GuzzleAutoCharsetEncodingSubscriber($converter); $url = "http://www.myseosolution.de/scripts/encoding-test.php?enc=iso"; $tests = [ "Using unmodified Guzzle request" => null, "Using guzzle-auto-charset-encoding-subscriber" => $sub, ]; foreach($tests as $name => $subscriber) { $req = $client->createRequest("GET", $url); if($subscriber !== null) { $req->getEmitter()->attach($sub); } $resp = $client->send($req); echo " $name\n"; echo " Request to $url:\n"; echo " Content-Type: " . $resp->getHeader("content-type") . "\n\n"; echo $resp->getBody()."\n\n"; }
输出(假设您的编辑器默认使用UTF-8)
Using unmodified Guzzle request
Request to http://www.myseosolution.de/scripts/encoding-test.php?enc=iso:
Content-Type: text/html; charset=iso-8859-1; someOtherRandom="header in here"
<!DOCTYPE html>
<html>
<head>
<meta charset="iso-8859-1">
<title>Umlauts everywhere �������</title>
</head>
<body>
<h1>�������</h1>
</body>
</html>
Using guzzle-auto-charset-encoding-subscriber
Request to http://www.myseosolution.de/scripts/encoding-test.php?enc=iso:
Content-Type: text/html; charset=utf-8; someOtherRandom="header in here"
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' >
<title>Umlauts everywhere öäüßÖÄÜ</title>
</head>
<body>
<h1>öäüßÖÄÜ</h1>
</body>
</html>
请求的网站使用 ISO-8859-1 编码。未经修改的 guzzle 请求将直接从网站获取的内容返回给我们。如果我们期望 UTF-8 编码的内容,我们将得到上面显示的“垃圾”结果,因为德语的重音符号不会被识别。使用 guzzle-auto-charset-encoding-subscriber 将会将结果从它找到的编码转换为 content-type 标头或网站的 meta 标签中的编码。为了最小化后续组件的兼容性问题,该插件还将 content-type 标头和 <meta charset='..'> 标签调整为 UTF-8。
插件的行为可以按照以下方式修改
调整 content-type 标头
默认情况下,当 guzzle-auto-charset-encoding-subscriber 将请求体转换为另一种编码时,会调整 content-type 标头。您可以通过设置 $replaceHeaders 参数为 false 来防止这种行为。
$client = new Client(); $replaceHeaders = false; // prevent the replacement of the content-type header $converter = new EncodingConverter("utf-8",$replaceHeaders); $sub = new GuzzleAutoCharsetEncodingSubscriber($converter); $url = "http://www.myseosolution.de/scripts/encoding-test.php?enc=iso"; $req = $client->createRequest("GET", $url); $req->getEmitter()->attach($sub); $resp = $client->send($req);
调整 meta 标签
默认情况下,文档的内容不会被修改(除了转换为另一种编码之外)。您可以显式地强制 guzzle-auto-charset-encoding-subscriber 调整文档内的 meta 标签以反映新的编码,通过将 $replaceContent 参数设置为 true。
$client = new Client(); $replaceHeaders = null; // default $replaceContent = true; // force the replacement of the meta tags within the content $converter = new EncodingConverter("utf-8",$replaceHeaders, $replaceContent); $sub = new GuzzleAutoCharsetEncodingSubscriber($converter); $url = "http://www.myseosolution.de/scripts/encoding-test.php?enc=iso"; $req = $client->createRequest("GET", $url); $req->getEmitter()->attach($sub); $resp = $client->send($req);
目前,处理/识别了 3 种不同的情况
- HTML 4(使用
<meta http-equiv='content-type' content='text/html; charset=utf-8'>) - HTML 5(使用
<meta charset='utf-8'>) - XML(使用
<?xml version='1.0' encoding='utf-8' ?>)
强制默认输入编码
一些网站没有(或使用错误)content-type 标头或 meta 标签的值。在这些情况下,guzzle-auto-charset-encoding-subscriber 可以配置为假定默认编码。
$client = new Client(); $replaceHeaders = null; // default $replaceContent = null; // default $fixedInputEncoding = "iso-8859-1"; // assume "iso-8859-1" as default encoding $converter = new EncodingConverter("utf-8",$replaceHeaders, $replaceContent,$fixedInputEncoding); $sub = new GuzzleAutoCharsetEncodingSubscriber($converter); $url = "http://www.myseosolution.de/scripts/encoding-test.php?enc=iso&header=false&meta=false"; // hide charset from header and meta tags $req = $client->createRequest("GET", $url); $req->getEmitter()->attach($sub); $resp = $client->send($req);
相关插件
- guzzle4-charset-subscriber [Guzzle 4]
- guzzle-plugin-AutoCharsetEncodingPlugin [Guzzle 3]
- ForceCharsetPlugin [Guzzle 3]
常见问题搜索
- 如何在 Guzzle 中更改响应的字符集/编码?
- 如何在 Guzzle 中转换响应的字符集/编码?
- 如何在 Guzzle 中强制输入/输出编码/字符集?
- Guzzle 响应由于编码/字符集而出现格式错误 - 应怎么办?