PHP调用大学成绩接口后阿拉伯字符显示为问号的求助
解决PHP获取阿拉伯字符显示为问号的问题
问题背景
我需要搭建页面从大学服务器获取考试成绩:
- 最初的表单直接提交到大学服务器(
https://exam.albaath-univ.edu.sy/exam-med/re.php),能正常显示包含阿拉伯姓名的成绩。 - 改成用PHP cURL转发请求后,返回的阿拉伯姓名全部显示为问号,尝试过UTF-8与Windows-1256的编码转换,均无效。
原表单HTML代码:
<form action="https://exam.albaath-univ.edu.sy/exam-med/re.php" method="post" accept-charset="UTF-8"> <p style="text-align: center;"> <input name="number1" type="hidden" value="" /> <input name="nospy" type="hidden" value="" /> </p> <table> <tbody> <tr> <td>choose field</td> <td> <select name="nospy"> <option value="1">Med</option> </select> </td> </tr> <tr> <td>enter your number</td> <td style="text-align: right;"><input name="number1" size="20" type="text" /></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="show result" /></td> </tr> </tbody> </table> </form>
原PHP转发代码(存在编码问题):
<?php if ($_SERVER['REQUEST_METHOD'] == 'POST') { $nospy = $_POST['nospy']; $number1 = $_POST['number1']; // send the information to another PHP page using cURL $url = 'https://example.com/other_page.php'; $post_data = array( 'nospy' => $nospy, 'number1' => $number1 ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); // process the response from the other PHP page // convert it to the Windows-1256 encoding $response = iconv("UTF-8", "Windows-1256", $response); // display the converted response in HTML echo $response; } ?>
解决方案
1. 确认服务器返回的实际编码
不要凭经验假设编码,先通过cURL获取响应头里的字符集信息:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://exam.albaath-univ.edu.sy/exam-med/re.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); // 包含响应头 $response = curl_exec($ch); curl_close($ch); // 分离响应头和内容 list($header, $content) = explode("\r\n\r\n", $response, 2); // 提取字符集 preg_match('/Content-Type:.*charset=([^\s;]+)/i', $header, $matches); $source_charset = isset($matches[1]) ? $matches[1] : 'Windows-1256';
2. 强制设置页面输出编码
在PHP代码最开头设置输出的Content-Type头(必须在任何输出之前):
// 推荐用UTF-8作为页面编码 header('Content-Type: text/html; charset=UTF-8');
3. 修正编码转换逻辑
根据服务器返回的编码,将内容转换为页面输出编码:
- 如果服务器返回Windows-1256,转成UTF-8:
// 优先使用mb_convert_encoding(需确保PHP开启mbstring扩展) if (function_exists('mb_convert_encoding')) { $content = mb_convert_encoding($content, 'UTF-8', $source_charset); } else { $content = iconv($source_charset, 'UTF-8//IGNORE', $content); }
- 如果服务器返回UTF-8,直接输出即可,无需转换。
4. 优化cURL请求头
添加Accept-Charset头,引导服务器返回指定编码:
curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Accept-Charset: UTF-8, Windows-1256' ));
5. 修正后的完整PHP代码
<?php // 设置页面输出编码为UTF-8,必须在任何输出之前调用 header('Content-Type: text/html; charset=UTF-8'); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $nospy = $_POST['nospy']; $number1 = $_POST['number1']; // 直接请求大学服务器,而非中转页面 $url = 'https://exam.albaath-univ.edu.sy/exam-med/re.php'; $post_data = array( 'nospy' => $nospy, 'number1' => $number1 ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); // 添加Accept-Charset请求头 curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Accept-Charset: UTF-8, Windows-1256' )); $response = curl_exec($ch); curl_close($ch); // 分离响应头与内容 list($header, $content) = explode("\r\n\r\n", $response, 2); // 获取服务器返回的字符集 preg_match('/Content-Type:.*charset=([^\s;]+)/i', $header, $matches); $source_charset = isset($matches[1]) ? $matches[1] : 'Windows-1256'; // 转换编码为UTF-8 if (strtolower($source_charset) !== 'utf-8') { if (function_exists('mb_convert_encoding')) { $content = mb_convert_encoding($content, 'UTF-8', $source_charset); } else { $content = iconv($source_charset, 'UTF-8//IGNORE', $content); } } // 输出处理后的内容 echo $content; } ?>
内容的提问来源于stack exchange,提问作者Mohammed Othman
相关产品推荐
相关产品推荐

