PHP 內建豐富的網路協議支援:SMTP 郵件發送、URL 解析編碼、FTP 檔案傳輸、DNS 查詢等。本文系統整理這些高頻網路函數,附參數詳解、安全提醒與實戰範例。
bool mail(string $to, string $subject, string $message, array|string $additional_headers = [], string $additional_params = ''): bool
$to:收件人,格式 `"user@example.com"` 或 `"Name $subject:主題,**不可包含換行** (防注入)$message:內文,每行不超過 70 字元,行尾 `\r\n`$additional_headers:額外表頭 (From, Cc, Bcc, Content-Type, Reply-To...),陣列或 `\r\n` 分隔字串$additional_params:傳給 sendmail 的額外參數 (如 `-f bounce@example.com`)$to = 'user@example.com';
$subject = '歡迎註冊';
$message = '
歡迎加入!
您的帳號已啟用。
';
$headers = [
'From: 系統 ',
'Reply-To: support@example.com',
'Content-Type: text/html; charset=UTF-8',
'X-Mailer: PHP/' . PHP_VERSION
];
// 發送
if (mail($to, $subject, $message, $headers)) {
echo "發送成功";
} else {
echo "發送失敗";
}
// 注意:mail() 依賴系統 sendmail/postfix,Windows 需在 php.ini 設定 SMTP 埠
// 生產環境強烈建議使用 PHPMailer/Symfony Mailer 透過 SMTP 發送
function safeMail($to, $subject, $message, $headers = []) {
// 過濾換行字元
$subject = str_replace(["\r", "\n"], '', $subject);
$to = str_replace(["\r", "\n"], '', $to);
foreach ($headers as $k => $v) {
$headers[$k] = str_replace(["\r", "\n"], '', $v);
}
return mail($to, $subject, $message, $headers);
}
$url = 'https://user:pass@example.com:8080/path/to/page?query=value#fragment';
$parts = parse_url($url);
/*
[
'scheme' => 'https',
'host' => 'example.com',
'port' => 8080,
'user' => 'user',
'pass' => 'pass',
'path' => '/path/to/page',
'query' => 'query=value',
'fragment' => 'fragment'
]
*/
// 實戰:提取域名
$host = parse_url($url, PHP_URL_HOST); // 'example.com' (PHP 5.1.2+)
$path = parse_url($url, PHP_URL_PATH); // '/path/to/page'
| 函數 | 用途 | 空格處理 | 範例 |
|---|---|---|---|
| urlencode($str) | 查詢字串值編碼 | → + | "a b" → "a+b" |
| rawurlencode($str) | 路徑/片段編碼 (RFC 3986) | → %20 | "a b" → "a%20b" |
| urldecode($str) | 解碼 urlencode | + → 空格 | |
| rawurldecode($str) | 解碼 rawurlencode | %20 → 空格 |
$params = [
'search' => 'PHP 教學',
'page' => 2,
'sort' => 'desc'
];
// 手動
$query = http_build_query($params); // 'search=PHP+%E6%95%99%E5%AD%B8&page=2&sort=desc'
// 解析回陣列
parse_str($query, $out); // $out = ['search'=>'PHP 教學', 'page'=>2, 'sort'=>'desc']
需要編譯時啟用 `--enable-ftp` (預設開啟)。
$conn = ftp_connect('ftp.example.com', 21, 30); // 主機, 埠, 逾時
if (!$conn) die('FTP 連線失敗');
$login = ftp_login($conn, 'username', 'password');
if (!$login) die('FTP 登入失敗');
// 被動模式 (穿透防火牆/NAT 必開)
ftp_pasv($conn, true);
// 目前目錄
echo ftp_pwd($conn); // /home/user
// 切換目錄
ftp_chdir($conn, 'public_html');
// 列出檔案
$files = ftp_nlist($conn, '.'); // 簡易清單
$details = ftp_rawlist($conn, '.'); // 詳細資訊 (ls -l 格式)
// 系統類型
echo ftp_systype($conn); // UNIX / Windows
// 上傳本地檔案到遠端
ftp_put($conn, 'remote/file.txt', 'local/file.txt', FTP_BINARY);
// 模式:FTP_ASCII (文字)、FTP_BINARY (二進位/圖片/壓縮檔)
// 下載遠端檔案到本地
ftp_get($conn, 'local/file.txt', 'remote/file.txt', FTP_BINARY);
// 使用檔案指標 (大檔案/串流)
$fp = fopen('local/large.zip', 'w');
ftp_fget($conn, $fp, 'remote/large.zip', FTP_BINARY);
fclose($fp);
// 上傳字串內容
$fp = fopen('php://memory', 'w');
fwrite($fp, $content);
rewind($fp);
ftp_fput($conn, 'remote/content.txt', $fp, FTP_ASCII);
fclose($fp);
// 建立目錄
ftp_mkdir($conn, 'new_folder');
// 刪除檔案/目錄
ftp_delete($conn, 'file.txt');
ftp_rmdir($conn, 'empty_folder');
// 重新命名/移動
ftp_rename($conn, 'old.txt', 'new.txt');
// 取得檔案大小
$size = ftp_size($conn, 'file.txt'); // -1 表示錯誤或目錄
// 取得修改時間 (Unix timestamp)
$time = ftp_mdtm($conn, 'file.txt'); // -1 表示不支援
// 執行原始指令 (SITE 指令)
ftp_site($conn, 'CHMOD 644 file.txt');
// 關閉連線
ftp_close($conn); // 或 ftp_quit($conn)
$ip = '8.8.8.8';
$host = gethostbyaddr($ip); // dns.google (PTR 記錄)
$ip2 = gethostbyname('google.com'); // 142.250.190.46 (A 記錄)
$ips = gethostbynamel('google.com'); // ['142.250.190.46', '142.250.190.47', ...]
// 檢查 DNS 記錄是否存在
checkdnsrr('example.com', 'MX'); // true/false (MX 記錄)
checkdnsrr('example.com', 'A'); // A 記錄
checkdnsrr('example.com', 'TXT'); // TXT 記錄 (SPF/DKIM/DMARC)
checkdnsrr('example.com', 'ANY'); // 任意記錄
// 取得 MX 記錄詳細
$mxHosts = [];
$mxWeights = [];
getmxrr('example.com', $mxHosts, $mxWeights);
// $mxHosts = ['mail.example.com'], $mxWeights = [10]
function validateEmailDomain(string $email): bool {
// 1. 基本格式
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) return false;
// 2. 提取域名
$domain = substr(strrchr($email, '@'), 1);
// 3. 檢查 MX 記錄 (必要條件)
if (!checkdnsrr($domain, 'MX')) return false;
// 4. 可選:檢查 A 記錄 (備用)
if (!checkdnsrr($domain, 'A')) return false;
// 5. 可選:排除常見一次性信箱域名
$disposable = ['mailinator.com', '10minutemail.com', 'guerrillamail.com'];
if (in_array(strtolower($domain), $disposable)) return false;
return true;
}
// 使用
if (validateEmailDomain('user@gmail.com')) {
echo "域名有效";
} else {
echo "域名無效或不可收信";
}
網路函數是 PHP 連接外部世界的橋樑。**mail() 僅適合簡單場景,生產環境請用 PHPMailer 走 SMTP**;URL 編碼區分 `urlencode` (查詢值) 與 `rawurlencode` (路徑);FTP 操作**務必開啟被動模式 `ftp_pasv(true)`** 穿透 NAT;DNS 查詢 `checkdnsrr` + `getmxrr` 是驗證 Email 域名有效性的輕量級方案。理解協議細節,才能寫出健壯的網路互動程式。