PHP serialize () 및 unserialize () 사용 방법


125

내 문제는 매우 기본적인 것입니다.

PHP에서 정확히 무엇 serialize()을 unserialize()의미 하는지에 대한 내 요구를 충족시키는 예를 찾지 못했 습니까? 그들은 단지 예를 제공합니다-배열을 직렬화하고 설명되지 않은 형식으로 출력을 표시합니다. 그들의 전문 용어를 통하는 기본 개념을 이해하는 것은 정말 어렵습니다.

편집하다:

<?php

$a= array( '1' => 'elem 1', '2'=> 'elem 2', '3'=>' elem 3');
print_r($a);
echo ("<br></br>");
$b=serialize($a);
print_r($b);

?>

산출:

Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) 

a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}

두 번째 출력을 이해할 수 없습니다. 그 외에도 사용하기 전에 PHP 배열을 직렬화해야하는 상황의 예를 누구든지 줄 수 있습니까?


10
"보조 출력"에 대해 여전히 궁금한 경우는 매우 간단합니다. a = 배열, 3 = 크기가 {} 내에있는 세 요소입니다. 그 안에는 i = integer / index가 1이고, len 6의 문자열이 "elem 1"과 같고, 정수가 2와 같습니다. 등이 있습니다. 이렇게 읽으면 상당히 명확합니다. 여러 수준의 배열 / 객체가 쉽게 포함되는 것을 상상할 수 있지만 수정은 매우 현명하지 않습니다. 일관성을 보장하려면 수정을 직렬화 해제 한 다음 직렬화해야합니다.
— Grizly

2
@IstiaqueAhmed, "사용하기 전에 PHP 배열을 직렬화해야하는 상황의 예를 누구든지 줄 수 있습니까? " 와 관련 하여 stackoverflow.com/a/30436890/632951
— Pacerier에 다음

@grizly 감사합니다, 저는 2 년 동안 그런 답을 찾고있었습니다. 설명하는 방법도 몰랐습니다. 그 기능을 사용하는 이유를 연결하는 방법도 몰랐습니다. 답변에 감사드립니다
— isaacewing

답변:


169

PHP 배열, 객체 또는 기타 복잡한 데이터 구조 는 전송 또는 저장하거나 실행중인 PHP 스크립트 외부에서 사용할 수 없습니다 . 단일 스크립트 실행을 넘어서 이러한 복잡한 데이터 구조 를 유지 하려면 직렬화 해야합니다. 이는 데이터베이스, 텍스트 파일, 소켓과 같은 PHP 이외의 다른 것들로 처리 할 수있는 "낮은 공통 분모"에 구조를 넣는 것을 의미합니다. 표준 PHP 함수 serialize는 그러한 것을 표현 하는 형식 일 뿐이며 데이터 구조를 PHP 고유의 문자열 표현으로 직렬화하고 .NET을 사용하여 PHP 객체로 되돌릴 수 있습니다 unserialize. 하지만 JSON 또는 XML과 같은 다른 많은 형식이 있습니다.


예를 들어 다음과 같은 일반적인 문제를 생각해보십시오.

PHP 배열 을 Javascript에 어떻게 전달 합니까?

PHP와 Javascript는 문자열을 통해서만 통신 할 수 있습니다. "foo"Javascript에 매우 쉽게 문자열을 전달할 수 있습니다 . 번호를 1매우 쉽게 Javascript에 전달할 수 있습니다 . 부울 값 true을 false쉽게 Javascript에 전달할 수 있습니다 . 그러나이 배열을 Javascript에 어떻게 전달합니까?

Array ( [1] => elem 1 [2] => elem 2 [3] => elem 3 ) 

대답은 직렬화 입니다. PHP / Javascript의 경우 JSON이 실제로 더 나은 직렬화 형식입니다.

{ 1 : 'elem 1', 2 : 'elem 2', 3 : 'elem 3' }

자바 스크립트는 이것을 실제 자바 스크립트 배열로 쉽게 되돌릴 수 있습니다.

이것은 동일한 데이터 구조의 유효한 표현입니다.

a:3:{i:1;s:6:"elem 1";i:2;s:6:"elem 2";i:3;s:7:" elem 3";}

그러나 거의 PHP만이 그것을 사용하고 다른 곳에서는이 형식에 대한 지원이 거의 없습니다.
이것은 매우 일반적이며 잘 지원됩니다.

<array>
    <element key='1'>elem 1</element>
    <element key='2'>elem 2</element>
    <element key='3'>elem 3</element>
