CodeIgniter4 使用 URI 類

2020-08-14 16:18 更新

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

創(chuàng)建 URI 實例

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

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

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

$uri = service('uri');

當(dāng)創(chuàng)建新實例的時候,你可以將完整或部分 URL 傳遞給構(gòu)造函數(shù),其將會被解析為相應(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

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

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

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

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

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

URI 字符串

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

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

如果你知道 URI 的各個部分,同時還想確保其格式準(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 的組成

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

Scheme

最常見的傳輸協(xié)議是 ‘http’ 或 ‘https’,同時也支持如 ‘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ù)個元素,包括用戶信息,主機地址和端口號。你可以通過 getAuthority() 方法來獲取一個包含了所有相關(guān)元素的字符串,也可以對獨立的元素進行操作。

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


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

默認(rèn)情況下,因為你不希望向別人展示密碼,所以它不會被顯示出來。如你想展示密碼,可以使用 showPassword() 方法。URI 實例會在你再次關(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)端口值,那它將永遠不會被顯示。

Userinfo

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

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

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

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

Host

URI 的主機部分通常是 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

端口值是一個在 0 到 65535 之間的整數(shù)。每個協(xié)議都會有一個與之關(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è)置。

Path

路徑是站點自身的所有分段。如你所料,可以使用 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 的時候,將會對危險字符進行編碼,并移除點分段來確保安全。

Query

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

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


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

注解

Query 值不能包含片段,否則會拋出一個 InvalidArgumentException 異常。

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

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

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

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

過濾查詢值

你可以對 getQuery() 方法傳遞一個選項數(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']]);

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

$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é)尾部分,前面是英鎊符號 (#)。在 HTML 中,它們是指向頁面錨點的鏈接。媒體 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é)都是一個單獨的分段。URI 類提供一個簡單的方式去界定段值。路徑最左側(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

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

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


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號