хранение объектов php в элементе html формы и передача объектов php через метод GET? - PullRequest
4 голосов
/ 30 января 2011

Я мог бы звучать немного странно, но есть ли способ? Например, у меня есть объект PHP $foo.

Есть ли способ сохранить этот объект в форме HTML (скрытый ввод) с помощью какой-либо функции шифрования объекта, а затем получить с помощью функции дешифрования.

Аналогично, можно ли передать эти объекты методом GET?

Ответы [ 3 ]

13 голосов
/ 30 января 2011

Как уже отмечалось в другом месте, вы можете использовать сериализацию, чтобы превратить объект в строку.

$foo = (object) array(
    'foo' => 'foo & bär',
    'bar' => new StdClass
);

$serialized = serialize($foo);

Это дает:

O:8:"stdClass":2:{s:3:"foo";s:10:"foo & bär";s:3:"bar";O:8:"stdClass":0:{}}

Как видите, в этой строке есть кавычки, поэтому вы не можете вставить это в ссылку, не рискуя нарушить разметку:

<a href="http://example.com?s=O:8:" <-- quote closes href

Так что, по крайней мере, вам придется htmlspecialchars или urlencode , которые выводятся. Однако это все равно оставит контент легко читаемым. Вы можете использовать PHP-библиотеку MCrypt , чтобы установить надежное шифрование строки. Но если данные действительно настолько чувствительны , вам, вероятно, следует найти другое средство переноса, вдали от общедоступной части вашего сайта.

Если данные менее чувствительны, то вы, вероятно, можете защитить некоторые циклы ЦП, просто запутав строку. Самый простой способ сделать это - запустить gzdeflate:

echo gzdeflate(serialize($foo));

дает что-то вроде

?R*.Iq�I,.V�2��.�2�RJ��W�.�24 …

Использование gzdeflate также сократит большие сериализованные строки. Недостаток в том, что он выводит данные, непригодные для передачи через HTTP, поэтому вам также нужно base64_encode, что:

echo base64_encode(gzdeflate(serialize($foo)));

, который затем даст

87eysFIqLklxzkksLlayMrKqLrYytlJKy89Xsi62MjQAMxXUFJIOLykCiQDlkhKBLH9UfQZW1bW1AA==

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

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

unserialize(
    gzinflate(
        base64_decode(
            $obfuscatedString
        )
    )
)

и верни свой предмет. Демо


Записка о безопасности

Выше все еще небезопасно. Вы не должны полагаться на запутывание для безопасности. Если вы передаете объект или весь граф объектов через HTTP, вы должны рассматривать их как пользовательский ввод на принимающей стороне. Пользовательский ввод не может быть доверенным . Злонамеренные пользователи, выясняющие, как строка была запутана, могут предоставить измененный ввод. Поскольку вы десериализуете объекты обратно в поток программы, вы должны быть абсолютно параноиком в отношении получающегося объекта.

См. http://www.sektioneins.com/en/advisories/advisory-032009-piwik-cookie-unserialize-vulnerability/ для соответствующего примера.

3 голосов
/ 30 января 2011

Если он не содержит конфиденциальных данных, вы можете serialize() это (или даже при желании зашифровать сериализованные данные), например:

<input type="hidden" name="foo" value="<?php echo htmlspecialchars(serialize($foo), ENT_QUOTES); ?>" />

В получающем скрипте:unseralize() POST-данные для возврата объекта:

$foo = unserialize($_POST['foo']);
2 голосов
/ 30 января 2011

Вы можете использовать методы serialize и unserialize:

$serialized = serialize($foo);

Теперь вы можете хранить $serialized в скрытом поле ввода. Позже вы можете прочитать его обратно и преобразовать в объект методом unserialize. Например:

$foo = unserialize($_POST['my_hidden_field']); // back to object
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...