1. 程式人生 > >PHP中的URL處理

PHP中的URL處理

似的 技術分享 ima resp eric 將在 媒體類型 解碼 callback

一,函數介紹

1.解析HTTP頭信息:get_header()

array get_headers ( string 目標URL [, int $format = 0 【如果將可選的 format 參數設為 1,則 get_headers() 會解析相應的信息並設定數組的鍵名】] )

返回包含有服務器響應一個 HTTP 請求所發送標頭的索引或關聯數組,如果失敗則返回 FALSE

相似的還有

apache_request_headers(void) 返回包含當前Apache請求所有頭信息的數組,失敗返回 FALSE

apache_response_headers(void)成功時返回包含全部 Apache 響應頭信息的數組, 或者在失敗時返回 FALSE

.


2.解釋meta標簽:get_meta_tags()

array get_meta_tags ( string $filename [, bool $use_include_path = false ] )

參數:

filename

  HTML 文件的路徑字符串。 此參數可以是本地文件也可以是一個 URL。

use_include_path

  將 use_include_path 設置為 TRUE 將使 PHP 嘗試按照 include_path 標準包含路徑中的每個指向去打開文件。這只用於本地文件,不適用於 URL。

打開 filename 逐行解析文件中的 <meta> 標簽。解析工作將在 </head>

處停止。

返回一個數組,包含所有解析過的 meta 標簽。

返回的關聯數組以屬性 name 的值作為鍵,屬性 content 的值作為值,所以你可以很容易地使用標準數組函數遍歷此關聯數組或訪問某個值。 屬性 name 中的特殊字符將使用‘_’替換,而其它字符則轉換成小寫。如果有兩個 meta 標簽擁有相同的 name,則只返回最後出現的那一個。


3.生成URL請求字符串:http_build_query()

string http_build_query ( mixed $query_data [, string $numeric_prefix [, string $arg_separator
[, int $enc_type = PHP_QUERY_RFC1738 ]]] )

參數:

query_data

  可以是數組或包含屬性的對象。

  一個 query_data 數組可以是簡單的一維結構,也可以是由數組組成的數組(其依次可以包含其它數組)。

  如果 query_data 是一個對象,只有 public 的屬性會加入結果。

numeric_prefix

  如果在基礎數組中使用了數字下標同時給出了該參數,此參數值將會作為基礎數組中的數字下標元素的前綴。

  這是為了讓 PHP 或其它 CGI 程序在稍後對數據進行解碼時獲取合法的變量名。

arg_separator

  除非指定並使用了這個參數,否則會用 arg_separator.output 來分隔參數。

enc_type

  默認使用 PHP_QUERY_RFC1738

  如果 enc_typePHP_QUERY_RFC1738,則編碼將會以 ? RFC 1738 標準和 application/x-www-form-urlencoded 媒體類型進行編碼,空格會被編碼成加號(+)。

  如果 enc_typePHP_QUERY_RFC3986,將根據 ? RFC 3986 編碼,空格會被百分號編碼(%20)。

返回:

  返回一個 URL 編碼後的字符串。

例:

技術分享
<?php

$data = array(
              ‘mother‘,‘father‘,‘son‘,
              ‘foo‘=>‘bar‘,
              ‘baz‘=>‘boom‘,
              ‘cow‘=>‘milk‘,
              ‘php‘=>‘hypertext processor‘,
              ‘user‘=>array(
                    ‘name‘=>‘bob‘,
                    ‘age‘=>17,
                    ‘class‘=>‘one‘
                    )
              );

echo http_build_query($data) . "<br/>";
echo http_build_query($data, ‘‘, ‘&amp;‘).‘<br/>‘;
echo http_build_query($data, ‘P_‘, ‘&amp;‘).‘<br/>‘;

