2012-05-31 3 views
5

"mysql"에 "serialize ($ array);"로 데이터를 저장하고 있습니다. 이 데이터는 입력 필드가있는 양식에서 가져온 것입니다. 나는 "a : 4 : {i : 1; s : 7 :"fdsfdsf "; i"와 같은 것을 폼 필드에 삽입하면 어떻게되는지 알고 싶습니다. DB에 저장된 내 데이터를 깨뜨릴 수 있습니까? 감사합니다.PHP MySQL에서 데이터 직렬화

답변

9

이 할 수 있고, 직렬화 한 후, 다음과 같은 값이 반환됩니다

string(42) "a:1:{i:0;s:24:"a:4:{i:1;s:7:"fdsfdsf";i";}" 

이 데이터베이스에 추가 될 것입니다. 그러나 사용자 입력을 데이터베이스에 저장하는 것은 매우 바람직하지 않습니다. 먼저 중요한 사용자를 이스케이프 처리하기 위해 일반 사용자 입력을 mysql_real_escape_string()으로 포맷해야합니다.

데이터베이스에서 serialize 된 텍스트를 unserialize()으로 호출하면 배열이 제대로 반환됩니다. 안전해야하지만 예상치 못한 결과가 발생할 수 있습니다.

은 데이터베이스에 직렬화 된 배열을 저장하는 데 매우주의해야합니다. 직렬화는 문자열을 리턴하므로 데이터를 저장하는 필드는 대개 VARCHAR 또는 TEXT입니다. 단순히 을 새로 작성한 저장된 배열을 덮어 쓰면 이전 데이터는 완전히 손실됩니다. 데이터베이스를 업데이트하려면 먼저 데이터베이스의 데이터를 배열로 읽어서 업데이트 한 다음 업데이트 한 다음 데이터베이스에 다시 써야합니다.

금지되어 있지는 않지만 데이터베이스에 직렬화 된 자료를 사용하고 저장하면 대개 많은 문제가 발생합니다. 데이터베이스는 기본적으로 많은 데이터 유형을 가지고 있으며 큰 직렬화 배열은 오버 헤드를 발생시키고 실행을 복잡하게 만듭니다. 나중에 시스템을 수정해야하는 경우 간단히 통증이 생깁니다. 또한 직렬화 된 필드에 관계 쿼리를 사용할 수 없습니다.

+0

귀하의 답변과 권고에 감사 드리며 매우 도움이되었습니다 !!! – alejoabella

+2

php 직렬화 된 데이터가 이진 데이터를 반환하므로 VARCHAR 또는 TEXT가 아니라 VARBINARY 또는 BLOB를 사용하십시오. –

6

오래된 방법

여전히 mysql_을 사용하고이 같은 쿼리를 작성할 수

$sql = sprintf("INSERT INTO mytable (a) VALUES ('%s')", 
    mysql_real_escape_string(serialize($myvar)) 
); 
mysql_query($sql) or die("oh no!"); 

권장되는 방법

PDO를 들어

mysqli 당신이 얻을 옵션을 사용하여 준비된 문을 사용하십시오. 이는 SQ를 방지하기위한 목적으로 적극 권장됩니다 L 주입 공격 벡터. PDO의 예 :

$stmt = $db->prepare('INSERT INTO mytable (a) VALUES (:myvar)'); 
$stmt->execute(array(
    ':myvar' => serialize($myvar), 
)); 

필드 또한

, 테이블 필드의 열 크기를 초과하지 않는 직렬화 된 데이터의 길이 확인 길이; 절단 된 직렬화 된 변수는 거의 쓸모가 없습니다.

+1

@alejoabella 오신 것을 환영합니다. 이 대답으로 돌아와서, 나는 그것이 결국 좋지 않다는 것을 깨달았습니다. 그래서 저는 그것을 수정했습니다. :) –

+0

음 .... 준비된 진술이 정확히 어떻게 주사를 예방합니까? 정확하게 - 그들은하지 않습니다. 조금도. – specializt

+1

@specializt 준비된 진술은 그 점에서 마술 적이 지 않습니다. 사람들은 여전히 ​​최근의 [Drupal advisory] (https://www.drupal.org/SA-CORE-2014- 005). 그러나 내 대답의 진술이 악용 될 수 있다고 생각되면 어떻게 달성 할 수 있는지 알려주십시오. –