</array>

복잡한 데이터 구조 를 문자열 로 전달해야하는 상황이 많이 있습니다. 임의의 데이터 구조를 문자열로 나타내는 직렬화는이를 수행하는 방법을 해결합니다.


1
귀하의 설명은 내가 기대했던 것에 접근하는 것 같습니다. 내 편집을 봐도 될까요?
— Istiaque Ahmed 2011

1
a : 3 : {i : 1; s : 6 : "elem 1"; i : 2; s : 6 : "elem 2"; i : 3; s에서 이러한 a, i, s 등에 대한 설명은 무엇입니까? 7 : "elem 3";}? 그리고 괜찮다면 배열을 직렬화하는 예제 (이 게시물의 주제와 관련이 없을 수도 있음)를 js로 보냅니다.
— Istiaque Ahmed 2011

2
내가 아는 한 해당 형식의 공식적인 사양은 거의 찾을 수 없지만 추측 할 수 있습니다. 그렇지 않습니까? i:1= 정수 1, s:6:"elem 1"= 6 개의 문자 "elem 1"... 그리고 어떤 예를 요구하고 있습니까?
— deceze

"하지만이 배열을 Javascript에 어떻게 전달합니까? Array ([1] => elem 1 [2] => elem 2 [3] => elem 3)"... 정확한 코드 스 니펫
— Istiaque Ahmed

echo json_encode($array);어떻게 정확히 당신이 패스 는 상황에 따라 달라집니다. 그것에 너무 매달리지 마십시오.
— deceze

27

PHP serialize () unserialize () 사용법

http://freeonlinetools24.com/serialize

echo '<pre>';
// say you have an array something like this 
$multidimentional_array= array(
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 4, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 5, 7) 
       ),
    array(
        array("rose", 1.25, 15),
        array("daisy", 0.75, 25),
        array("orchid", 8, 7) 
    )
);

// serialize 
$serialized_array=serialize($multidimentional_array);
print_r($serialized_array);

다음과 같은 출력을 제공합니다.

a:3:{i:0;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:4;i:2;i:7;}}i:1;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:5;i:2;i:7;}}i:2;a:3:{i:0;a:3:{i:0;s:4:"rose";i:1;d:1.25;i:2;i:15;}i:1;a:3:{i:0;s:5:"daisy";i:1;d:0.75;i:2;i:25;}i:2;a:3:{i:0;s:6:"orchid";i:1;i:8;i:2;i:7;}}}

다시 원래 배열을 얻으려면 PHP unserialize () 함수를 사용하십시오.

$original_array=unserialize($serialized_array);
var_export($original_array);

도움이 되길 바랍니다


7

PHP 값을 저장 가능하게 만들고 싶을 때 문자열 값으로 바꿔야 합니다. 이것이 serialize () 가하는 일입니다. 그리고 unserialize () 는 그 반대입니다.


1
'저장 가능'이란 무엇을 의미합니까? 나는 당신이 언급 한 페이지를 살펴 보았다. php, mysql (필요한 경우) 예제를 보여줄 수 있습니까?
— Istiaque Ahmed 2011

2
@Istiaque Ahmed 예를 들어, 어레이를 디스크의 파일에 저장하려는 경우 어레이를 직접 저장할 수는 없지만 저장할 수있는 값으로 바꾸는 것이 문자열입니다.
— xdazz 2011

그러나 우리는 PHP mysql에서 직렬화하지 않고 변수를 데이터베이스에 직접 삽입 할 수 있습니다. 설명 부탁드립니다.
— Istiaque Ahmed 2011

9
"변수를 직렬화하지 않고 데이터베이스에 삽입 할 수 있습니다 . " . 이것은 기본 데이터 유형 (문자열, 정수, 숫자)에만 해당됩니다. 배열과 객체 를 DB 또는 파일 시스템에 직접 삽입 할 수 없습니다 . 그것이 무엇 serialize()을 unserialize()위해 만들어졌습니다.
— lorenzo-s

정보를 가져 와서 어딘가에 저장 / 전송할 준비가 된 PHP 스크립트에서 작업을 수행합니다. 예상 데이터와 정확히 일치하는 테이블을 생성 할 수있는 옵션이 있지만 일치하는 코드를 작성해야하고 데이터베이스를 변경하려면 코드를 변경해야하므로 작업 부하가 두 배로 늘어나거나 그 반대의 경우도 마찬가지입니다. 직렬화되면 두 개의 열 id int (10) 및 정보 BLOB가있는 테이블을 간단히 만들 수 있습니다. 직렬화는 삽입 할 문자열을 제공하고 직렬화 해제는 데이터를 원래 상태로 되돌립니다. 그렇지 않은 경우가 있으며 PHP 문서가이를 다룹니다.
— Chris

