前端輸入通配符 *(如 sun*、*zhong*、sun*zhong*),後端需轉換為 MySQL LIKE 模式的 %。本文提供一個健壯的 PHP 處理函數,支持多段通配符、去除首尾多餘 %、空段過濾。
| 用戶輸入 | 轉換後 LIKE 模式 | 含義 |
|---|---|---|
sunzhongshan | sunzhongshan | 精確匹配 |
sun* | sun% | 以 sun 開頭 |
*shan | %shan | 以 shan 結尾 |
sun*shan | sun%shan% | 以 sun 開頭、以 shan 結尾 |
*zhong* | %zhong% | 包含 zhong |
sun*zhong* | sun%zhong% | 以 sun 開頭、包含 zhong |
function buildLikeConditions(string $input, string $column = 'username'): string {
// 1. * 替換為 %,%
$step1 = str_replace('*', '%,%', $input);
// 2. 去除首尾多餘 %
$step2 = trim($step1, '%');
// 3. 按逗號分割
$parts = explode(',', $step2);
// 4. 過濾空段並構建 LIKE 條件
$conditions = [];
foreach ($parts as $part) {
$part = trim($part);
if ($part === '') continue;
$conditions[] = "`$column` LIKE '$part'";
}
// 5. 組合 SQL 片段
return $conditions ? ' AND ' . implode(' AND ', $conditions) : '';
}
// 使用示例
$sql = "SELECT autoid FROM users WHERE 1=1";
$sql .= buildLikeConditions('sun*zhong*');
echo $sql;
// 輸出:SELECT autoid FROM users WHERE 1=1 AND `username` LIKE 'sun%' AND `username` LIKE '%zhong%'
str_replace('*', '%,%'):將單個 * 展開為 %,%,使得 sun*zhong → sun%,%zhong,分割後得到 sun% 和 %zhong。trim($str, '%'):移除首尾可能產生的多餘 %(如 *abc → %,%abc → %abc)。explode(','):按逗號分割為多段模式。LIKE 'sun%' AND LIKE '%zhong%',邏輯上為「同時滿足所有片段」,符合通配符語義。生產環境**務必使用預處理語句**:
$stmt = $pdo->prepare("SELECT autoid FROM users WHERE 1=1" . buildLikeConditions($input, '?'));
// buildLikeConditions 需改造為返回佔位符數組,並綁定參數
// 簡易版:手動構建佔位符
$parts = array_filter(explode(',', trim(str_replace('*', '%,%', $input), '%')));
$placeholders = implode(' AND ', array_fill(0, count($parts), "`username` LIKE ?"));
$stmt = $pdo->prepare("SELECT autoid FROM users WHERE 1=1 AND $placeholders");
$stmt->execute($parts);
若用戶需搜索字面 % 或 _,可約定轉義字符(如 \%、\_),在構建模式前替換:
$input = str_replace(['\%', '\_'], ['\\%', '\\_'], $input); // 保留給 LIKE 的轉義
此方案簡潔、無依賴、易維護,適合中小項目快速接入通配符搜索。