Я пытаюсь получить двоичный контент MTOM, используя расширенный класс SoapClient, ответ примерно такой:
--uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2
Content-ID:
<http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<big-xml-here>
<xop:Include href="cid:http://tempuri.org/1/636644204289948690" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</big-xml-here>
--uuid:8c73f23e-47d9-49fb-a61c-c1df7b19a306+id=2--
Сразу после XML ответ MTOM продолжается с двоичными файлами, связанными с URL «cid»:
Content-ID: <http://tempuri.org/1/636644204289948690>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
%PDF-1.4
%���� (lots of binary content here)
--uuid:7329cfb8-46a4-40a8-b15b-39b7b0988b57+id=4--
Чтобы извлечь все, что я пробовал этот код:
$xop_elements = null;
preg_match_all('/<xop[\s\S]*?\/>/', $response, $xop_elements);
$xop_elements = reset($xop_elements);
if (is_array($xop_elements) && count($xop_elements)) {
foreach ($xop_elements as $xop_element) {
$cid = null;
preg_match('/cid:(.*?)"/', $xop_element, $cid);
if(isset($cid[1])){
$cid = $cid[1];
$binary = null;
preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/", $response, $binary);
var_dump($binary);
exit();
}
}
}
Хотя preg_match_all
и первый preg_match
работаем, последний:
/Content-ID:.*?$cid.*?(.*?)uuid/
не работает
По первоисточнику: https://github.com/debuss/MTOMSoapClient/blob/master/MTOMSoapClient.php
регулярное выражение
/Content-ID:[\s\S].+?'.$cid.'[\s\S].+?>([\s\S]*?)--uuid/
но я получил ошибку на PHP 7:
preg_match (): неизвестный модификатор ‘/’
Есть ли возможность получить двоичный файл MTOM для каждого CID?
Заранее спасибо!
Вы должны сначала расстаться $cid
как это вызывает вашу первую ошибку
$cid = preg_quote($cid[1], '/');
Далее вам нужно использовать s
флаг модификатора так, чтобы .
также соответствует новым строкам
preg_match("/Content-ID:.*?$cid.*?(.*?)uuid/s", $response, $binary);
s (PCRE_DOTALL)
Если этот модификатор установлен, метасимвол точки в шаблоне соответствует всем символам, включая символы новой строки. Без этого новые строки исключаются. Этот модификатор эквивалентен модификатору Perl’s / s. Отрицательный класс, такой как [^ a], всегда соответствует символу новой строки, независимо от установки этого модификатора.
Как я понимаю, вы пытаетесь настроить исходный код в соответствии с измененной версией файла SOAP.
Вместо числа, вы хотите захватить весь http://tempuri.org/1/636644204289948690
в $cid
переменная (вы можете переименовать переменную). Для этого вы можете использовать следующее регулярное выражение, которое соответствует всему, кроме двойной кавычки в группе захвата 1: cid:([^"]+)
preg_match('/cid:([^"]+)/', $xop_element, $cid);
Все идет нормально. Исходя из вашего описания, вы должны использовать следующий шаблон для захвата двоичной части:
'%Content-ID: <'.$cid.'>([\s\S]*?)--uuid%'
Мы используем модифицированную точку [\ s \ S] для сопоставления между несколькими строками (как показано также в исходной реализации). В противном случае добавьте s
| однострочный флаг или (?s)
встроенный модификатор. Кроме того, я использую альтернативные разделители регулярных выражений%, чтобы избежать проблем. Это все еще звук, чтобы использовать preg_quote($cid[1], '%')
как предложено Таруном.
Теперь вы можете извлечь рассматриваемый блок из группы захвата 1:
trim($binary[1]);