輸出:
/*
0=mother&1=father&2=son&foo=bar&baz=boom&cow=milk&php=hypertext+processor&user%5Bname%5D=bob&user%5Bage%5D=17&user%5Bclass%5D=one
0=mother&1=father&2=son&foo=bar&baz=boom&cow=milk&php=hypertext+processor&user%5Bname%5D=bob&user%5Bage%5D=17&user%5Bclass%5D=one
P_0=mother&P_1=father&P_2=son&foo=bar&baz=boom&cow=milk&php=hypertext+processor&user%5Bname%5D=bob&user%5Bage%5D=17&user%5Bclass%5D=one
*/
View Code


4.解析URL並返回其組成部分:parse_url()

mixed parse_url ( string $url [, int $component = -1 ] )

參數

url

要解析的 URL。無效字符將使用 _ 來替換。

component

指定 PHP_URL_SCHEMEPHP_URL_HOSTPHP_URL_PORTPHP_URL_USERPHP_URL_PASSPHP_URL_PATHPHP_URL_QUERYPHP_URL_FRAGMENT 的其中一個來獲取 URL 中指定的部分的 string。 (除了指定為 PHP_URL_PORT 後,將返回一個 integer 的值)。

返回:

對嚴重不合格的 URL,parse_url() 可能會返回 FALSE

如果省略了 component 參數,將返回一個關聯數組 array,在目前至少會有一個元素在該數組中。數組中可能的鍵有以下幾種:

  • scheme - 如 http
  • host
  • port
  • user
  • pass
  • path
  • query - 在問號 ? 之後
  • fragment - 在散列符號 # 之後

如果指定了 component 參數, parse_url() 返回一個 string (或在指定為 PHP_URL_PORT 時返回一個 integer)而不是 array。如果 URL 中指定的組成部分不存在,將會返回 NULL

parse_url可以解釋丟失協議的url如://www.baidu.com/index.php?a=1&b=2

parse_url不能用於相對url


5.將字符串解釋成多個變量:parse_str()

void parse_str ( string $str [, array &$arr ] )

如果 str 是 URL 傳遞入的查詢字符串(query string),則將它解析為變量並設置到當前作用域。

獲取當前的 QUERY_STRING,你可以使用 $_SERVER[‘QUERY_STRING‘] 變量。

magic_quotes_gpc 影響到了 parse_str() 這個函數的輸出,和 PHP 用於填充 $_GET$_POST 及其他變量的機制一致。

雖然第二個參數為可選,但如果不填,則處理後的數據也無處安放,因此一般2個參數都填上。

例:parse_str完美解釋http_bulid_query()生成的請求字符串

技術分享
<?php
$data = array(
              ‘mother‘,‘father‘,‘son‘,
              ‘foo‘=>‘bar‘,
              ‘baz‘=>‘boom‘,
              ‘cow‘=>‘milk‘,
              ‘php‘=>‘hypertext processor‘,
              ‘user‘=>array(
                    ‘name‘=>‘bob‘,
                    ‘age‘=>17,
                    ‘class‘=>‘one‘
                    )
              );

$query=http_build_query($data);
parse_str($query,$arr);
var_dump($arr);

/*
輸出
array (size=8)
  0 => string ‘mother‘ (length=6)
  1 => string ‘father‘ (length=6)
  2 => string ‘son‘ (length=3)
  ‘foo‘ => string ‘bar‘ (length=3)
  ‘baz‘ => string ‘boom‘ (length=4)
  ‘cow‘ => string ‘milk‘ (length=4)
  ‘php‘ => string ‘hypertext processor‘ (length=19)
  ‘user‘ => 
    array (size=3)
      ‘name‘ => string ‘bob‘ (length=3)
      ‘age‘ => string ‘17‘ (length=2)
      ‘class‘ => string ‘one‘ (length=3)
*/
View Code


6.URL參數字符串編碼,解碼:urlencode(),urldecode()

string urlencode ( string $str )

此函數便於將字符串編碼並將其用於 URL 的請求部分,同時它還便於將變量傳遞給下一頁。