7
<?php
$a= array("1","2","3");
print_r($a);
$b=serialize($a);
echo $b;
$c=unserialize($b);
print_r($c);

이 프로그램을 실행하면 출력이 에코됩니다.

a:3:{i:0;s:1:"1";i:1;s:1:"2";i:2;s:1:"3";}


여기서
a = 배열의 크기
i = 배열 ​​수
의 개수 s = 배열 ​​값의 크기

직렬화를 사용하여 데이터베이스에 데이터 배열을 저장
하고 사용할 데이터를 검색하고 직렬화 해제 할 수 있습니다.


6

대부분의 저장 매체는 문자열 유형을 저장할 수 있습니다. 그들은 배열이나 객체와 같은 PHP 데이터 구조를 직접 저장할 수 없으며, 데이터 저장 매체를 PHP와 결합하기 때문에 그렇게해서는 안됩니다.

대신 serialize()이러한 구조체 중 하나를 문자열로 저장할 수 있습니다. 를 사용하여 문자열 표현에서 역 직렬화 할 수 있습니다 unserialize().

json_encode()및 json_decode()(및 일반적으로 JSON)에 익숙하다면 개념은 비슷합니다.


json에 익숙합니다. PHP는 여전히 모호합니다. 내 게시물을 편집
— Istiaque Ahmed dec.

json_encode가 있으면 직렬화가 필요한 이유는 무엇입니까? 알고 있다면 설명해주세요. 감사.
— Yevgeniy Afanasyev

1
@YevgeniyAfanasyev 아마도 당신은 일부 데이터 하위 집합을 원하지 않을 것입니다. 하지만 serialize()JSON보다 앞선 것 같습니다 .
— alex

5

부디! 부디! 부디! 데이터를 직렬화하지 말고 데이터베이스에 배치하십시오. 직렬화는 그런 방식으로 사용할 수 있지만 관계형 데이터베이스의 요점과 데이터베이스 엔진에 내재 된 데이터 유형이 없습니다. 이렇게하면 데이터베이스의 데이터를 이식 할 수없고 읽기 어렵고 쿼리가 복잡해질 수 있습니다. 애플리케이션이 다른 언어로 이식되기를 원하는 경우, 예를 들어 Java를 사용하는 것이 합당한 앱의 일부에 Java를 사용하려는 경우 직렬화는 엉덩이에 고통이 될 것입니다. 삽입 할 데이터를 조작하기 위해 타사 중개 도구를 사용하지 않고도 데이터베이스의 데이터를 항상 쿼리하고 수정할 수 있어야합니다.

코드, 이식성 문제가있는 코드, 다른 RDMS 시스템, 새 스키마 등으로 마이그레이션하기 더 어려운 데이터를 유지 관리하기가 정말 어렵습니다. 또한 다음 중 하나를 기반으로 데이터베이스를 검색하는 것이 지저분 해지는 단점이 있습니다. 직렬화 한 필드.

그것은 serialize ()가 쓸모 없다는 말은 아닙니다. 예를 들어 데이터 집약적 인 작업의 결과를 포함하는 캐시 파일을 사용하기에 좋은 곳이 될 수 있습니다. 다른 사람이 엄청나게 많습니다. 다음 사람이 유지 보수 또는 마이그레이션 악몽을 겪을 것이기 때문에 직렬화를 남용하지 마십시오.

serialize () 및 unserialize ()의 좋은 예는 다음과 같습니다.

$posts = base64_encode(serialize($_POST));
header("Location: $_SERVER[REQUEST_URI]?x=$posts");

페이지에서 직렬화 해제

if($_GET['x']) {
   // unpack serialize and encoded URL
   $_POST = unserialize(base64_decode($_GET['x']));
}

2
제공된 코드에는 몇 가지 보안 취약점이 포함되어 있으며, 코드를 복사하여 붙여 넣는 사람에게 경고해야합니다.
— Daniel W.

주어진 코드는 searilize 및 unserialize 함수를 사용하는 방법의 예일뿐입니다.
— Avnish alok

2

에서 http://php.net/manual/en/function.serialize.php :

