檢測字串是否僅包含合法的目錄名稱字元:英數字、底線、連字號、點號。適用於使用者輸入的目錄名稱驗證。
原始碼有語法錯誤(`for` 迴圈條件不完整、`nerror` 未定義),以下是修正並加強的版本:
<?php
/**
* 檢測目錄名稱合法性
* @param string $str 待檢測字串
* @param bool $strict 嚴格模式:true=僅允許英數字底線連字號點,false=允許中文等
* @return string|false 合法時回傳原字串,不合法回傳 false
*/
function isValidDirName($str, $strict = true) {
if (!is_string($str) || $str === '') return false;
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$p = ord($str[$i]);
if ($strict) {
// 僅允許:0-9 (48-57)、A-Z (65-90)、a-z (97-122)、_ (95)、- (45)、. (46)
if (($p < 48 || $p > 57) && ($p < 65 || $p > 90) && ($p < 97 || $p > 122)
&& $p !== 95 && $p !== 45 && $p !== 46) {
return false;
}
} else {
// 寬鬆模式:排除控制字元、斜線、冒號、星號、問號、引號、小於大於、縱線
if ($p < 32 || $p === 47 || $p === 58 || $p === 42 || $p === 63
|| $p === 34 || $p === 60 || $p === 62 || $p === 124) {
return false;
}
}
}
// 額外檢查:不可為 . 或 ..
if ($str === '.' || $str === '..') return false;
// 禁止以點開頭(隱藏目錄),視需求決定
// if ($str[0] === '.') return false;
return $str;
}
// 使用範例
var_dump(isValidDirName('valid_name-123')); // true
var_dump(isValidDirName('invalid/name')); // false
var_dump(isValidDirName('')); // false
var_dump(isValidDirName('.')); // false
?>
function isValidDirNameRegex($str, $strict = true) {
if (!is_string($str) || $str === '') return false;
if ($str === '.' || $str === '..') return false;
$pattern = $strict
? '/^[a-zA-Z0-9_.-]+$/' // 嚴格:英數字 _ - .
: '/^[^\\x00-\\x1F\\/:*?"<>|]+$/'; // 寬鬆:排除控制字元與 Windows 非法字元
return (bool)preg_match($pattern, $str) ? $str : false;
}
| 作業系統 | 禁止字元 | 保留名稱 |
|---|---|---|
| Windows | \ / : * ? " < > | 及控制字元 (0-31) | CON, PRN, AUX, NUL, COM1-9, LPT1-9 |
| Linux/Unix | / 及 null 字元 | 無(區分大小寫) |
| macOS (APFS) | / : 及控制字元 | 無 |