2013-08-15 3 views
0

그래서 나는 다음과 같은 코드를 사용하여 내 DB를 백업하고이 위대한 작동하는 것 같군MySQL DB 백업 ... 적절한 방법으로 문자열을 이스케이프합니까?

$rows = $this->_getDb()->fetchAll("SELECT * FROM $table"); 

foreach ($rows AS $row) 
{ 
    foreach ($row AS &$value) 
    { 
     if (!is_numeric($value)) 
     { 
      $value = "'".addcslashes($value, "'\\")."'"; 
      $value = str_replace("\n", '\n', $value); 
     } 
    } 

    if (!$count) 
    { 
     $output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES"; 
    } 

    $count++; 
    $output .= "\n(" .implode(', ', $row). "),"; 

    if ($count >= $limit) 
    { 
     $count = 0; 
     $output = preg_replace('#,$#', ";\n\n", $output); 
    } 
} 

$output = preg_replace('#,$#', ";\n\n", $output); 

...하지만 내가 phpMyAdmin을에서 무엇을 얻을 내 출력을 비교하고있어 좀 알았어 야 약간의 차이. 문자열을 '에 포함하면 \'으로 이스케이프 처리합니다. addcslashes을 사용하고 있기 때문에 코드가 생깁니다. 그러나 PHPMyAdmin의 결과물에서 '을 대신 하나의 작은 따옴표 ''을 한 행으로 대체합니다.

실제로 차이가 있습니까? 제가 숫자가 아닌 필드를 빠져 나가는 길을보고 더 좋은 방법이 있는지 말해주십시오.

답변

2

'' 행의 두 개의 작은 따옴표로 묶인 방법이 표준 SQL이므로 더 이식성이 뛰어납니다.

심지어 MySQL은 SQL_MODE이라고하는 NO_BACKSLASH_ESCAPES을 지원합니다.이 모드를 사용하는 서버로 백업을 가져 오려고하면 백 슬래시로 처리 된 문자열을 사용할 수 없습니다.

그러나 데이터베이스를 백업하는 방법이 다른 문제로 가득하다는 점을 분명히하기 위해 주석을 추가해야합니다.

  • 당신은 널 (null)을 처리하지 않는다 : 이것은 그들이 SQL 예약어와 충돌 할 수 있기 때문에 구분 될 필요가 열 이름을 처리하지 않습니다

    if (!is_numeric($value)) 
    
  • :

    $output .= "INSERT INTO `$table` (" .implode(', ', $columns). ") VALUES"; 
    
  • 임의의 탭에 수백만 개의 행이있는 경우 해당 테이블의 전체 내용을 일련의 INSERT 문의 형태로 단일 문자열에 저장하려고하면 PHP ' 의 최대 메모리 제한 :

    $output .= "\n(" .implode(', ', $row). "),"; 
    
  • 에만 스크립트의 일부를 보여 주지만, 그것은 또한 제대로 등 바이너리 문자열, 문자 세트, 트리거, 스토어드 루틴, 뷰, 테이블 옵션,

을 처리 할 수 ​​있습니다

당신은 정말로 바퀴를 재발 명하고 있습니다.

나는 사람들이 당신이하고있는 일을하려고 과거의 질문을 본 적이 있지만 그것을 제대로하기 어려운 :

그것은 훨씬 더 될 것입니다 PHP의 shell_exec()을 사용하여 mysqldump 또는 mydumper으로 전화하는 데 시간을 더 잘 사용하십시오.

관련 문제