| 特性 | file_get_contents | cURL |
|---|---|---|
| 依賴設定 | 需 allow_url_fopen=On | 需 curl 擴充套件 |
| HTTP 控制 | 極少(僅 stream context) | 完整(Header、Cookie、驗證、Proxy...) |
| 錯誤處理 | 回傳 false,需檢查 $http_response_header | 豐富錯誤碼、詳細資訊 |
| 效能 | 簡單 GET 較快 | 複雜請求更穩定 |
| 支援協定 | HTTP、FTP、檔案... | HTTP/HTTPS、FTP、SMTP、LDAP 等 20+ |
file_get_contents:簡單的 GET 請求、本地檔案讀取、
allow_url_fopen開啟的環境。
cURL:POST 請求、需設定 Header/Cookie、HTTPS 驗證、Proxy、檔案上傳、超時控制、重試邏輯、生產環境標準選擇。
$content = @file_get_contents('https://api.example.com/data');
if ($content === false) {
// 錯誤處理
}
$options = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json\r\n" .
"Authorization: Bearer $token\r\n",
'content' => json_encode(['key' => 'value']),
'timeout' => 10,
'ignore_errors' => true, // 取得 4xx/5xx 回應內容
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://api.example.com/endpoint', false, $context);
// 取得 HTTP 狀態碼
if (isset($http_response_header[0])) {
preg_match('/HTTP\/\d\.\d\s+(\d+)/', $http_response_header[0], $matches);
$statusCode = (int)$matches[1];
}
function curlRequest(string $url, array $options = []): array {
$ch = curl_init();
$defaults = [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => true, // 生產環境必須驗證
CURLOPT_SSL_VERIFYHOST => 2,
CURLOPT_USERAGENT => 'MyApp/1.0 (+https://example.com)',
];
curl_setopt_array($ch, $defaults + $options);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
$info = curl_getinfo($ch);
curl_close($ch);
return [
'body' => $response,
'error' => $errno ? $error : null,
'errno' => $errno,
'http_code' => $info['http_code'],
'content_type' => $info['content_type'],
'total_time' => $info['total_time'],
];
}
// 1. 簡單 GET
$result = curlRequest('https://api.example.com/users');
// 2. POST JSON
$result = curlRequest('https://api.example.com/users', [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['name' => 'John']),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
// 3. 檔案上傳 (PHP 5.5+)
$result = curlRequest('https://api.example.com/upload', [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'file' => new CURLFile('/path/to/file.jpg', 'image/jpeg', 'photo.jpg'),
],
]);
// 4. Basic Auth
$result = curlRequest('https://api.example.com/protected', [
CURLOPT_USERPWD => 'username:password',
]);
// 5. 設定 Proxy
$result = curlRequest('https://api.example.com/data', [
CURLOPT_PROXY => 'proxy.example.com:8080',
CURLOPT_PROXYUSERPWD => 'user:pass',
]);
| 現象 | 可能原因 | 解決方案 |
|---|---|---|
| file_get_contents 回傳 false | allow_url_fopen=Off / 防火牆 / DNS | 改用 cURL / 檢查 php.ini / 測試網路 |
| cURL error 60: SSL certificate problem | 缺少 CA 憑證 / 憑證過期 | 設定 CURLOPT_CAINFO / 更新 ca-bundle.crt |
| 中文亂碼 | 編碼不一致 | 檢查 Content-Type charset / 使用 mb_convert_encoding |
| 超時 | 對方伺服器慢 / 網路問題 | 調大 CURLOPT_TIMEOUT / 非同步處理 |
生產環境強烈建議使用 Guzzle:
composer require guzzlehttp/guzzle
$client = new \GuzzleHttp\Client();
$response = $client->post('https://api.example.com/users', [
'json' => ['name' => 'John'],
'timeout' => 10,
'headers' => ['Authorization' => 'Bearer token'],
]);
$data = json_decode($response->getBody()->getContents(), true);
file_get_contents + stream context