CodeIgniter4 使用 URI 類(lèi)

2020-08-14 16:18 更新

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

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

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

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

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

  1. $uri = service('uri');

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

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

當(dāng)前 URI

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

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

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

  1. helper('url');
  2. $uri = current_url(true);

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

URI 字符串

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

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

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

  1. $uriString = URI::createURIString($scheme, $authority, $path, $query, $fragment);
  2. // Creates: http://exmample.com/some/path?foo=bar#first-heading
  3. echo URI::createURIString('http', 'example.com', 'some/path', 'foo=bar', 'first-heading');

URI 的組成

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

Scheme

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');
  2. echo $uri->getScheme(); // 'http'
  3. $uri->setScheme('https');

Authority

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

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

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

  1. echo $uri->getAuthority(); // user@example.com:21
  2. echo $uri->showPassword()->getAuthority(); // user:password@example.com:21
  3. // Turn password display off again.
  4. $uri->showPassword(false);

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

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

注解

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

Userinfo

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

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

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

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

Host

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');
  2. echo $uri->getHost(); // www.example.com
  3. echo $uri->setHost('anotherexample.com')->getHost(); // anotherexample.com

Port

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

  1. $uri = new \CodeIgniter\HTTP\URI('ftp://user:password@example.com:21/some/path');
  2. echo $uri->getPort(); // 21
  3. echo $uri->setPort(2201)->getPort(); // 2201

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

Path

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path');
  2. echo $uri->getPath(); // 'some/path'
  3. echo $uri->setPath('another/path')->getPath(); // 'another/path'

注解

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

Query

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar');
  2. echo $uri->getQuery(); // 'foo=bar'
  3. $uri->setQuery('foo=bar&bar=baz');

注解

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

你可以使用一個(gè)數(shù)組來(lái)設(shè)置查詢(xún)值:

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

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

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

過(guò)濾查詢(xún)值

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');
  2. // Returns 'foo=bar'
  3. echo $uri->getQuery(['only' => ['foo']);
  4. // Returns 'foo=bar&baz=foz'
  5. echo $uri->getQuery(['except' => ['bar']]);

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com?foo=bar&bar=baz&baz=foz');
  2. // Leaves just the 'baz' variable
  3. $uri->stripQuery('foo', 'bar');
  4. // Leaves just the 'foo' variable
  5. $uri->keepQuery('foo');

Fragment

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

  1. $uri = new \CodeIgniter\HTTP\URI('http://www.example.com/some/path#first-heading');
  2. echo $uri->getFragment(); // 'first-heading'
  3. echo $uri->setFragment('second-heading')->getFragment(); // 'second-heading'

URI 分段

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

  1. // URI = http://example.com/users/15/profile
  2. // Prints '15'
  3. if ($request->uri->getSegment(1) == 'users')
  4. {
  5. echo $request->uri->getSegment(2);
  6. }

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

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

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

  1. $segments = $request->uri->getSegments();
  2. // $segments =
  3. [
  4. 0 => 'users',
  5. 1 => '15',
  6. 2 => 'profile'
  7. ]
以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)