3 changed files with 128 additions and 1 deletions
@ -0,0 +1,90 @@ |
|||
<?php |
|||
|
|||
namespace App\Services\Device; |
|||
|
|||
class CommonService |
|||
{ |
|||
|
|||
public static function parseMultipart($raw): array |
|||
{ |
|||
// 1. 提取边界 |
|||
if (!preg_match('/^--([^\s]+)/', $raw, $matches)) { |
|||
// 若不是 multipart,尝试当作纯 XML |
|||
$xml = simplexml_load_string(trim($raw)); |
|||
return [ |
|||
'xml' => $xml ? json_decode(json_encode($xml), true) : null, |
|||
'images' => [] |
|||
]; |
|||
} |
|||
$boundary = $matches[1]; |
|||
|
|||
// 2. 按边界分割(保留空块) |
|||
$blocks = explode("--$boundary", $raw); |
|||
$result = ['xml' => null, 'images' => []]; |
|||
|
|||
foreach ($blocks as $block) { |
|||
$block = trim($block); |
|||
if ($block === '' || $block === '--') { |
|||
continue; // 跳过空块和结束标记 |
|||
} |
|||
|
|||
// 3. 分离头部和内容(分隔符:\r\n\r\n 或 \n\n) |
|||
$sepPos = strpos($block, "\r\n\r\n"); |
|||
if ($sepPos === false) { |
|||
$sepPos = strpos($block, "\n\n"); |
|||
} |
|||
if ($sepPos === false) { |
|||
continue; // 未找到分隔,跳过 |
|||
} |
|||
|
|||
$headers = substr($block, 0, $sepPos); |
|||
$body = substr( |
|||
$block, |
|||
$sepPos + 4 |
|||
); // 跳过 \r\n\r\n,如果是 \n\n 这里会多一个字符,但后续 trim 会处理 |
|||
|
|||
// 4. 根据头部判断类型 |
|||
$isXml = strpos($headers, 'filename="mnpr.xml"') !== false |
|||
|| strpos($headers, 'text/xml') !== false; |
|||
|
|||
$isImage = strpos($headers, 'image/') !== false |
|||
|| preg_match( |
|||
'/\.(jpg|jpeg|png|gif|bmp|webp)/i', |
|||
$headers |
|||
); |
|||
|
|||
if ($isXml) { |
|||
// 清理可能残留的尾部边界标记 |
|||
$xmlString = trim($body); |
|||
// 移除尾部可能出现的 -- 或空白 |
|||
$xmlString = preg_replace('/\s*--\s*$/', '', $xmlString); |
|||
|
|||
// 尝试解析 XML |
|||
libxml_use_internal_errors(true); |
|||
$xmlObj = simplexml_load_string($xmlString); |
|||
if ($xmlObj !== false) { |
|||
$result['xml'] = json_decode(json_encode($xmlObj), true); |
|||
} else { |
|||
// 如果解析失败,将原始字符串保留(可记录错误) |
|||
$result['xml'] = $xmlString; // 或 null |
|||
} |
|||
} |
|||
|
|||
if ($isImage) { |
|||
// 提取文件名(可选) |
|||
preg_match('/filename="([^"]+)"/', $headers, $fname); |
|||
$filename = $fname[1] ?? 'image.jpg'; |
|||
|
|||
// 清除可能残留的尾部边界标记(二进制数据不要 trim!) |
|||
$imageData = preg_replace('/\s*--\s*$/', '', $body); |
|||
|
|||
$result['images'][] = [ |
|||
'filename' => $filename, |
|||
'data' => $imageData // 原始二进制 |
|||
]; |
|||
} |
|||
} |
|||
|
|||
return $result; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue