進階 WWW 程式設計 -- PHP 語言結構 靜宜大學資訊管理學系 蔡奇偉副教授 2003 2018/9/17 進階 WWW 程式設計 PHP String 靜宜大學資訊管理學系 蔡奇偉副教授 2003 靜宜大學資管系 蔡奇偉編撰 版權所有 2003
內容大綱 列印字串 取得字串長度 存取字串中的字元 刪除首尾的空白 改變字串的大小寫 字串的比較 子字串的處理 字串的分解與組合 HTML 原始碼處理 URL 字串的處理 字串搜尋
列印 PHP 提供以下四個列印函式: echo – 輸出一個或多個字串(內建的列印函式)。 print – 輸出一個字串(內建的列印函式)。 printf – 輸出一個格式化的字串。 sprintf – 傳回一個格式化的字串。
範例 echo 指令 echo "Hello World"; echo "This spans multiple lines. The newlines will be output as well"; echo "This spans\nmultiple lines. The newlines will be\noutput as well."; echo "Escaping characters is done \"Like this\"."; //You can use variables inside of an echo statement $foo = "foobar"; $bar = "barbaz"; echo "foo is $foo"; // foo is foobar
// Using single quotes will print the variable name, not the value echo 'foo is $foo'; // foo is $foo // If you are not using any other characters, you can just echo variables echo $foo; // foobar echo $foo, $bar; // foobarbarbaz echo <<<END This uses the "here document" syntax to output multiple lines with $variable interpolation. Note that the here document terminator must appear on a line with just a semicolon no extra whitespace! END; // Because echo is not a function, following code is invalid. ($some_var) ? echo('true'): echo('false'); // However, the following examples will work: ($some_var) ? print('true'): print('false'); // print is a function echo $some_var ? 'true': 'false'; // changing the statement around
範例 print 指令 print("Hello World"); print "print() also works without parentheses."; print "This spans multiple lines. The newlines will be output as well"; print "This spans\nmultiple lines. The newlines will be\noutput as well."; print "escaping characters is done \"Like this\"."; // You can use variables inside of an print statement $foo = "foobar"; $bar = "barbaz"; print "foo is $foo"; // foo is foobar
// Using single quotes will print the variable name, not the value print 'foo is $foo'; // foo is $foo // If you are not using any other characters, you can just print variables print $foo; // foobar print <<<END This uses the "here document" syntax to output multiple lines with $variable interpolation. Note that the here document terminator must appear on a line with just a semicolon no extra whitespace! END;
echo 與 print 的差別 echo 可以接受以逗號隔開的多個參數,但 print 不可以,譬如: echo “Hello “, “world!\n”; // ok print “Hello “, “world!\n”; // error print “Hello “ . “world!\n”; // ok,改用字串連結運算子 . echo 是一個無傳回值的函式,然而 print 有傳回值:true 代表列印 成功,false 代表列印失敗。譬如: $ret = echo “Hello”; // error $ret = print “Hello”; // ok
printf() 函式 void printf ( string format [, mixed args] ) 按照格式字串 format 所指定的方式輸出參數 args。 格式字串包含底下兩個部份: % 以外的字元:忠實地一一輸出。 % 開頭的轉換規則(conversion specification) 轉換規則依序可包含以下的組成: 前導的填充字元:空白字元、0、或用單引號 ‘ 設定的字元(如 ’X)。預設的填充字元是空白字元。 對齊方式:預設為向右靠齊。我們可以用減號 – 改為向左靠齊。 寬度:指定輸出所需的最小字元數。
精準度:指定浮點數輸出的小數位數。此設定對非浮點數的資料無效。 資料型態:指定參數的資料型態解讀方式。以下是這些資料型態的代表字元: % % 字元 b 以二進位的格式輸出整數 c 把整數解讀為 ASCII 的字元碼,然後輸出該字元 d 以十進位的格式輸出整數 u 把整數視為正數然後輸出 f 輸出浮點數 o 以八進位的格式輸出整數 s 輸出字串 x 以十六進位的格式輸出整數 X 以十六進位的格式輸出整數
範例 %% 列印字元 %。 %04d 列印四位數的整數,若不足四位數,則左邊補零, 如:1234 印成 1234、123 印成 0123。 %% 列印字元 %。 %04d 列印四位數的整數,若不足四位數,則左邊補零, 如:1234 印成 1234、123 印成 0123。 %10s 保留 10 格來列印字串。若字串長度不足 10 個字 元,則左邊補空白,即靠右對齊。 %-10s 保留 10 格來列印字串。若字串長度不足 10 個字 元,則右邊補空白,即靠左對齊。 %01.2f 列印浮點數到小數第二位。如 123.1 印成 123.10、 123.123 印成 123.12、 123.456 印成 123.46。
Argument Swapping 為了克服自然語言結構上的差異,PHP 自 4.0.6 版之後,提供 argument swapping 的機制。我們用下面的例子來說明這個機制。 $format = "There are %d monkeys in the %s"; printf($format, $num, $location); 上述英文訊息 $format 中文化後,可能改成: $format = “ %s 有 %d 隻猴子"; 但這樣一來,printf 指令也得跟著修改成: printf($format, $location, $num); 如果利用底下 Argument swapping 的方法,我們就可以避免修改 printf 指令。
我們只要把中文訊息改寫成下一行所示就可以了: $format = “ %2\$s 有 %1\$d 隻猴子"; 對應第一個參數 對應第二個參數 Argument swapping 也可用來重複列印參數,如下例所示: $format = "The %2\$s contains %1\$d monkeys. That's a nice %2\$s full of %1\$d monkeys."; printf($format, $num, $location);
sprintf() 函式 string sprintf ( string format [, mixed args] ) 範例 sprintf() 的參數 format 和之前討論的 printf() 相同,都是用來設定輸出的格式。不過,sprintf() 傳回格式化後的字串,並不會像 printf() 般地直接輸出。 範例 $year = 2003; $month = 5; $day = 13; $isodate = sprintf("%04d-%02d-%02d", $year, $month, $day); // $isosate = "2003-05-13"
取得字串長度 int strlen ( string str ) 範例 這個函式傳回字串參數 str 的長度。 $aStr = “abcd”; $aStrLen = strlen($aStr); // $aStrLen == 4
存取字串中的字元 範例 你可以用索引的方式來存取字串中的字元。 $string = “Hello”; for ($i = 0; $i < strlen($string); $i++) { printf(“The %dth character is %s\n”, $i, $string[$i]); } 輸出結果: The 0th character is H The 1th character is e The 2th character is l The 3th character is l The 4th character is o
刪除首尾的空白 string trim ( string str [, string charlist] ) string ltrim ( string str [, string charlist] ) string rtrim ( string str [, string charlist] ) string chop ( string str [, string charlist] ) 上面的函式可用來刪除字串 str 中首尾的空白(或 charlist 所指定的字元集)。預設的空白字元如下表所示: 字元 ASCII 值 名稱 “ “ 32 空白字元 \t 9 水平跳位字元 \n 10 跳行字元 \r 13 歸位字元 \0 0 空值字元 \x0B 11 垂直跳位字元
範例 trim() 函式刪除字串首尾的空白或指定字元集中的字元。 $text = "\t\tThese are a few words :) ... "; $trimmed = trim($text); // $trimmed = "These are a few words :) ..." $trimmed = trim($text," \t. "); // $trimmed = "These are a few words :)" $clean = trim($binary,"\0x00..\0x1F"); // trim the ASCII control characters at the beginning and end of $binary // (from 0 to 31 inclusive)
範例 ltrim() 函式刪除字串首的空白或指定字元集中的字元。 $text = "\t\tThese are a few words :) ... "; $trimmed = ltrim($text); // $trimmed = "These are a few words :) ... " $trimmed = ltrim($text," \t."); $clean = ltrim($binary,"\0x00..\0x1F"); // trim the ASCII control characters at the beginning of $binary // (from 0 to 31 inclusive)
範例 rtrim() 函式或其同義函式 chop()刪除字串尾的空白或指定字元集中的字元。 $text = "\t\tThese are a few words :) ... "; $trimmed = rtrim($text); // $trimmed = "\t\tThese are a few words :) ..." $trimmed = rtrim($text," \t."); // $trimmed = "\t\tThese are a few words :)" $clean = rtrim($binary,"\0x00..\0x1F"); // trim the ASCII control characters at the end of $binary // (from 0 to 31 inclusive)
改變字串的大小寫 string strtolower ( string str ):改為小寫 範例 $str = "Mary Had A Little Lamb and She LOVED It So"; $str = strtolower($str); print $str; # Prints mary had a little lamb and she loved it so string strtoupper ( string string ) :改為大寫 範例 $str = "Mary Had A Little Lamb and She LOVED It So"; $str = strtoupper($str); print $str; // Prints MARY HAD A LITTLE LAMB AND SHE LOVED IT SO
string ucfirst ( string str ) :字串第一個字元改為大寫 範例 $foo = 'hello world!'; $foo = ucfirst($foo); // Hello world! $bar = 'HELLO WORLD!'; $bar = ucfirst($bar); // HELLO WORLD! $bar = ucfirst(strtolower($bar)); // Hello world! string ucwords ( string str ) :字串中每個字的第一個字元 改為大寫 範例 $foo = 'hello world!'; $foo = ucwords($foo); // Hello World! $bar = 'HELLO WORLD!'; $bar = ucwords($bar); // HELLO WORLD! $bar = ucwords(strtolower($bar)); // Hello World!
字串的比較 關係運算子 ==, ===, <, <=, >, >= 可用來比較字串的大小。不過碰到數字時,因為資料轉換的緣故,可能造成不正確的比較結果,譬如: $string = “PHP”; $number = 5; if ($string < $number) print “$string < $number”; 輸出結果: PHP < 5 這是因為 < 運算子的其中一個運算元若是數字,另一個運算元會先轉換成數值。因此 “PHP” 被轉換成數值 0,使得 $string < $number 成立。
int strcmp ( string str1, string str2 ) 為了解決前述的問題,PHP 提供底下純字串比較的函式: int strcmp ( string str1, string str2 ) 函式以字碼序來比較字串,傳回值如下: < 0 若 str1 小於 str2 0 若 str1 等於 str2 > 0 若 str1 大於 str2 int strcasecmp ( string str1, string str2 ) 類似上述的 strcmp() 函式,但忽略大小寫的區別,譬如: strcasecmp(“Hello”, “hello”) 的傳回值是 0,即兩個字串相等。
int strncmp ( string str1, string str2, int len ) 此函式與 strcmp() 類似,但最多只比較 len 參數所指定的字元個數(由字串頭算起)。譬如: $str1 = “sample”; $str2 =“sam”; $result1 = strncmp($str1, $str2, 3); // $result1 等於 0 $result2 = strncmp($str1, $str2, 4); // $result2 大於 0 int strncasecmp ( string str1, string str2, int len ) 此函式與 strcasecmp () 類似,但最多只比較 len 參數所指定的字元個數(由字串頭算起)。
int strnatcmp ( string str1, string str2 ) 對文字和數字組成的字串(如 ”img12.jpg”),PHP 提供下列兩個採用「自然序(natural order)」的比較函式: int strnatcmp ( string str1, string str2 ) int strnatcasecmp ( string str1, string str2 ) 下表列出自然序與字碼序的差異處: img1.png img10.png img12.png img2.png img1.png img2.png img10.png img12.png 自然序 ASCII 字碼序 關於自然序的細節,請參閱 http://www.naturalordersort.org/
子字串的處理 string substr ( string str, int start [, int length] ) 此函式從參數 string 取出自 start 位置開始的子字串,或自 start 位置開始的 length 個字元子字串。 1 start 1 start length
範例 $rest = substr("abcdef", 1); // returns "bcdef" $rest = substr("abcdef", 0, 4); // returns "abcd" $rest = substr("abcdef", 0, 8); // returns "abcdef"
範例 若 start 是負數,則由字串右方開始算起 length -1 start -2 -1 start length 範例 $rest = substr("abcdef", -1); // returns "f" $rest = substr("abcdef", -2); // returns "ef" $rest = substr("abcdef", -3, 1); // returns "d"
範例 若 legth 是負數,則扣除自 start 位置開始的子字串最右方 |length| 個字元。 |length| $rest = substr("abcdef", 0, -1); // returns "abcde" $rest = substr("abcdef", 2, -1); // returns "cde" $rest = substr("abcdef", 4, -4); // returns "" $rest = substr("abcdef", -3, -1); // returns "de"
string substr_replace ( string str, string replacement, int start [, int length] ) 此函式把 str 參數中由 start 和 length 所指定的子字串(見上述 substr() 的討論)用 replacement 字串取代。 範例 $var = 'ABCDEFGH:/MNRPQR/'; // These two examples replace all of $var with 'bob'. substr_replace($var, 'bob', 0); substr_replace($var, 'bob', 0, strlen($var)); // Insert 'bob' right at the beginning of $var. substr_replace($var, ‘bob’, 0, 0); // These next two replace 'MNRPQR' in $var with 'bob'. substr_replace($var, 'bob', 10, -1); substr_replace($var, 'bob', -7, -1); // Delete 'MNRPQR' from $var. substr_replace($var, "", 10, -1);
字串的分解與組合 array explode ( string separator, string str [, int limit] ) 此函式以字串 separator 為分隔,把字串 str 拆解存在陣列中然後傳回。若指定 limit 的話,則拆解成最多 limit 個陣列元素,而且最後的元素包含字串未拆解的剩餘部分。譬如底下兩行把 Unix 系統的帳號檔中帳號資料拆解並存入 $user, $pass, …, $shell 變數中: $passwd_line = "foo:*:1023:1000::/home/foo:/bin/sh"; list($user,$pass,$uid,$gid,$gecos,$home,$shell) = explode(":", $ passwd_line ); 又如下兩行敘述使得 $pieses 成為含有 “piece1”, …, 和 “piece6” 等 6 個元素的陣列。 $pizza = "piece1 piece2 piece3 piece4 piece5 piece6"; $pieces = explode(" ", $pizza);
string implode ( string glue, array pieces ) 此函式與上述 explode() 函式的作用剛好相反。它以 glue 字串用為分隔把陣列 pieces 所含的字串元素結合起來。譬如: $array = array('lastname', 'email', 'phone'); $comma_separated = implode(",", $array); print $comma_separated; // lastname,email,phone $colon_separated = implode(“:", $array); print $colon_separated; // lastname:email:phone
array split ( string pattern, string str [, int limit] ) 此函式的作用與 explode() 雷同,但提供更具彈性的分隔字串設定,因為參數 pattern 是一個規則算式(regular expression)(以後我們會專章討論規則算式)。譬如: list ($month, $day, $year) = split ('[/.-]', $date); 可用來拆解下列三種日期字串: 以 / 分隔,如 5/14/2003 以 . 分隔,如 5.14.2003 以 – 分隔,如 5-14-2003 array spliti ( string pattern, string str [, int limit] ) 此函式的與 split() 雷同,但忽略比對分隔字串時的大小寫區別。
HTML 原始碼處理 string htmlspecialchars ( string string [, int quote_style [, string charset]] ) 此函式把字串中屬於 HTML 的特殊字元(下表第一欄)轉換成其字元本體(entity)(下表第二欄)。 字元 字元本體 & (ampersand) & “ (double quote) "e; ‘ (single quote) ' < (less than) < > (greater than) >
範例 參數選項 quote_style 選擇引號的處理方式。它的值如下: ENT_COMPAT : 只轉換雙引號(此為預設值)。 ENT_QUOTES : 轉換單引號與雙引號。 ENT_NOQUOTES : 單引號與雙引號都不轉換。 參數選項 charset 選擇轉換所用的字碼值(預設值是 iso-8859-1)。 範例 $str = ‘if x > y, then set a to be “cube”’; $str1 = htmlspecialchars($str); // $str1 is ‘if x > y, then set a to be "e;cube"e;’; $str2 = htmlspecialchars($str, ENT_NOQUOTES); // $str2 is ‘if x > y, then set a to be “cube”’;
string htmlentities ( string string [, int quote_style [, string charset]] ) 此函式與前述的 htmlspecialchars() 功能雷同,但會轉換字串中所有具有字元本體的字元。 範例 $str = htmlentities(“Einstürzende Neubauten”); // $str is Einstürzende Neubauten // Note: ü 的字元本體是 ü
string html_entity_decode ( string string [, int quote_style [, string charset]] ) 此函式的功能與 htmlentities() 相反,亦即它把字串中的字元本體轉換成對應的字元。 範例 $str1 = htmlentities(“Einstürzende Neubauten”); // $str1 is “Einstürzende Neubauten” (Note: ü 的字元本體是 ü) $str2 = html_entity_decode ($str1); // str2 is “Einstürzende Neubauten”
string strip_tags ( string str [, string allowable_tags] ) 此函式移除字串 str 中的 HTML 與 PHP 標籤。 參數選項 allowable_tags 可用來指定不移除的標籤。 範例 $str1 = strip_tags (“The <b>tags</b> will be <i>removed</i>.”); // $str1 is “The tags will be removed.” $str2 = strip_tags(“The <b>bold</b> tags will <i>stay</i>.”, “<a><b>”); // str2 is “The <b>bold</b> tags will stay.”
string nl2br ( string str ) 此函式把字串 str 中的跳行字元(’\n’)轉換成 ‘<br />’ (PHP 4.0.5 之後)或 ‘<br>’ (PHP 4.0.5 之前)。 範例 $str = nl2br (“The first …\nThe second…\n”); // $str is “The first …<br />The second …<br />”);
URL 字串的處理 string rawurlencode ( string str ) 範例 此函式把字串中不合 URL 規定的字元(即除了文數字、底線字元 _、減號 -、和句號 . 以外的字元)用 %xx 來取代(xx 是該字元的 16 進位 ASCII 碼)。譬如:空白字元和 @ 字元會分別用 %20 和%40 來取代。 範例 $folder = “Advanced Web Programming”; $url_folder = rawurlencode($folder); echo “http://localhost/$url_folder”; // http://localhost/Advanced%20Web%20Programming
string rawurldecode ( string str ) 此函式的功能與 rawurlencode() 相反。它把字串 str 中的 %xx字碼(xx 是兩個 16 進位數字)轉換成對應的字元。 範例 $str = rawurldecode (‘foo%20bar%40baz’); // str is “foo bar@baz”
string urlencode ( string str ) 此函式的功能與 rawurlencode() 雷同,惟一的不同處在於它把空白字元用加號(+)來取代。此函式主要用於 URL 中查詢字串(query string)的編碼轉換。 範例 $base_url = ‘http://webprog.cs.pu.edu.tw/search?’; $query = ‘sid=PHP String’; $url = $base_url . urlencode($query); // $url is ‘http://webprog.cs.pu.edu.tw/search?sid= PHP+String’
string urldecode ( string str ) 此函式的功能與 urlencode() 相反。它把字串 str 中的 %xx字碼(xx 是兩個 16 進位數字)轉換成對應的字元、也把加號(+)轉成空白字元。 範例 $a = explode('&', $QUERY_STRING); $i = 0; while ($i < count($a)) { $b = split('=', $a[$i]); echo 'Value for parameter ', htmlspecialchars(urldecode($b[0])), ' is ', htmlspecialchars(urldecode($b[1])), "<br />\n"; $i++; }
array parse_url ( string url ) 此函式把包含 URL 的字串 url 拆解成以下的部分,並存入一個對照陣列中。 scheme e.g. http host port user pass path query - after the question mark ? fragment - after the hashmark #
字串的搜尋 int strpos ( string haystack, string needle [, int offset] ) 範例 在字串 haystack 中尋找字串 needle 第一次出現的地方。若找到,則傳回所在的位置,否則傳回 false。 若參數 needle 不是字串,則會先轉換成整數並把其視為字碼,然後再進行尋找。 若指定參數選項 offset,則從 offset 位置開始尋找。 範例 $ret = strpos(“abcabc”, “c”); // $ret == 2 $ret = strpos(“abcabc”, 99); // $ret == 2 $ret = strpos(“abcabc”, “c”, 3); // $ret == 5 $ret = strpos(“abcabc”, “d”); // $ret == false
int strrpos ( string haystack, string needle) 在字串 haystack 中尋找字串 needle 最後出現的地方。若找到,則傳回所在的位置,否則傳回 false。 若參數 needle 不是字串,則會先轉換成整數並把其視為字碼,然後再進行尋找。 範例 $ret = strrpos(“abcabc”, “c”); // $ret == 5 $ret = strrpos(“abcabc”, 99); // $ret == 5 $ret = strpos(“abcabc”, “d”); // $ret == false
註:strchr() 是 strstr() 的別名。 string strstr ( string haystack, string needle ) 在 haystack 中,傳回從 needle 第一次出現的位置到結尾的子字串。若 needle 不在 haystack 中,則傳回 false。 若參數 needle 不是字串,則會先轉換成整數並把其視為字碼,然後再進行尋找。 註:strchr() 是 strstr() 的別名。 範例 $ret = strstr(“abcabc”, “c”); // $ret == “cabc” $ret = strstr(“abcabc”, 99); // $ret == “cabc” $ret = strstr(“abcabc”, “d”); // $ret == false $ret = strstr(“someone@yahoo.com.tw”, “@”); // $ret == “@yahoo.com.tw” $domain = substr($ret, 1); // $domain == “yahoo.com.tw”
string strrchr ( string haystack, string needle ) 在 haystack 中,傳回從 needle 最後出現的位置到結尾的子字串。若 needle 不在 haystack 中,則傳回 false。 若參數 needle 不是字串,則會先轉換成整數並把其視為字碼,然後再進行尋找。 範例 $ret = strrchr(“abcabc”, “c”); // $ret == “c” $ret = strrchr(“abcabc”, 99); // $ret == “c” $ret = strrchr(“abcabc”, “d”); // $ret == false $ret = strrchr(“/etc/passwd”, “/”); // $ret == “/passwd” $file = substr($ret, 1); // $file == “passwd”
int strspn ( string str, string charset ) 傳回只包含 charset 中的字元而且自 str 第一個字元開始的最大子字串的長度。 範例 $ret = strspn("42 is the answer,...", "1234567890"); // $ret == 2 // 底下的函式檢查字串 $str 是否全由八進位數字所組成 function is_octal ($str) { return strspn($str, “01234567”) == strlen($str); }
int strcspn ( string str, string charset ) 傳回不包含 charset 中的任一字元而且自 str 第一個字元開始的最大子字串的長度。此函式可說是 strspn() 的互補函式。 範例 $ret = strcspn("42 is the answer,...", "1234567890"); // $ret == 0 $ret = strcspn("42 is the answer,...", “abc"); // $ret == 10 // 檢查字串 $str 是否含有字元 \n, \t, 或 \0。若有的話,$ret 將是一個 // 大於 0 的值,若沒有的話,$ret 的值將是 0。 $ret = strcspn($str, “\n\t\0”);