CodeIgniter4 使用 URI 類

2020-08-14 16:18 更新

CodeIngiter 為你在應(yīng)用中使用 URI 類提供了一個(gè)面向?qū)ο蟮慕鉀Q方案。使用這種方式可以輕易地確保結(jié)構(gòu)始終準(zhǔn)確,無論 URI 的復(fù)雜程度如何,也能將相對(duì) URI 添加到現(xiàn)有應(yīng)用中,并保證其可以被安全、準(zhǔn)確地解析。

創(chuàng)建 URI 實(shí)例

就像創(chuàng)建一個(gè)普通類實(shí)例一樣去創(chuàng)建一個(gè) URI 實(shí)例:

$uri = new \CodeIgniter\HTTP\URI();

或者,你可以使用 service() 方法來返回一個(gè) URI 實(shí)例:

$uri = service('uri');

當(dāng)創(chuàng)建新實(shí)例的時(shí)候,你可以將完整或部分 URL 傳遞給構(gòu)造函數(shù),其將會(huì)被解析為相應(yīng)的分段:

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');
$uri = service('uri', 'http://www.example.com/some/path');

當(dāng)前 URI

很多時(shí)候,你真正想要的是一個(gè)表示著當(dāng)前請(qǐng)求 URL 的對(duì)象??梢杂袃煞N不同的方式來獲取。第一,直接從當(dāng)前請(qǐng)求對(duì)象中提取。假設(shè)你所在的控制器已繼承自 CodeIgniter\Controller,可以這樣做:

$uri = $this->request->uri;

第二,你可以使用 url_helper 中的一個(gè)可用函數(shù)來獲取:

helper('url');
$uri = current_url(true);

你必須在第一個(gè)參數(shù)中傳遞 true,否則該函數(shù)將僅返回表示當(dāng)前 URL 的字符串。

URI 字符串

很多時(shí)候,你真正想要的是得到一個(gè)表示 URI 的字符串。那直接將 URI 對(duì)象轉(zhuǎn)換為字符串就可以了:

$uri = current_url(true);
echo (string)$uri;  // http://example.com

如果你知道 URI 的各個(gè)部分,同時(shí)還想確保其格式準(zhǔn)確無誤,你可以通過使用 URI 類的靜態(tài)方法 createURIString() 來生成字符串:

$uriString = URI::createURIString($scheme, $authority, $path, $query, $fragment);


// Creates: http://exmample.com/some/path?foo=bar#first-heading
echo URI::createURIString('http', 'example.com', 'some/path', 'foo=bar', 'first-heading');

URI 的組成

一旦你得到了一個(gè) URI 實(shí)例,你就可以設(shè)置或檢索這個(gè) URI 的任意部分。本節(jié)將詳細(xì)介紹這些部分的內(nèi)容及如何使用它們。

Scheme

最常見的傳輸協(xié)議是 ‘http’ 或 ‘https’,同時(shí)也支持如 ‘file’, ‘mailto’ 等其他協(xié)議。

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');


echo $uri->getScheme(); // 'http'
$uri->setScheme('https');

Authority

許多 URI 內(nèi)裝載著被統(tǒng)稱為 ‘a(chǎn)uthority’ 的數(shù)個(gè)元素,包括用戶信息,主機(jī)地址和端口號(hào)。你可以通過 getAuthority() 方法來獲取一個(gè)包含了所有相關(guān)元素的字符串,也可以對(duì)獨(dú)立的元素進(jìn)行操作。

$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path');


echo $uri->getAuthority();  // user@example.com:21

默認(rèn)情況下,因?yàn)槟悴幌M騽e人展示密碼,所以它不會(huì)被顯示出來。如你想展示密碼,可以使用 showPassword() 方法。URI 實(shí)例會(huì)在你再次關(guān)掉顯示之前一直保持密碼部分地展示,所以你應(yīng)在使用完成后立刻關(guān)閉它:

echo $uri->getAuthority();  // user@example.com:21
echo $uri->showPassword()->getAuthority();   // user:password@example.com:21


// Turn password display off again.
$uri->showPassword(false);

如果你不想顯示端口,可以傳遞唯一參數(shù) true:

echo $uri->getAuthority(true);  // user@example.com

注解

如果當(dāng)前端口值是傳輸協(xié)議的默認(rèn)端口值,那它將永遠(yuǎn)不會(huì)被顯示。

Userinfo

