UrlParser是 PHP 库,提供符合 RFC 3986 的 URL 解析器和 PSR-7 兼容的 URI 组件。该库的目的是提供一个准确实现 RFC 规范的解析器,这与内置函数parse_url()
不同,后者在一些微妙的方面与规范有所不同。
这个库有两个主要目的。第一个从解析的 URL 中提供信息。为了实现这一目标,该库实现了 PSR-7 中的标准 URI 处理接口,并且还提供了其他方法,使从 URL 检索常用信息变得更加容易。第二个目的是还允许使用 PSR-7 标准的接口修改所述 URL,此外还有一些使某些任务更加简单的额外方法。
虽然该库主要用于解析 URL,但解析只是基于通用 URI 语法。因此,可以使用该库根据通用语法验证和解析任何其他类型的 URI。该库不会对 URL 执行任何特定于方案的验证。
除了默认的 RFC 3986 兼容模式之外,该库还提供允许解析 URL 不同组件中包含 UTF-8 字符的 URL 的选项,同时将它们转换为适当的百分比编码和 IDN ascii 格式。
API 文档位于:http://kit.riimu.net/api/urlparser/
^1.0
)intl
(仅需要 IDN 支持) 安装此库的最简单方法是使用 Composer 来处理依赖项。要通过 Composer 安装此库,只需执行以下两个步骤:
通过在项目根目录中运行 Composer 命令行安装来获取composer.phar
。
运行安装脚本后,项目根目录中应该有composer.phar
文件,并且可以运行以下命令:
php composer.phar require "riimu/kit-urlparser:^2.1"
通过 Composer 安装此库后,您可以通过包含 Composer 在安装过程中生成的vendor/autoload.php
文件来加载该库。
如果您已经熟悉如何使用 Composer,您也可以通过将以下composer.json
文件添加到您的项目并运行composer install
命令来将该库添加为依赖项:
{
"require" : {
"riimu/kit-urlparser" : " ^2.1 "
}
}
如果您不想使用 Composer 加载库,您还可以通过下载最新版本并将src
文件夹解压到您的项目来手动下载库。然后,您可以包含提供的src/autoload.php
文件来加载库类。
请注意,使用 Composer 还将自动下载其他所需的 PHP 库。如果您手动安装此库,您还需要使其他必需的库可用。
使用这个库相对简单。该库提供了一个 URL 解析类UriParser
和一个表示 URL 的不可变值对象类Uri
。要解析 URL,您只需将 URL 作为字符串提供给UriParser
中的parse()
方法,该方法返回从解析的 URL 生成的Uri
实例。
例如:
<?php
require ' vendor/autoload.php ' ;
$ parser = new Riimu Kit UrlParser UriParser ();
$ uri = $ parser -> parse ( ' http://www.example.com ' );
echo $ uri -> getHost (); // Outputs 'www.example.com'
或者,您可以完全跳过使用UriParser
并简单地将 URL 作为构造函数参数提供给Uri
:
<?php
require ' vendor/autoload.php ' ;
$ uri = new Riimu Kit UrlParser Uri ( ' http://www.example.com ' );
echo $ uri -> getHost (); // Outputs 'www.example.com'
使用parse()
方法和构造函数之间的主要区别在于,如果提供的 URL 不是有效的 url,则parse()
方法将返回null
,而构造函数将抛出InvalidArgumentException
。
要从 URL 检索不同类型的信息, Uri
类提供了各种不同的方法来帮助您。这是一个简单的示例,概述了不同的可用方法:
<?php
require ' vendor/autoload.php ' ;
$ parser = new Riimu Kit UrlParser UriParser ();
$ uri = $ parser -> parse ( ' http://jane:[email protected]:8080/site/index.php?action=login&prev=index#form ' );
echo $ uri -> getScheme () . PHP_EOL ; // outputs: http
echo $ uri -> getUsername () . PHP_EOL ; // outputs: jane
echo $ uri -> getPassword () . PHP_EOL ; // outputs: pass123
echo $ uri -> getHost () . PHP_EOL ; // outputs: www.example.com
echo $ uri -> getTopLevelDomain () . PHP_EOL ; // outputs: com
echo $ uri -> getPort () . PHP_EOL ; // outputs: 8080
echo $ uri -> getStandardPort () . PHP_EOL ; // outputs: 80
echo $ uri -> getPath () . PHP_EOL ; // outputs: /site/index.php
echo $ uri -> getPathExtension () . PHP_EOL ; // outputs: php
echo $ uri -> getQuery () . PHP_EOL ; // outputs: action=login&prev=index
echo $ uri -> getFragment () . PHP_EOL ; // outputs: form
print_r ( $ uri -> getPathSegments ()); // [0 => 'site', 1 => 'index.php']
print_r ( $ uri -> getQueryParameters ()); // ['action' => 'login', 'prev' => 'index']
Uri
组件还提供了各种修改 URL 的方法,允许您从单独的组件构造新的 URL 或修改现有的 URL。请注意, Uri
组件是一个不可变的值对象,这意味着每个修改方法都会返回一个新的Uri
实例,而不是修改现有的 Uri 实例。下面是一个从其组件构造 URL 的简单示例:
<?php
require ' vendor/autoload.php ' ;
$ uri = ( new Riimu Kit UrlParser Uri ())
-> withScheme ( ' http ' )
-> withUserInfo ( ' jane ' , ' pass123 ' )
-> withHost ( ' www.example.com ' )
-> withPort ( 8080 )
-> withPath ( ' /site/index.php ' )
-> withQueryParameters ([ ' action ' => ' login ' , ' prev ' => ' index ' ])
-> withFragment ( ' form ' );
// Outputs: http://jane:[email protected]:8080/site/index.php?action=login&prev=index#form
echo $ uri ;
从前面的示例可以看出, Uri
组件还提供了__toString()
方法,该方法以字符串形式提供 URL。
以下是Uri
组件提供的用于从 URL 检索信息的方法列表:
getScheme()
返回 URL 中的方案,如果 URL 没有方案,则返回空字符串。
getAuthority()
从 URL 返回由用户名、密码、主机名和端口组成的组件,格式为user-info@hostname:port
getUserInfo()
从 URL 返回包含用冒号分隔的用户名和密码的组件。
getUsername()
返回从 URL解码的用户名,如果 URL 中不存在用户名,则返回空字符串。
getPassword()
返回 URL 中解码后的密码,如果 URL 中不存在密码,则返回空字符串。
getHost()
返回 URL 中的主机名,如果 URL 没有主机,则返回空字符串。
如果主机是 IP 地址,则getIpAddress()
返回主机的 IP 地址。否则此方法将返回null
。如果提供了 IPv6 地址,则返回的地址不带大括号。
getTopLevelDomain()
返回主机的顶级域。如果没有主机或者主机是IP地址,则返回空字符串。
getPort()
返回 URL 中的端口,如果 url 中不存在端口,则返回null
。如果端口是当前方案的标准端口(例如,http 为 80),则此方法也将返回null
。
getStandardPort()
返回当前方案的标准端口。如果没有方案或方案的标准端口未知,则将返回null
。
getPath()
返回 URL 的路径,如果 URL 没有路径,则返回空字符串。
getPathSegments()
返回已解码路径段的数组(即由每个正斜杠分割的路径)。空路径段将被丢弃,并且不包含在返回的数组中。
getPathExtension()
从路径返回文件扩展名;如果 URL 没有路径,则返回空字符串。
getQuery()
返回 URL 中的查询字符串;如果 URL 没有查询字符串,则返回空字符串。
getQueryParameters()
使用parse_str()
函数从 URL 解析查询字符串并返回解析值的数组。
getFragment()
返回 URL 中的片段,如果 URL 没有片段,则返回空字符串。
__toString()
以字符串形式返回 URL。
Uri
组件提供了各种可用于修改 URL 和构造新 URL 的方法。请注意,由于Uri
类是一个不可变值对象,因此每个方法都会返回一个新的Uri
实例,而不是修改现有实例。
withScheme($scheme)
返回具有给定方案的新实例。空方案可用于从 URL 中删除方案。请注意,任何提供的方案都会标准化为小写。
withUserInfo($user, $password = null)
返回具有给定用户名和密码的新实例。请注意,除非提供用户名,否则密码将被忽略。空用户名可用于从 URL 中删除用户名和密码。任何无法单独插入 URL 的字符都将进行百分比编码。
withHost($host)
返回具有给定主机的新实例。空主机可用于从 URL 中删除主机。请注意,此方法不接受国际域名。请注意,此方法还将主机标准化为小写。
withPort($port)
返回具有给定端口的新实例。 null
可用于从 URL 中删除端口。
withPath($path)
返回具有给定路径的新实例。空路径可用于从 URL 中删除路径。请注意,任何不是有效路径字符的字符都将在 URL 中进行百分比编码。但是,现有的百分比编码字符不会进行双重编码。
withPathSegments(array $segments)
返回一个新实例,其中路径由路径段数组构造而成。段中的所有无效路径字符都将进行百分比编码,包括正斜杠和现有的百分比编码字符。
withQuery($query)
返回具有给定查询字符串的新实例。空查询字符串可用于从 URL 中删除路径。请注意,任何不是有效查询字符串字符的字符都将在 URL 中进行百分比编码。但是,现有的百分比编码字符不会进行双重编码。
withQueryParameters(array $parameters)
返回一个新实例,其中包含使用http_build_query()
函数根据提供的参数构造的查询字符串。参数中的所有无效查询字符串字符都将进行百分比编码,包括与号、等号和现有的百分比编码字符。
withFragment($fragment)
返回具有给定片段的新实例。空字符串可用于从 URL 中删除片段。请注意,任何不是有效片段字符的字符都将在 URL 中进行百分比编码。但是,现有的百分比编码字符不会进行双重编码。
默认情况下,该库提供符合 RFC 3986 的解析器。 RFC 规范不允许在域名或 URL 的任何其他部分中使用 UTF-8 字符。 URL 中这些内容的正确表示是使用域名的 IDN 标准,并在其他部分对 UTF-8 字符进行百分比编码。
但是,为了帮助您处理 UTF-8 编码字符, Uri
组件中的许多方法将自动对无法自行插入 URL 中的任何字符(包括 UTF-8 字符)进行百分比编码。然而,由于涉及的复杂性, withHost()
方法不允许使用 UTF-8 编码的字符。
默认情况下,解析器也不解析任何包含 UTF-8 编码字符的 URL,因为这违反了 RFC 规范。然而,解析器确实提供了两种额外的解析模式,只要有可能就允许这些字符。
如果您希望解析 URL 中的用户信息(即用户名或密码)、路径、查询或片段组件中可能包含 UTF-8 字符的 URL,则可以简单地使用 UTF-8 解析模式。例如:
<?php
require ' vendor/autoload.php ' ;
$ parser = new Riimu Kit UrlParser UriParser ();
$ parser -> setMode ( Riimu Kit UrlParser UriParser:: MODE_UTF8 );
$ uri = $ parser -> parse ( ' http://www.example.com/föö/bär.html ' );
echo $ uri -> getPath (); // Outputs: /f%C3%B6%C3%B6/b%C3%A4r.html
然而,域名中的 UTF-8 字符是一个稍微复杂的问题。不过,解析器确实为使用 IDNA 模式解析这些域名提供了基本支持。例如:
<?php
require ' vendor/autoload.php ' ;
$ parser = new Riimu Kit UrlParser UriParser ();
$ parser -> setMode ( Riimu Kit UrlParser UriParser:: MODE_IDNA );
$ uri = $ parser -> parse ( ' http://www.fööbär.com ' );
echo $ uri -> getHost (); // Outputs: www.xn--fbr-rla2ga.com
请注意,使用此解析模式需要启用 PHP 扩展intl
。还可以使用第二个构造函数参数向Uri
组件的构造函数提供适当的解析模式。
虽然支持解析这些 UTF-8 字符,但该库不提供任何反向操作方法,因为该库的目的是处理符合 RFC 3986 的 URI。
由于 RFC 3986 规范将一些 URL 定义为等效的,尽管存在一些细微的差异,因此该库对提供的值进行了一些最小的标准化。例如,在解析用户提供的 URL 时,您可能会遇到这些情况。您可能遇到的最值得注意的标准化如下:
scheme
和host
组件被认为不区分大小写。因此,这些组件将始终标准化为小写。getAuthority()
和__toString()
返回的字符串中。__toString()
返回的字符串中路径开头的正斜杠数量可能会根据 URL 是否具有authority
组件而改变。userinfo
组件中解析和生成的 URI 中的编码字符百分比可能会有所不同,因为UriParser
使用 PSR-7 规范,该规范不提供提供编码用户名或密码的方法。 该库版权所有 (c) 2013-2022 Riikka Kalliomaki。
有关许可证和复制信息,请参阅许可证。