trim系列函數是用于去除字符串中首尾的空格或其他字符。ltrim函數只去除掉字符串首部的字符,rtrim函數只去除字符串尾部的字符。
trim參數說明string trim ( string $str [, string $character_mask = ' ' ] )
character_mask
默認是' '等空白字符。
使用..可以指定一段范圍的字符。此處要注意,'..'左右兩邊是一對合法的范圍值,如果傳遞的是非法的值會報錯。
運行示例先來看看用正常的使用:
$str = 'hello..';$new_str = trim($str, '.'); // 結果是hello
一個比較詭異的結果。這里報錯是因為php把..左右兩邊看作是范圍值,而此處'..'左邊是字符'.',PHP內部將認為其是一個缺少右邊界的范圍值。
$str = 'hello...';$second_str = trim($str, '...'); // 報錯
第二個參數使用合法的邊界值:
$str = 'helloabcdefg';$new_str = trim($str, 'a..g'); // 輸出hellotrim執行步驟
trim、ltrim、rtrim三個函數都是調用了php_do_trim函數,區別在于第二個參數mode的不同。本文主要對trim函數進行分析,ltrim和rtrim函數跟trim的類似。然后php_do_trim會調用了php_trim來實現功能,因此trim函數的核心函數時php_trim函數。其執行步驟如下:
1、根據what的值設置保存過濾字符的mask數組
2、過濾在字符串首部的待過濾字符
3、過濾在字符串尾部的待過濾字符
php_trim函數執行的流程圖如下:
php_trim函數先調用了php_charmask,這個函數試將過濾字符設置為mask[char] = 1的形式,這樣就是一個哈希數組,然后可用于后面的判斷。如果第二個參數是范圍值時,調用了memset函數給mask數組賦值。
在用mode變量判斷是哪種過濾時,此處有一個小優化,在PHP內部使用的是與運算,而不是多個的判斷條件。該部分代碼如下:
if (mode & 1) { for (i = 0; i < len; i++) { if (mask[(unsigned char)c[i]]) { trimmed++; } else { break; } } len -= trimmed; c += trimmed; } if (mode & 2) { for (i = len - 1; i >= 0; i--) { if (mask[(unsigned char)c[i]]) { len--; } else { break; } } }
判斷的過程:
1 && 1 == 1 左邊需要過濾
2 && 1 == 0 左邊不需要過濾
3 && 1 == 1 左邊需要過濾
1 && 2 == 0 右邊不需要過濾
2 && 2 == 1 右邊需要過濾
3 && 2 == 1 右邊需要過濾
像這樣使用位操作可以提高程序的效率,而且代碼更加簡潔易讀。
閱讀這個函數的源碼,首先學習到在C語言中,如果需要做鍵值對數組,而且鍵值是單個字符,可以使用unsigned char的類型做數組下標,這樣可以構造類似字符作為下標的映射數組。
第二個就是使用位運算可以提高程序效率和代碼可讀性。
原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。
如果本文對你有幫助,請點下推薦吧,謝謝^_^
最后,我在github有對PHP源碼更詳細的注解。感興趣的可以圍觀一下,給個star。PHP5.4源碼注解。
PHP編程鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答