
PHP 使用 cURL 发送 GET 请求时出现中文显示为问号,本质是服务器响应使用了 windows-1251 编码而客户端未正确转码;需在获取响应后显式将其转换为 UTF-8。
php 使用 curl 发送 get 请求时出现中文显示为问号,本质是服务器响应使用了 `windows-1251` 编码而客户端未正确转码;需在获取响应后显式将其转换为 utf-8。
当你通过 PHP 的 curl_exec() 获取网页内容(如 https://theatrevazrajdane.bg/...)时,页面实际以 Content-Type: text/html; charset=windows-1251 返回,但 PHP 默认按字节流处理响应,未自动解码。浏览器或 Insomnia 能正常显示,是因为它们内置了对 windows-1251 的识别与渲染能力;而原生 cURL 不会自动转码,直接输出会导致 UTF-8 环境下出现 `` 类乱码。
✅ 正确解决方案:响应后转码
在 curl_exec() 获取 $response 后,必须显式将其从 windows-1251 转换为 UTF-8。推荐使用以下任一方式(二者均可靠,建议优先 mb_convert_encoding,因兼容性更广且可处理部分非法字节):
// 方式 1:使用 mb_convert_encoding(推荐)
$convertedResponse = mb_convert_encoding($response, 'UTF-8', 'Windows-1251');
// 方式 2:使用 iconv(需确保系统支持 windows-1251)
$convertedResponse = @iconv('Windows-1251', 'UTF-8//IGNORE', $response);
⚠️ 注意:
iconv在某些 Linux 环境中可能不默认支持Windows-1251,此时会报错或返回false;mb_convert_encoding更健壮,且//IGNORE或//TRANSLIT修饰符可增强容错性(上例中@抑制警告,生产环境建议配合mb_internal_encoding('UTF-8')和错误检查)。
Test Curl 2下载父母的功课——育儿心理学对话支持技能(心虫增强版)。提供结构化对话、情绪识别、场景匹配与安全检测;可选Python脚本(scripts/)在SKILL_DIR/data/本地存储评估历史、洞察与会话状态,不对外传输。核心路径:觉察(看见防御)→接纳(慈悲是……
? 完整修复代码示例
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://theatrevazrajdane.bg/%D1%82%D0%B2%D0%BE%D1%80%D1%87%D0%B5%D1%81%D0%BA%D0%B8-%D1%81%D1%8A%D1%81%D1%82%D0%B0%D0%B2/%D0%B0%D0%BA%D1%82%D1%8C%D0%BE%D1%80%D0%B8/2",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
// 移除 CURLOPT_POSTFIELDS(GET 请求不应设 body)
CURLOPT_HTTPHEADER => [
"Accept: application/json",
// 注意:此处 Content-Type 是你发给服务器的声明,不影响响应编码解析
// 响应编码由服务端 Content-Type header 决定,无需在此指定
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
die("cURL Error #: " . $err);
}
// ✅ 关键步骤:检测并转换响应编码
// 先尝试从 HTTP 响应头中提取 charset(更通用的做法)
$contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);
preg_match('/charset=([^;\s]+)/i', $contentType, $matches);
$detectedCharset = !empty($matches[1]) ? trim($matches[1]) : 'windows-1251';
// 执行转换(兼容 fallback)
if (function_exists('mb_convert_encoding')) {
$utf8Response = mb_convert_encoding($response, 'UTF-8', $detectedCharset);
} else {
$utf8Response = @iconv($detectedCharset, 'UTF-8//IGNORE', $response);
}
// 输出前确保脚本自身以 UTF-8 响应(如用于 Web)
header('Content-Type: text/html; charset=UTF-8');
echo $utf8Response;
? 补充说明与最佳实践
-
不要依赖
CURLOPT_ENCODING:该选项仅控制是否接受 gzip/deflate 压缩,与字符编码无关; -
Content-Type请求头中的charset=UTF-8无意义:这是告诉服务器“我发送的内容是 UTF-8”,但当前是 GET 请求,无请求体,因此该字段可安全移除; -
动态检测编码更稳健:使用
curl_getinfo($curl, CURLINFO_CONTENT_TYPE)解析响应头中的真实charset,避免硬编码windows-1251; -
HTML 页面内
<meta charset>不能替代 HTTP 头:浏览器会优先采用 HTTPContent-Type中的 charset,PHP cURL 同理,需以响应头为准。
通过以上调整,你将获得正确解码的 UTF-8 内容,例如 <title>Актьори | Театър Възраждане</title>,彻底解决问号乱码问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











