PHP - Pack массив с двоичными данными - PullRequest
0 голосов
/ 27 мая 2019

Существует служба (php), которая отправляет изображение клиенту (php).

header('Content-Type: image/png');
readfile($image);

Что делать, если необходимо отправить не только изображение, но и некоторые данные вместе с ним.

$arrayToSend = [
    'image' => file_get_contents($image),
    'some_data' => [
        'a' => 1,
        'b' => 2
    ]
];

Как сервис может упаковать $ arrayToSend, чтобы клиент мог распаковать его?

Без преобразования изображения в base64 (из-за слишком большого размера).

Ответы [ 2 ]

1 голос
/ 27 мая 2019

@ Подход с использованием заголовков Danon, вероятно, является подходящим вариантом, если вы общаетесь по HTTP, но другие транспорты могут не поддерживать отправку дополнительных заголовков, поэтому вам нужно будет упаковать их в двоичные данные, а затем распаковать на принимающей стороне..

<?php
class Codec
{
    /**
     * Pack metadata along with binary data
     *
     * @param $meta
     * @param $data
     * @return false|string
     */
    public static function encode($meta, $data)
    {
        $meta = base64_encode($meta);

        //determine length of metadata
        $metaLength = strlen($meta);

        //The first part of the message is the metadata length
        $output = pack('VA*', $metaLength, $meta);

        //Length and metadata are set, now include the binary data
        $output .= $data;

        return $output;
    }

    /**
     * Unpack data encoded via the encode function.
     * Returns an array with "meta" and "data" elaments
     *
     * @param $content
     * @return array
     */
    public static function decode($content)
    {
        //Get the length of the metadata content
        $metaLength = unpack('V', $content)[1];

        //Slice out the metatdata, offset 4 to account for the length bytes
        $metaPacked = substr($content, 4, $metaLength);

        //Unpack and base64 decode the metadata
        $meta = unpack('A*', $metaPacked)[1];
        $meta = base64_decode($meta);

        //The binary data is everything after the metadata
        $data = substr($content, $metaLength+4);

        return [
            'meta' => $meta,
            'data' => $data
        ];
    }
}

//Load contents of a binary file
$imageFilePath = 'path_to_image.png';
$data = file_get_contents($imageFilePath);

//Arbitrary metadata - could be anything, let's use JSON
$meta = [
    'filename' => 'foo.png',
    'uid' => 12345,
    'md5' => md5_file($imageFilePath)
];

$metaJson = json_encode($meta);

//Encode the message, you can then send this to the receiver
$payload = Codec::encode($metaJson, $data);

//Receiver decodes the message
$result = Codec::decode($payload);

//Decode our JSON string
$resultMeta = json_decode($result['meta'], true);


echo 'Filename: '.$resultMeta['filename'].PHP_EOL;
echo 'UID: '.$resultMeta['uid'].PHP_EOL;

//We included an MD5 hash of the file, so we can verify here
if($resultMeta['md5'] != md5($result['data']))
{
    echo 'MD5 mismatch!';
}
1 голос
/ 27 мая 2019

Может быть, вы могли бы передать some_data-a и some_data-b в качестве заголовков? Например, как печенье.

Вы можете помочь себе с этим документом: https://developer.mozilla.org/pl/docs/Web/HTTP/Headers для получения дополнительной информации о заголовках.

...