寫在前面
PHP也能幹大事是我總結的PHP文法特性及相關函數類庫的經典用法,並不一定是真正能實現四兩撥千斤的功效,但是掌握這些方法,可以在你的工作和學習上有一些協助,希望大家能集思廣益,將《PHP也能幹大事》豐富得更精彩!轉載請註明出處(jb51.net)
二、前言
PHP是常見的指令碼語言,主要是因為其簡單易學,上手快,幾乎50%以上的Web程式都有PHP的身影(不完全統計)。PHP為開發這提供了豐富的函數和API介面,這使得我們能夠非常方便地使用其強大的內建函數及擴充,本文是《PHP也能幹大事》系列的第一篇,主要總結PHP在編解碼、進位轉換方面的知識。
三、PHP編解碼
1、ASCII編解碼
ASCII(發音:英語發音:/ˈæski/ ASS-kee,American Standard Code for Information Interchange,美國資訊交換標準代碼)是基於拉丁字母的一套電腦編碼系統。它主要用於顯示現代英語,而其擴充版本EASCII則可以部分支援其他西歐語言,並等同於國際標準ISO/IEC 646。由於全球資訊網使得ASCII廣為通用,直到2007年12月,逐漸被Unicode取代。 https://zh.wikipedia.org/zh/ASCII
PHP基本函數內建了ASCII的編解碼函數,這使得我們能輕鬆進行ASCII編解碼。
int ord ( string $string ) //返回字串 string 第一個字元的 ASCII 碼值。
string chr ( int $ascii ) //返回相對應於 ascii 所指定的單個字元。
複製代碼 代碼如下:
<?php
$str = 'Welcome to China';
function getNum($string){
$needle = 0;
$num = '';
while (isset($string[$needle])) {
$num .= $num==0?'':' ';
$num .= ord($string[$needle]);
$needle++;
}
return $num;
}
function getChar($num){
$num_arr = explode(' ', $num);
$string = '';
foreach ($num_arr as $value) {
$string .= chr($value);
}
return $string;
}
echo "字元轉ASCII碼\n";
echo getNum($str);
echo "\n";
echo "ASCII碼字元\n";
echo getChar(getNum($str));
/* @OUTPUT
字元轉ASCII碼
87 101 108 99 111 109 101 32 116 111 32 67 104 105 110 97
ASCII碼字元
Welcome to China
*/
?>
2、URL編解碼
URL編碼是一種瀏覽器用來打包表單輸入的格式。瀏覽器從表單中擷取所有的name和其中的值,將它們以name/value參數編碼作為URL的一部分或者分離地發給伺服器。比如我們在訪問網頁中,會出現很多帶有%的字串,這就是URL編碼。
URL編碼一般採用UTF-8編碼格式,所以建議採用UTF-8格式傳遞資料。正常意義的URL編碼可以理解為ASCII碼的16進位前加上%,無大小寫區分。
複製代碼 代碼如下:
string urlencode(string $str) //此函數便於將字串編碼並將其用於URL的請求部分,同時它還便於將變數傳遞給下一頁。空格編碼成 + 。
string urldecode(string $str) //解碼給出的已編碼字串中的任何 %XX,加號('+')被解碼成一個空白字元。
string rawurlencode (string $str) //根據 RFC 3986 編碼指定的字元,空格轉換成%20。
string rawurldecode (string $str) //返回字串,此字串中百分比符號(%)後跟兩位十六進位數的序列都將被替換成原義字元。 + 不被轉換成空格。
兩組函數用法一樣,除了對於+和空格的轉換處理上:rawurlencode將空格轉為%20,不將+轉為空白格;urlencode則不一樣。
複製代碼 代碼如下:
<?php
$str_arr = array(
'www.jb51.net',
'http://www.jb51.net/',
'PHP也能幹大事',
'!@#$%^&*()_+=-~`[]{}|\\;:\'"<>,./?'
);
foreach ($str_arr as $key => $value) {
echo $value,"\t->\t",urlencode($value),"\n";
}
/* @OUTPUT
www.jb51.net -> www.jb51.net
http://www.jb51.net/ -> http%3A%2F%2Fwww.jb51.net%2F
PHP也能幹大事 -> PHP%E4%B9%9F%E8%83%BD%E5%B9%B2%E5%A4%A7%E4%BA%8B
!@#$%^&*()_+=-~`[]{}|\;:'"<>,./? -> %21%40%23%24%25%5E%26%2A%28%29_%2B%3D-%7E%60%5B%5D%7B%7D%7C%5C%3B%3A%27%22%3C%3E%2C.%2F%3F
*/
?>
3、Base64編解碼
Base64是一種基於64個可列印字元來表示位元據的表示方法。由於2的6次方等於64,所以每6個位元為一個單元,對應某個可列印字元。三個位元組有24個位元,對應於4個Base64單元,即3個位元組需要用4個可列印字元來表示。它可用來作為電子郵件的傳輸編碼。使用的字元包括大小寫字母各26個,加上10個數字,和加號「+」,斜杠「/」,一共64個字元,等號「=」用來作為尾碼用途。完整的base64定義可見RFC 1421和RFC 2045。編碼後的資料比未經處理資料略長,為原來的4/3。在電子郵件中,根據RFC 822規定,每76個字元,還需要加上一個斷行符號換行。可以估算編碼後資料長度大約為原長的135.1%。 https://zh.wikipedia.org/zh/Base64
string base64_encode(string $data) //使用 base64 對 data 進行編碼。
string base64_decode (string $data [, bool $strict = false ]) //對 base64 編碼的 data 進行解碼。
案例:HTML頁面中img標籤可以在src屬性中採用base64編碼方式,來輸出圖片,這樣可以減少HTTP請求次數。
複製代碼 代碼如下:
<?php
$string = file_get_content('3mc2.png');
echo '<img src="data:image/png;base64,',base64_encode($string),'">';
/* @OUTPUT
UEhQ5Lmf6IO95Yqe5aSn5LqL
*/
?>
4、HTML實體編解碼
一些字元在HTML中是預留的,擁有特殊的含義,比如小於符號「<」用於定義HTML標籤的開始。如果我們希望瀏覽器正確地顯示這些字元,我們必須在 HTML 源碼中插入字元實體。字元實體有三部分:一個和號「&」 和一個實體名稱(或者一個 「#」 和一個實體編號),以及一個分號「;」。http://www.ascii.cl/htmlcodes.htm
string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = “UTF-8″ [, bool $double_encode = true ]]] ) //對包含如下HTML特殊字元進行HTML實體編碼
1.'&' (ampersand) becomes ‘&'
2.'”‘ (double quote) becomes ‘"' when ENT_NOQUOTES is not set.
3.”‘” (single quote) becomes ‘'' (or ') only when ENT_QUOTES is set.
4.'<‘ (less than) becomes ‘<'
5.'>' (greater than) becomes ‘>'
string htmlspecialchars_decode (string $string [, int $flags = ENT_COMPAT | ENT_HTML401 ]) //此函數的作用和 htmlspecialchars() 剛好相反。它將特殊的HTML實體轉換回一般字元。
還有功能相同的函數htmlentities/html_entity_decode,這對函數甚至對漢字都進行了HTML實體編碼,而且會產生亂碼,所以建議使用htmlspecialchars進行編解碼。
案例:防止XSS跨站指令碼攻擊,需要對使用者提交的資料進行HTML實體轉換:
複製代碼 代碼如下:
<?php
$_POST['message'] = '測試留言字元\'"><sCript src=http://www.jb51.net/hook.js>';
if (empty($_POST['message'])) {
exit('Message is NULL');
}
$message = htmlspecialchars(trim($_POST['message']));
echo $message;
/* @OUTPUT
測試留言字元'"><sCript src=http://www.jb51.net/hook.js>
*/
?>
5、二進位、八進位、十進位、十六進位相互轉換
進位之間的轉換這裡沒什麼好說的,總之都差不多,只要記住多少進位就是逢多少進一位,比如10進位就是9的下一位就是10,二進位、八進位、十六進位以此類推。
string bin2hex (string $str) //返回 ASCII 字串,為參數 str 的十六進位表示。轉換使用位元組方式,高四位位元組優先。
string hex2bin (string $data) //轉換十六進位字串為二進位字串。
number bindec (string $binary_string) //返回 binary_string 參數所表示的位元的十進位等價值。
string decbin (int $number) //返回一字串,包含有給定 number 參數的二進位表示。所能轉換的最大數值為十進位的 4294967295,其結果為 32 個 1 的字串。
number octdec (string $octal_string) //返回 octal_string 參數所表示的八位元的十進位等值。
string decoct (int $number) //返回一字串,包含有給定 number 參數的八進位表示。所能轉換的最大數值為十進位的 4294967295,其結果為 “37777777777”。
string base_convert (string $number , int $frombase , int $tobase) //任意進位轉換,返回一字串,包含 number 以 tobase 進位的表示。number 本身的進位由 frombase 指定。frombase 和 tobase 都只能在 2 和 36 之間(包括 2 和 36)。高於十進位的數字用字母 a-z 表示,例如 a 表示 10,b 表示 11 以及 z 表示 35。
6 、GBK、UTF-8字元編碼轉換
在寫代碼過程中,經常遇到編碼問題而引發的亂碼。其實解決編碼問題非常簡單,只要使用一種編碼即可,一般來說,採用萬國碼——UTF-8是最好的選擇。
這裡說的編碼是文字編碼和檔案儲存體的編碼,當然,不得不提到系統的編碼的差異性:
系統 編碼 字元結尾
Windows GBK \r\n
*nix UTF-8 \n
所以在處理特殊字元的時候要特別注意。
常見的編碼有GBK、UTF-8等等,函數使用上一般採用兩種:
string mb_convert_encoding (string $str , string $to_encoding [, mixed $from_encoding = mb_internal_encoding() ]) //將 string 類型 str 的字元編碼從可選的 from_encoding 轉換到 to_encoding。
string iconv (string $in_charset , string $out_charset , string $str) //將字串 str 從 in_charset 轉換編碼到 out_charset。
案例:Windows系統,架設了一個WAMP伺服器,將如下指令碼另存新檔一個UTF-8編碼的php檔案,即可通過瀏覽器查看無亂碼的php目錄裡的檔案;如果不是用mb_convert_encoding轉碼,將直接導致輸出亂碼(Windows作為伺服器)。
複製代碼 代碼如下:
<?php
function getDir($dir){
static $string = '';
if(is_file($dir)){
$string.= $dir;
}else{
$oDir = @opendir($dir);
while($fileName = readdir($oDir)){
if($fileName!='.' && $fileName!='..'){
if(is_file($dir.'/'.$fileName)){
$string.=$fileName."\n";
}elseif(is_dir($dir.'/'.$fileName)){
$string.= $dir.'/'.$fileName.'/'."\n";
getDir($dir.'/'.$fileName);
}
}
}
}
return $string;
}
echo mb_convert_encoding( getDir('php'),'utf8', 'gbk' );
?>
四、總結
編碼是資料的處理的基礎,所以在PHP的編程開發過程中是相當重要的。對於PHP的處理方法,應用在編程中還需要數量掌握,特別有些相似函數要如何區分。轉載請註明出處(jb51.net)