Отказ от ответственности: в приведенном ниже коде используется другой, но я уверен, что он поможет другим (в моем случае это мне понадобилось, поскольку библиотека ddeboer / imap не поддерживает заголовки).
Решение Питера отлично, но мне пришлось использовать регулярное выражение fred727 , чтобы избежать получения ключей с символами новой строки.
Поскольку электронное письмо может иметь заданный заголовок несколько раз, мне пришлось использовать вариант array_combine()
, который позволяет дублировать ключи.
Вот окончательный код для разбора строки части заголовка RFC822 (получение такой части выходит за рамки):
function parse_rfc822_headers(string $header_string): array {
// Reference:
// * Base: /5430906/poluchenie-atributa-x-mailer-v-php-imap#5430917
// * Improved regex: https://stackoverflow.com/questions/5631086/getting-x-mailer-attribute-in-php-imap#comment61912182_5631445
preg_match_all(
'/([^:\s]+): (.*?(?:\r\n\s(?:.+?))*)\r\n/m',
$header_string,
$matches
);
$headers = array_combine_groupkeys($matches[1], $matches[2]);
return $headers;
}
function array_combine_groupkeys(array $keys, array $values): array {
// Reference: "welcome at el hyphen mustafa" on 2015-11-29 09:46 (http://php.net/manual/fr/function.array-combine.php#118397)
$result = [];
foreach ($keys as $i => $k) {
$result[$k][] = $values[$i];
}
array_walk(
$result,
function (&$v) {
$v = (count($v) === 1) ? array_pop($v): $v;
}
);
return $result;
}
Который прекрасно работает. Вот пример использования того же $string
(с добавленным заголовком Received
):
const RFC2822_EOL = "\r\n";
$string =
'MIME-Version: 1.0' . RFC2822_EOL .
'Received: by 10.42.228.195; Wed, 16 Feb 2011 21:18:09 -0800 (PST)' . RFC2822_EOL .
'Received: by 127.0.0.1; Wed, 16 Feb 2011 21:18:06 -0800 (PST)' . RFC2822_EOL .
'Date: Wed, 16 Feb 2011 21:18:06 -0800' . RFC2822_EOL .
'Message-ID: <AANLkTikj8NgGgkG=Of=V6VvNSt2QZ3WLNKUVZxpcs4tk@mail.gmail.com>' . RFC2822_EOL .
'Subject: Get Gmail on your mobile phone' . RFC2822_EOL .
'From: Gmail Team <mail-noreply@google.com>' . RFC2822_EOL .
'To: test case2 <email@gmail.com>' . RFC2822_EOL .
'Content-Type: multipart/alternative; boundary=20cf302234f1c34163049c73853c' . RFC2822_EOL .
'' . RFC2822_EOL;
var_dump(parse_rfc822_headers($string));
Какие выходы:
array(8) {
["MIME-Version"]=>
string(3) "1.0"
["Received"]=>
array(2) {
[0]=>
string(55) "by 10.42.228.195; Wed, 16 Feb 2011 21:18:09 -0800 (PST)"
[1]=>
string(51) "by 127.0.0.1; Wed, 16 Feb 2011 21:18:06 -0800 (PST)"
}
["Date"]=>
string(31) "Wed, 16 Feb 2011 21:18:06 -0800"
["Message-ID"]=>
string(62) "<AANLkTikj8NgGgkG=Of=V6VvNSt2QZ3WLNKUVZxpcs4tk@mail.gmail.com>"
["Subject"]=>
string(30) "Get Gmail on your mobile phone"
["From"]=>
string(36) "Gmail Team <mail-noreply@google.com>"
["To"]=>
string(28) "test case2 <email@gmail.com>"
["Content-Type"]=>
string(60) "multipart/alternative; boundary=20cf302234f1c34163049c73853c"
}