jstewmc/url

用于创建、解析和操作统一资源定位符(URL)的类

v0.1.1 2014-12-24 03:50 UTC

This package is auto-updated.

Last update: 2024-08-29 04:13:19 UTC


README

一个用于创建、解析和操作统一资源定位符(URL)的类。

统一资源定位符(URL)是一个字符串,用于标识资源并描述如何定位它。

大多数时候,PHP(或你的PHP框架)会为你处理创建、解析和操作URL。然而,偶尔你可能需要手动处理URL。

我发现手动处理URL作为字符串可能会有些麻烦。因此,我创建了一个URL类

// create a url
$url = new Url();

$url->setScheme('http');
$url->setHost('example.com');
$url->setPath('foo/bar');
$url->setQuery('baz=qux');

echo $url;  // prints "http://example.com/foo/bar?baz=qux"
// parse a url
$url = new Url('http://example.com/foo/bar?baz=qux');

echo $url->getScheme();                      // prints 'https'
echo $url->getHost();                        // prints 'example.com'
echo $url->getPath();                        // prints 'foo/bar'
echo $url->getPath()->getSegment(1);         // prints 'bar'
echo $url->getQuery();                       // prints 'baz=qux'
echo $Url->getQuery()->getParameter('baz');  // prints 'qux'
// manipulate a url
$url = new Url('http://example.com/foo/bar?baz=qux');

$url->getPath()->reverse()->prependSegment('qux')->insertSegment('quux', 2);

echo $url;  // prints "http://example.com/qux/bar/quux/foo?baz=qux

$url->getQuery()->unsetParameter('baz')->setParameter('quux', 'corge');

echo $url;  // prints "http://example.com/qux/bar/quux/foo?quux=corge

以下示例有些牵强(对于这些示例中的某些,字符串可能更快),且较为冗长(大多数方法可以串联使用)。然而,我相信你已经明白了我的意思。

您可以自由地查看API文档报告问题贡献提出问题

Url

此类基于(并利用)PHP的parse_url()函数。