값의 저장 가능한 표현을 생성합니다. 이것은 유형과 구조를 잃지 않고 PHP 값을 저장하거나 전달하는 데 유용합니다.

기본적으로 PHP 배열 또는 객체를 가져 와서 문자열로 변환합니다 (그런 다음 적합하다고 생각되는대로 전송하거나 저장할 수 있음).

직렬화 해제는 문자열을 다시 개체로 변환하는 데 사용됩니다.


'저장 가능한 표현'에 대한 설명은 무엇입니까?
— Istiaque Ahmed 2011

누군가가 PHP 배열을 가져 와서 데이터베이스에 저장하려고 할 때만 직렬화가 사용되는 것을 보았습니다. 직렬화하고, 데이터베이스의 표준 문자열 필드에 출력을 저장 한 다음 다시 사용하고 싶을 때 가져 와서 직렬화 해제 할 수 있습니다.
— MrGlass

1

기본적으로 배열이나 객체를 직렬화 할 때 php 스크립트 외부에 쉽게 저장할 수 있도록 유효한 문자열 형식으로 변환하면됩니다.

  1. serialize를 사용하여 데이터베이스에 개체의 상태를 저장합니다 (예로 User 클래스를 사용합니다). 다음으로 데이터를 직렬화 해제하여 이전 상태를 다시 개체에로드합니다 (메서드는 serializer가 아니므로 사용할 수 있도록 개체 클래스를 포함해야합니다. 그것)
    • 사용자 개인화

객체에 대해서는 매직 __sleep 및 __wakeup 메서드를 사용해야합니다. __sleep은 serialize ()에 의해 호출됩니다. sleep 메소드는 지속하려는 객체의 값 배열을 반환합니다.

__wakeup은 unserialize ()에 의해 호출됩니다. wakeup 메서드는 직렬화되지 않은 값을 가져 와서 객체에서 초기화해야합니다.

php와 js간에 데이터를 전달하려면 json_encode를 사용하여 PHP 배열을 유효한 json 형식으로 전환합니다. 또는 다른 방법으로-JSON.parese ()를 사용하여 출력 데이터 (문자열)를 유효한 json 객체로 변환합니다. 로컬 저장소를 사용하기 위해 그렇게 할 수 있습니다. (오프라인 데이터 액세스)


json_encode가 있으면 직렬화가 필요한 이유는 무엇입니까? 알고 있다면 설명해주세요. 감사.
— Yevgeniy Afanasyev

1
직렬화 및 직렬화 해제를 사용할 때 수집되는 매직 메서드를 사용자 지정할 수 있다는 이점이 있습니다. 즉, Json_encode () 및 json_decode ()를 훨씬 더 많이 사용할 수 있으며 각 객체는 고유 한 방식으로이 기능을 처리 할 수 ​​있습니다. 이것이 당신이 그들을 사용하고 싶은 이유입니다.
— DevWL

1
더 많은 것이 있습니다. 자세한 정보는이 답변을 참조하십시오. stackoverflow.com/questions/804045/…
— DevWL

1
json_encode는 더 빠릅니다 (사용하는 PHP 버전에 따라 다름), json은 stdClass로 디코딩하고, serilized 객체는 실제 클래스 인스턴스로 직렬화 해제됩니다. 일부 구성은 UTF-8 인코딩을 변경하지 않고 유지하기 위해 JSON으로 만들어야하며 직렬화는 인코딩을 변경하지 않습니다. 데이터 크로스 플랫폼이 JSON을 사용하도록하려면 PHP에서만 작업하는 경우 __sleep 및 __wakeup 매직 메서드를 사용하여 직렬화를 사용자 지정할 수 있습니다.
— DevWL

0

예, 저는 할수 있습니다. 시스템을 추적해야한다고 가정하면 시스템에 두 명 이상의 관리자와 하위 관리자가 있다는 것을 의미하며 이들 모두가 정보를 삽입하거나 업데이트하거나 편집 할 수 있습니다. 이 문제를 해결하려면 직렬화가 필요합니다.

  **Explain:**Create a table named history which stores all changes. Each time there is a change insert a new row in this table. It might have this fields:

  history(id,target_table(name of the table), target_id (ID of the saved entry),create/edit/change data (serialized data of the saved row),date)

도움이 되길 바랍니다.


-1
preg_match_all('/\".*?\"/i', $string, $matches);
foreach ($matches[0] as $i => $match) $matches[$i] = trim($match, '"');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.