返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數,空格則編碼為加號(+)。此編碼與 WWW 表單 POST 數據的編碼方式是一樣的,同時與 application/x-www-form-urlencoded 的媒體類型編碼方式一樣。由於歷史原因,此編碼在將空格編碼為加號(+)方面與 ? RFC3896 編碼(參見 rawurlencode())不同。

string urldecode ( string $str )

解碼給出的已編碼字符串中的任何 %##。 加號(‘+‘)被解碼成一個空格字符。

返回解碼後的字符串。

註意改函數僅用於對URL請求參數部分進行編解碼。


7.URL參數字符串編碼,解碼:rawurlencode(),rawurldecode()

string rawurlencode ( string $str )

根據 ? RFC 3986 編碼指定的字符。

返回字符串,此字符串中除了 -_. 之外的所有非字母數字字符都將被替換成百分號(%)後跟兩位十六進制數。這是在 ? RFC 3986 中描述的編碼,是為了保護原義字符以免其被解釋為特殊的 URL 定界符,同時保護 URL 格式以免其被傳輸媒體(像一些郵件系統)使用字符轉換時弄亂。

string rawurldecode ( string $str )

返回字符串,此字符串中百分號(%)後跟兩位十六進制數的序列都將被替換成原義字符。

rawurldecode() 不會把加號(‘+‘)解碼為空格,而 urldecode() 可以。

8.獲取文件路徑信息:pathinfo()

mixed pathinfo ( string $path [, int $options = PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME ] )

pathinfo() 返回一個關聯數組包含有 path 的信息。返回關聯數組還是字符串取決於 options

參數:

path

  要解析的路徑。

options

  如果指定了,將會返回指定元素;它們包括:PATHINFO_DIRNAMEPATHINFO_BASENAMEPATHINFO_EXTENSIONPATHINFO_FILENAME

  如果沒有指定 options 默認是返回全部的單元。

返回:

  如果沒有傳入 options ,將會返回包括以下單元的數組 array:dirnamebasenameextension(如果有),以 及filename。如果有,則返回options所指定的值

相似的還有:

  dirname()返回文件路徑目錄部分,相當於pathinfo(path,PATHINFO_DIRNAME)

  basename()返回路徑中文件名部分,相當於pathinfo(path,PATHINFO_BASENAME)


二,實踐應用

1.獲取URL中的參數

例:http://www.baidu.com/index.php?m=content&c=index&a=lists&catid=6&area=0&author=九把刀&h=嘿嘿嘿‘

解決方法:

//第一種:切割字符串
function params($url)
{
    $p=[];
    $urls=explode(‘?‘,$url);
    $params=str_replace(‘&&‘,‘&‘,$urls[1]);
    $params_arr=explode(‘&‘,$params);
    foreach($params as $param)
    {
        $_v=explode(‘=‘,$param);
        $p[$_v[0]]=$_v[1];
    }
    return $p;
}

//第二種:使用正則匹配
function params($url)
{
    $p=[];
    preg_match_all(‘/([^\=\?\&]+)\=([^&$]+)/‘,$url,$matches);
    
    foreach($matches[1] as $k=>$v)
    {
        $p[$matches[1][$k]]=$matches[2][$k];
    }
    return $p;
}
//第三種,使用parse_url配合parse_str,最簡便
function params($url)
{
    $query=parse_url($url,PHP_URL_QUERY);
    //或parse_url($url)[‘query‘]
    parse_str($query,$p);
    return $p;
}

2,將HTML文檔中的<img src="/images/1.jpg">替換為絕對路徑,根目錄http://www.pic.com

解決:

$newdoc=preg_replace_callback(‘/<img[\s\S]+src\s*=\s*[\‘\"](\/[^\‘\"]+)[\‘\"]/‘,function($m){
    
    if(empty(parse_url($m[1],PHP_URL_HOST)))
    {
        $newsrc=‘http://www.pic.com/‘.ltrim($m[1],‘/‘);
        return str_replace($m[1],$newsrc,$m[0]);
    }
    
},$html);

未完...

PHP中的URL處理