就此类(及该函数)而言,URL由以下部分组成

  • scheme - 协议(例如,httphttps
  • username - 用于认证的用户名
  • password - 用于认证的密码
  • host - 域或IP地址(例如,example.com123.123.123.123
  • port - 服务器的端口号(例如,http80https443
  • path - 服务器上文件的路径(例如,path/to/file
  • query - 一系列键值对字符串(即,?foo=bar
  • fragment - 页面内的锚点(例如,#example

合并在一起

https://username:password@example.com:8080/path/to/file?key1=value1#fragment
-------|--------|--------|-----------|----|------------|-----------|--------
scheme |username|password|host       |port|path        |query      |fragment

格式

就此类而言,URL有两种格式:相对绝对。一个 绝对 URL 包含了所有非空的部分。另一方面,一个 相对 URL 包含了URL的路径、查询和片段。

当作为字符串使用时,此类将返回其 绝对 URL。然而,您可以使用 format() 方法返回其 相对 URL

$url = new Url();
$url
	->setScheme('http')
	->setHost('example.com')
	->setPort('1234')
	->setPath('foo/bar/baz')
	->setQuery('qux=quux')
	->setFragment('corge');

echo $url;                      // prints "http://example.com:1234/foo/bar/baz?qux=quux#corge
echo $url->format('absolute');  // prints "http://example.com:1234/foo/bar/baz?qux=quux#corge
echo $url->format('relative');  // prints "/foo/bar/baz?qux=quux#corge"

大小写

根据W3指南,Url类是区分大小写的。根据W3

URL通常区分大小写(机器名除外)。可能存在不区分大小写的URL或URL的一部分,但确定这些可能并不容易。用户应始终考虑URL区分大小写。

方案、主机、端口和片段

Url的schemehostportfragment是简单的字符串

// create a url
$url = new Url();
$url
	->setScheme('http')
	->setHost('example.com')
	->setPort('1234')
	->setFragment('foo');

echo $url;  // prints "http://example.com:1234#foo"

// parse a url
$url = new Url('http://example.com:1234#foo');

echo $url->getScheme();    // prints 'http'
echo $url->getHost();      // prints 'example.com' 
echo $url->getPort();      // prints '1234'
echo $url->getFragment();  // prints 'foo'

路径

Url的path可以被视为字符串或Path对象

// set the path as a string
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->setPath('foo/bar');

echo $url;  // prints "http://example.com/foo/bar"

// set the path as an array of segments
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->getPath()
		->setSegments(['foo', 'bar']);

echo $url;  // prints "http://example.com/foo/bar"

// set the path's segments one-by-one
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->getPath()
		->appendSegment('foo')
		->appendSegment('bar');

echo $url;  // prints "http://example.com/foo/bar"

路径由段组成。例如,路径 foo/bar/baz 有三个段:foobarbaz

段从0开始索引。因此,在路径 foo/bar/baz 中,foo 的索引是0。bar 的索引是1,baz 的索引是2。

大多数使用段索引作为参数的方法都接受一个偏移量。偏移量可以是正数(从路径开头算起这么多位置)或负数(从路径末尾算起这么多位置)。此外,大多数方法还接受特殊字符串 firstlast

您可以对路径段进行追加、预置、插入、设置和取消设置。

$url = new Url();
$url->setScheme('http')
	->setHost('example')
	->getPath()
		->appendSegment('foo')     // path is "foo"
		->prependSegment('bar')    // path is "bar/foo"
		->insertSegment('baz', 1)  // path is "bar/baz/foo"
		->setSegment(-1, 'qux')    // path is "bar/baz/qux"
		->unsetSegment('last');    // path is "bar/baz"

您还可以通过值或偏移量获取、查找和验证段。

$url  = new Url("http://example.com/foo/bar/baz");
$path = $url->getPath();

echo $path;  // prints "foo/bar/baz"

// get the index of the 'foo' segment
$path->getIndex('foo');  // returns 0
$path->getIndex('qux');  // returns false

// get the value of the 0-th (aka, 'first') segment
$path->getSegment(0);        // returns 'foo'
$path->getSegment('first');  // returns 'foo'

// does the path have a segment at the 1-st index?
$path->hasIndex(1);   // returns true
$path->hasIndex(10);  // returns false

// does the path have the given segments at any index?
$path->hasSegment('bar');  // returns true
$path->hassegment('qux');  // returns false

// does the path have the given segments at the given indices?
$path->hasSegment('foo', 0);        // returns true
$path->hasSegment('foo', 'first');  // returns true
$path->hasSegment('qux', 'last');   // returns false

最后,您可以切片和反转路径。

$url  = new Url("http://example.com/foo/bar/baz");
$path = $url->getPath();

echo $path;  // prints "foo/bar/baz"

// get a slice (as a new Path) from the 1-st index to the end
$path->getSlice(1);  // returns ['bar', 'baz']

// get a slice (as a new Path) from the 1-st index for one segment
$path->getSlice(1, 1);  // returns ['bar']

// slice the path itself
$path->slice(1, 1);
echo $path;  // prints "bar"

// get a new, reversed Path
$reverse = $path->getReverse();
echo $reverse;  // prints "baz/bar/foo"

// reverse the path itself
$path->reverse();
echo $path;  // prints "baz/bar/foo"

Url 类依赖于我的 Path 类。有关详细信息,请参阅该 README.md。

查询

查询可以被视为字符串或 Query 对象。

// set the query as a string
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->setQuery('foo=bar&baz=qux');

echo $url;  // prints "http://example.com?foo=bar&baz=qux"

// set the query's parameters as an array
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->getQuery()
		->setParameters(['foo' => 'bar', 'baz' => 'qux']);

echo $url;  // prints "http://example.com?foo=bar&baz=qux"

// finally, you can set the query's parameters one-by-one
$url = new Url();
$url->setScheme('http')
	->setHost('example.com')
	->getQuery()
		->setParameter('foo', 'bar')
		->setParameter('baz', 'qux');

echo $url;  // prints "http://example.com?foo=bar&baz=qux"

查询由参数组成。例如,在查询 foo=bar&baz=qux 中,有两个参数,foobazfoo 的值是 barbaz 的值是 qux。查询通常被视为键值对的列表。

与路径不同,路径中的顺序很重要,查询字符串中的顺序不重要。参数要么存在,要么不存在。

您可以设置或取消设置查询的参数。

$url   = new Url();
$url
	->setScheme('http')
	->setHost('example.com')
	->getQuery()
		->setParameter('foo', 'bar')
		->setParameter('baz', 'qux');

echo $url;  // prints "http://example.com?foo=bar&baz=qux"

$url->getQuery()->unsetParameter('foo');

echo $url;  // prints "http://example.com?baz=qux"

您还可以获取或验证参数。

$url   = new Url('http://example.com?foo=bar&baz=qux');
$query = $url->getQuery();

// does the query have the given parameters?
$query->hasParameter('foo');    // returns true
$query->hasParameter('corge');  // returns false

// what is the value of the given parameters?
$query->getParameter('foo');  // returns 'foo'
$query->getParameter('baz');  // returns 'qux' 
$query->getParameter('qux');  // throws OutOfBoundsException

分隔符

Url 类在假设您使用默认分隔符的情况下解析路径和查询:路径使用正斜杠字符 ("/"),查询参数使用和字符 ("&")。

如果您使用不同的参数,应避免在实例化时解析 URL。相反,您应手动设置分隔符,然后解析 URL。

$string = 'http://example.com|foo|bar|baz?foo=bar;baz=qux';

// notice the pipe character ("|") as the path separator (for some reason), and
//     notice the semi-colon character (";") as the argument separator
//

$url = new Url($string);  // this will not work!

// instead, set your separators and call the parse() method manually

$url = new Url();
$url->getPath()->setSeparator('|');
$url->getQuery()->setSeparator(';');
$url->parse($string);  

自定义

在上面的大多数示例中,我必须每次都明确设置 schemehost。这可能会很烦人。

一种解决方案是将 Url 类扩展到创建具有您默认设置的 MyUrl 类。

class MyUrl extends Url
{
	/* !Protected properties */
	
	/**
     * @var  string  my default host name
     */
	protected $host = 'mydomain.com';
	
	/**
     * @var  string  my default scheme
     */
	protected $scheme = 'https';
	
	/**
     * @var  string  my non-standard default https port
     */
    protected $port = '12345';    
}

$url = new MyUrl();
$url->setPath('foo/bar');

echo $url;  // prints "https://mydomain.com:12345/foo/bar"

单行代码

当然,如果我们不能写出神秘的单一行代码(使用 PHP 5.4+ 方法链),那我们就不会酷。

// print "http://example.com" in one line
echo (new Url())->setScheme('http')->setHost('example.com');

测试

我已经编写了平均 93% 代码覆盖率的单元测试。我仍在学习如何编写优秀的测试。所以,请随意查看并告诉我您的看法。

贡献

请随意贡献您的改进。

  1. 分叉
  2. 克隆
  3. PHPUnit
  4. 分支
  5. PHPUnit
  6. 代码
  7. PHPUnit
  8. 提交
  9. 推送
  10. 拉取请求
  11. 放松并吃一个原始人松饼

有关详细信息,请参阅 contributing.md

作者

Jack Clayton - clayjs0@gmail.com

许可

Url 在 MIT 许可下发布。有关详细信息,请参阅 LICENSE 文件。

历史

您可以在 changelog.md 文件中查看 Url 项目的(简短)历史。