「ulthon/uri」簡單又優雅地解析URL

php武器庫 發佈 2022-10-23T05:07:11.490924+00:00

一個能夠簡單地解析和操作URL的類庫。

一個能夠簡單地解析和操作URL的類庫。

開發中,我們會經常處理URL,在以前我們會向下面這樣做:

比如我們希望做一個在連結中增加lang參數的處理,可能會封裝這樣一個函數:

function switch_lang_url($lang)
{

    $url = Request::url();
    // 解析URL
    $url_info = parse_url($url);

    $query = [];

    // 獲取query,但有時不存在這個元素
    if (isset($url_info['query'])) {
        parse_str($url_info['query'], $query);
    }
    // 設置lang參數
    $query['lang'] = $lang;

    // 把新的query設置數組重新生成query
    $url_info['query'] = http_build_query($query);
    // 把url的設置重新生成url
    return unparse_url($url_info);
}

在上面我們可以看到,我們希望獲得url中的lang參數,返回新的帶有lang的參數。

但僅僅是這樣做是不夠的,我們還要再封裝一個unparse_url用於把url的解析結果編碼成url。

function unparse_url($parsed_url)
{
    $scheme   = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
    $host     = isset($parsed_url['host']) ? $parsed_url['host'] : '';
    $port     = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
    $user     = isset($parsed_url['user']) ? $parsed_url['user'] : '';
    $pass     = isset($parsed_url['pass']) ? ':' . $parsed_url['pass']  : '';
    $pass     = ($user || $pass) ? "$pass@" : '';
    $path     = isset($parsed_url['path']) ? $parsed_url['path'] : '';
    $query    = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
    $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
    return "$scheme$user$pass$host$port$path$query$fragment";
}

這樣一通操作下來,雖然代碼總體不複雜,但是寫起來很不順手,要處理很多邊界情況,比如:

  • 解析完url之後還要判斷query參數是否存在
  • 再把字符串的query轉成我們需要的數組
  • 設置完query數組還要再轉回去
  • 最後還要依賴一個外部參數生成最終的url

總之一個小小的替換url的get參數的事情,要寫的東西卻太多了。

新的操作

但是有這樣一個簡單卻實用的庫,能夠讓這些操作變得非常簡單,像下面這樣:

<?php
use Ulthon\URI\URI;

function switch_lang_url($lang)
{
    $url = 'https://phpreturn.com/index/a6310ae8e7c561.html?name=john&emailjohn@smith.com#fragment';
    $uri = URI::make($url);
    $url->set('lang',$lang);
    return $url->url();
}

是的,就這麼簡單,還可以使用鏈式操作,讓代碼更精簡:

<?php
use Ulthon\URI\URI;

function switch_lang_url($lang)
{
    $url = 'https://phpreturn.com/index/a6310ae8e7c561.html?name=john&emailjohn@smith.com#fragment';
    return  URI::make($url)->set('lang',$lang)->url()
}

使用文檔

最低支持php7.2,通過composer安裝:

composer require ulthon/uri

基本的使用方式如下,通過make靜態方法或手動實例化:

use Ulthon\URI\URI;

$url = 'https://phpreturn.com/index/a6310ae8e7c561.html?name=john&emailjohn@smith.com#fragment';

$uri = URI::make($url);

// 或者

$uri = new URI($url);

實例化完成之後,就可以使用類庫方法隨心所欲的操作URL。

比如設置協議或域名:

use Ulthon\URI\URI;

$url = 'phpreturn.com?name=john&emailjohn@smith.com';

$newUrl = URI::make($url)
    ->scheme('http') // 修改連結為: http://phpreturn.com/index/a6310ae8e7c561.html?name=john&emailjohn@smith.com
    ->domain('doc.ulthon.com') // 修改連結為: http://doc.ulthon.com/index/a6310ae8e7c561.html?name=john&emailjohn@smith.com
    ->url();

支持的方法如下:

  • scheme()
  • user()
  • pass()
  • host()
  • port()
  • path()
  • query()
  • fragment()

如果傳入參數,就是設置,否則只是讀取。比如我們要讀取域名:

use Ulthon\URI\URI;

$url = 'http://phpreturn.com?name=john&emailjohn@smith.com';

$domain = URI::make($url)
    ->domain();

他還支持更複雜的用法,比如解析相對路徑:

use Ulthon\URI\URI;

$url = 'http://phpreturn.com/dir/sub/file.php?name=john&emailjohn@smith.com';

$relativeUrl = '../../hello.php';

$newUrl = URI::make($url)
    ->relative($relativeUrl) // 連結修改為: http://phpreturn.com/hello.php?name=john&emailjohn@smith.com
    ->url();

在設置和獲取query時,支持通過點分隔符讀取多級數組,比如想要獲取這樣的值$_GET['post']['content']['html'] ,這時只需要使用post.content.html即可獲取。

query的操作有這些:

  • add() 添加get參數
  • remove() 刪除get參數
  • set() 設置get參數
  • get() 讀取get參數

其中remove方法支持通過回調函數方式:

$url = 'https://phpreturn.com/?utm_source=summer-mailer&utm_medium=email&utm_campaign=summer-sale';

$newUrl = URI::make($url)->remove(function ($key, $value) {
    return (bool)preg_match('#^utm_#si', $key);
})->url();

這樣一個庫,很簡單,卻很好用,提升開發幸福感。

原文標題:[ulthon/uri]簡單又優雅的解析URL

原文地址:https://phpreturn.com/index/a6353461657301.html

原文平台:PHP武器庫

版權聲明:本文由phpreturn.com(PHP武器庫官網)原創和首發,所有權利歸phpreturn(PHP武器庫)所有,本站允許任何形式的轉載/引用文章,但必須同時註明出處。

關鍵字: