VBA Excel MacOs. Кодировка кириллицы при получении строки с PHP сервера
Отправляю GET запрос на сервер, в ответ получаю строку. В екселе под виндой всё работает. А в екселе под MacOs выдаёт кракозябры. Причём, только заглавные буквы ломает, маленькие получает нормально.
Код PHP на сервере:
<?php
header( "Content-Type: text/html; charset=utf-8" );
// charset=windows-1251 пробовал, utf-16, ISO разные, на эту строку вообще не реагирует
$str = "ABCdef.АБВГД.абвгд";
//перед выводом пробовал разные танцы с бубном, результаты такие:
//echo $str; // ABCdef.–Р–С–Т–У–Ф.–∞–±–≤–≥–і
//echo iconv('utf-8', 'windows-1251', $str); // ABCdef.јЅ¬√ƒ.абвгд
echo mb_convert_encoding($str, "windows-1251", "utf-8" ); // ABCdef.јЅ¬√ƒ.абвгд
?>
VBA макрос:
Option Explicit
Private Declare PtrSafe Function popen Lib "/usr/lib/libc.dylib" (ByVal command As String, ByVal mode As String) As LongPtr
Private Declare PtrSafe Function pclose Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As Long
Private Declare PtrSafe Function fread Lib "/usr/lib/libc.dylib" (ByVal outStr As String, ByVal size As LongPtr, ByVal items As LongPtr, ByVal stream As LongPtr) As Long
Private Declare PtrSafe Function feof Lib "/usr/lib/libc.dylib" (ByVal file As LongPtr) As LongPtr
#If Mac Then
'макрос для Mac
params = "test=test"
result = HTTPGet("http://f0106330.xsph.ru/test.php", params)
#Else
'макрос для Win
Set oHttp = CreateObject("MSXML2.ServerXMLHTTP")
comp = CreateObject("WScript.Network").ComputerName
sUrl = "http://f0106330.xsph.ru/test.php?test=test"
oHttp.Open "GET", sUrl, False
oHttp.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
oHttp.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHttp.Send ("")
result = oHttp.ResponseText
#End If
Function HTTPGet(sUrl As String, sQuery As String) As String
Dim sCmd As String
Dim sResult As String
Dim lExitCode As Long
sCmd = "curl --get -d """ & sQuery & """" & " " & sUrl
sResult = execShell(sCmd, lExitCode)
HTTPGet = sResult
End Function
Function execShell(command As String, Optional ByRef exitCode As Long) As String
Dim file As LongPtr
file = popen(command, "r")
If file = 0 Then
Exit Function
End If
While feof(file) = 0
Dim chunk As String
Dim read As Long
chunk = Space(50)
read = fread(chunk, 1, Len(chunk) - 1, file)
If read > 0 Then
chunk = Left$(chunk, read)
execShell = execShell & chunk
End If
Wend
exitCode = pclose(file)
End Function
А если выполнить просто curl http://f0106330.xsph.ru/test.php в терминале с минимальным кодом PHP на сервере <?php $str = "ABCdef.АБВГД.абвгд"; echo $str;?>, результат нормально возвращает.
Ответы (1 шт):
Дело в кодировке, на маке в макросах VBA в данном случае используется MacCyrillic, это однобайтная кодировка, а русский текст здесь приходит в двухбайтной UTF-8.
Например буква б, имеющая код в UTF-8 D0 B1, в MacCyrillic превращается в –± (– это D0, ± это B1).
Поэтому в скрипте перед отдачей конвертируем UTF-8 в MacCyrillic для макос, для определения можно передавать параметр
<?php
$str = "ABCdef.АБВГД.абвгд";
if ($_GET['os'] === 'macos') {
echo iconv('utf-8', 'MacCyrillic', $str);
} else {
echo $str;
}
?>
Sub DoQuery()
Dim result As String
Dim params As String
params = "os=macos"
result = HTTPGet("http://192.168.64.3/test/test.php", params)
Cells(1, 1).Value = result
MsgBox result
End Sub
Однако это решение работает только для английских и кириллических символов, например это не сработает для строки наподобие ßååååå (вернется пустая строка), универсального решения мне придумать не удалось.