用戶信息部分是在使用 FTP URI 時(shí)你看到的用戶名和密碼。當(dāng)你能在 Authority 中得到它時(shí),你也可以通過方法直接獲取它:

echo $uri->getUserInfo();   // user

默認(rèn)情況下,它將不會(huì)展示密碼,但是你可以通過 showPassword() 方法來重寫它:

echo $uri->showPassword()->getUserInfo();   // user:password
$uri->showPassword(false);

Host

URI 的主機(jī)部分通常是 URL 的域名??梢酝ㄟ^ getHost()setHost() 方法很容易地設(shè)置和獲取:

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');


echo $uri->getHost();   // www.example.com
echo $uri->setHost('anotherexample.com')->getHost();    // anotherexample.com

Port

端口值是一個(gè)在 0 到 65535 之間的整數(shù)。每個(gè)協(xié)議都會(huì)有一個(gè)與之關(guān)聯(lián)的默認(rèn)端口值。

$uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path');


echo $uri->getPort();   // 21
echo $uri->setPort(2201)->getPort(); // 2201

當(dāng)使用 setPort() 方法時(shí),端口值會(huì)在通過可用范圍值檢查后被設(shè)置。

Path

路徑是站點(diǎn)自身的所有分段。如你所料,可以使用 getPath()setPath() 方法來操作它:

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');


echo $uri->getPath();   // 'some/path'
echo $uri->setPath('another/path')->getPath();  // 'another/path'

注解

以這種方式或類允許的其他方式設(shè)置 path 的時(shí)候,將會(huì)對(duì)危險(xiǎn)字符進(jìn)行編碼,并移除點(diǎn)分段來確保安全。

Query

查詢變量可以通過類使用簡(jiǎn)單的字符串來調(diào)整。Query 的值通常只能設(shè)定為一個(gè)字符串。

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar');


echo $uri->getQuery();  // 'foo=bar'
$uri->setQuery('foo=bar&bar=baz');

注解

Query 值不能包含片段,否則會(huì)拋出一個(gè) InvalidArgumentException 異常。

你可以使用一個(gè)數(shù)組來設(shè)置查詢值:

$uri->setQueryArray(['foo' => 'bar', 'bar' => 'baz']);

setQuery()setQueryArray() 方法會(huì)重寫已經(jīng)存在的查詢變量。你可以使用 addQuery() 方法在不銷毀已存在查詢變量的前提下追加值。第一個(gè)參數(shù)是變量名,第二個(gè)參數(shù)是值:

$uri->addQuery('foo', 'bar');

過濾查詢值

你可以對(duì) getQuery() 方法傳遞一個(gè)選項(xiàng)數(shù)組來過濾查詢返回值,使用關(guān)鍵字 onlyexcept:

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');


// Returns 'foo=bar'
echo $uri->getQuery(['only' => ['foo']);


// Returns 'foo=bar&baz=foz'
echo $uri->getQuery(['except' => ['bar']]);

這樣只是對(duì)調(diào)用方法后的返回值進(jìn)行更改。如果你需要對(duì) URI 對(duì)象的查詢值進(jìn)行永久地更改,可以使用 stripQuery()keepQuery() 方法來更改真實(shí)對(duì)象的查詢變量:

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');


// Leaves just the 'baz' variable
$uri->stripQuery('foo', 'bar');


// Leaves just the 'foo' variable
$uri->keepQuery('foo');

Fragment

片段是 URL 的結(jié)尾部分,前面是英鎊符號(hào) (#)。在 HTML 中,它們是指向頁面錨點(diǎn)的鏈接。媒體 URI 可以用其他各種方法來使用它們。

$uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path#first-heading');


echo $uri->getFragment();   // 'first-heading'
echo $uri->setFragment('second-heading')->getFragment();    // 'second-heading'

URI 分段

路徑中,斜杠之間的每一節(jié)都是一個(gè)單獨(dú)的分段。URI 類提供一個(gè)簡(jiǎn)單的方式去界定段值。路徑最左側(cè)的段為起始段 1。

// URI = http://example.com/users/15/profile


// Prints '15'
if ($request->uri->getSegment(1) == 'users')
{
        echo $request->uri->getSegment(2);
}

你能得到總分段數(shù)量:

$total = $request->uri->getTotalSegments(); // 3

最后,你能獲取到一個(gè)包含著所有分段的數(shù)組:

$segments = $request->uri->getSegments();


// $segments =
[
        0 => 'users',
        1 => '15',
        2 => 'profile'
]
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)