Ctype 擴展提供一組高效的字元類型檢測函數,比正則表達式更快、語義更清晰。本文完整列舉所有函數、參數陷阱、效能比較與實戰建議。
| 函數 | 檢測內容 | 對應字元範圍 | 範例通過 | 範例失敗 |
|---|---|---|---|---|
| ctype_alnum() | 英數字 | A-Z, a-z, 0-9 | "Abc123" | "Abc-123" |
| ctype_alpha() | 純字母 | A-Z, a-z | "Abc" | "Abc123" |
| ctype_cntrl() | 控制字元 | \n, \r, \t, \0... | "\n\r\t" | "abc" |
| ctype_digit() | 純數字 | 0-9 | "12345" | "12.34", "-10" |
| ctype_graph() | 可列印非空白 | !-~ (ASCII 33-126) | "abc#" | "abc " |
| ctype_lower() | 純小寫字母 | a-z | "abc" | "Abc", "abc1" |
| ctype_print() | 可列印含空白 | 空白 + graph | "abc " | "\n" |
| ctype_punct() | 標點符號 | 非英數、非空白的可列印 | "!@#$" | "a1", " " |
| ctype_space() | 空白字元 | 空格, \n, \r, \t, \v, \f | " \n\t" | "a" |
| ctype_upper() | 純大寫字母 | A-Z | "ABC" | "Abc", "ABC1" |
| ctype_xdigit() | 十六進位 | 0-9, a-f, A-F | "1a3F" | "1g", "1.5" |
<?php
$str1 = 'Azxc1234'; // true
$str2 = '123#Axy'; // false
if (ctype_alnum($str1)) {
echo "This string totally works";
} else {
echo "And this one not so much";
}
<?php
$integer = 42;
ctype_digit($integer); // false!整數被視為 ASCII 碼 42 ('*')
ctype_digit((string)$integer); // true 正確:轉字串後檢測
// 空字串行為(PHP 5.1+)
ctype_alnum(''); // false(早期版本為 true)
鐵律:永遠確保傳入字串型別,必要時強制轉型 (string)$var。
<?php
$test = 'abcdefghijklmnopqrstuvwxyz0123456789';
$iterations = 100000;
// ctype_alpha
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) ctype_alpha($test);
echo "ctype_alpha: " . (microtime(true) - $start) . "s\n";
// 正則
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) preg_match('/^[a-z]+$/i', $test);
echo "preg_match: " . (microtime(true) - $start) . "s\n";
// is_* 系列(注意:is_numeric 包含浮點、科學記號)
$start = microtime(true);
for ($i = 0; $i < $iterations; $i++) ctype_digit($test);
echo "ctype_digit: " . (microtime(true) - $start) . "s\n";
典型結果: ctype 系列比正則快 3-10 倍,比 is_* 更精確(is_numeric 允許 +-.eE)。
| 場景 | 推薦函數 | 避坑提醒 |
|---|---|---|
| 驗證純數字 ID | ctype_digit((string)$id) | is_numeric() 會通過 "1.5", "1e3" |
| 驗證用戶名(英數) | ctype_alnum($username) | 需額外檢查長度、禁止關鍵字 |
| 驗證十六進位顏色 | ctype_xdigit($color) | 需配合 strlen==6 或 3 |
| 檢測控制字元(安全) | ctype_cntrl($input) | 防止注入換行、Null 字元 |
| 驗證純字母代碼 | ctype_alpha($code) | 區分大小寫需搭配 lower/upper |
| 密碼複雜度檢查 | 組合使用 | 需自行實作邏輯:長度+大小寫+數字+符號 |
<?php
class Validator {
public static function username($str) {
return is_string($str)
&& strlen($str) >= 3
&& strlen($str) <= 20
&& ctype_alnum($str)
&& !preg_match('/^(admin|root|system)$/i', $str);
}
public static function password($str) {
if (!is_string($str) || strlen($str) < 8) return false;
$hasUpper = $hasLower = $hasDigit = $hasSymbol = false;
for ($i = 0; $i < strlen($str); $i++) {
$c = $str[$i];
if (ctype_upper($c)) $hasUpper = true;
elseif (ctype_lower($c)) $hasLower = true;
elseif (ctype_digit($c)) $hasDigit = true;
else $hasSymbol = true;
}
return $hasUpper && $hasLower && $hasDigit && $hasSymbol;
}
public static function hexColor($str) {
return is_string($str)
&& (strlen($str) === 6 || strlen($str) === 3)
&& ctype_xdigit($str);
}
public static function noControlChars($str) {
for ($i = 0; $i < strlen($str); $i++) {
if (ctype_cntrl($str[$i])) return false;
}
return true;
}
}
// 使用
var_dump(Validator::username('john123')); // true
var_dump(Validator::username('john@123')); // false
var_dump(Validator::password('Abc123!@')); // true
var_dump(Validator::password('abc123')); // false
var_dump(Validator::hexColor('ff00aa')); // true
var_dump(Validator::hexColor('ff00gg')); // false
<?php
if (!extension_loaded('ctype')) {
die('Ctype extension not loaded. Install: docker-php-ext-install ctype');
}
// 或運行時檢查
function ctype_safe($func, $str) {
if (!is_string($str)) return false;
return $func($str);
}
// 使用
ctype_safe('ctype_alnum', $input);
(string)$var 避免整數/浮點誤判ctype_cntrl() 可作為輸入淨化第一道防線Ctype 是 PHP 內建的高效工具,善用它能寫出更快、更安全、更易讀的驗證程式碼。