PHP에서 MySQL 데이터베이스 찾기/바꾸기 스크립트 작성
저는 현재 제 맞춤형 웹사이트를 워드프레스 기반의 CMS로 재개발하는 중입니다.
제가 작업하고 있는 웹사이트는 단순히 제 기존 URL 플러스입니다./dev/
,예.http://my.website.com/dev/
.
이 웹 사이트를 다음으로 이동합니다.http://my.website.com
주말 동안, 그리고 따라서 그것은 모든 언급을 제거할 필요가 있을 것입니다./dev/
URL.
제가 하고 싶은 것은 기본적으로 다음을 위한 "찾기 및 대체"입니다./dev
내 데이터베이스에.어떤 테이블에 이 값이 있는지 정확히 알 수 있지만, WordPress 설치에 따르면 이러한 필드의 상당 부분이 직렬화된 데이터입니다. 이는 간단합니다.dump
>open with notepad++
>find & replace
깨질 것입니다.
이를 위해 개발한 코드는 다음과 같습니다.
<?php
$look_at[] = array( "table" => "wp_options", "fields" => array( "option_value" ), "id_field" => "option_id" );
$look_at[] = array( "table" => "wp_postmeta", "fields" => array( "meta_value" ), "id_field" => "meta_id" );
$look_at[] = array( "table" => "wp_posts", "fields" => array( "post_content", "guid" ), "id_field" => "ID" );
$look_at[] = array( "table" => "wp_sfmeta", "fields" => array( "meta_value" ), "id_field" => "meta_id" );
$look_at[] = array( "table" => "wp_sfoptions", "fields" => array( "option_value" ), "id_field" => "option_id" );
$look_at[] = array( "table" => "wp_sferrorlog", "fields" => array( "error_text" ), "id_field" => "id" );
for ( $i = 0; $i < sizeof ( $look_at ); $i++ ) {
foreach( $look_at[$i]["fields"] as $field ) {
$sql = 'SELECT `' . $field . '`, `' . $look_at[$i]["id_field"] . '` FROM `' . $look_at[$i]["table"] . '`;';
$res = mysql_query( $sql );
while ( $row = mysql_fetch_assoc( $res ) ) {
$table = $look_at[$i]["table"];
$id_field = $look_at[$i]["id_field"];
$old_val = $row[$field];
$id = $row[$id_field];
$unserialized_value = @unserialize( $old_val );
if ( $old_val === 'b:0;' || $unserialized_value !== false )
$new_val = serialize( str_replace( array( "/dev/", "/dev" ), array( "/", "" ), $unserialized_value ) );
else
$new_val = str_replace( array( "/dev/", "/dev" ), array( "/", "" ), $old_val );
$update_array[] = array( "id_field" => $id_field, "id" => $id, "table" => $table, "key" => $key, "old_val" => $old_val, "new_val" => $new_val );
}
}
}
for ( $i = 0; $i < sizeof( $update_array ); $i++ ) {
if ( $update_array[$i]["old_val"] !== $update_array[$i]["new_val"] )
$updated_sql .= 'UPDATE ' . $update_array[$i]["table"] . ' SET `' . $update_array[$i]["key"] . '` = \'' . $update_array[$i]["new_val"] . '\' WHERE `' . $update_array[$i]["id_field"] . '` = \'' . $update_array[$i]["id"] . '\';';
}
mysql_query( $updated_sql );
?>
직렬화된 데이터의 예:
a:6:{s:5:"width";s:3:"400";s:6:"height";s:3:"530";s:14:"hwstring_small";s:22:"height='96' width='72'";s:4:"file";s:30:"2011/12/Amazonas-English-1.jpg";s:5:"sizes";a:13:{s:9:"thumbnail";a:3:{s:4:"file";s:30:"Amazonas-English-1-125x165.jpg";s:5:"width";s:3:"125";s:6:"height";s:3:"165";}s:6:"medium";a:3:{s:4:"file";s:30:"Amazonas-English-1-339x450.jpg";s:5:"width";s:3:"339";s:6:"height";s:3:"450";}s:5:"large";s:0:"";s:14:"post-thumbnail";a:3:{s:4:"file";s:30:"Amazonas-English-1-125x165.jpg";s:5:"width";s:3:"125";s:6:"height";s:3:"165";}s:23:"indexleft-species-thumb";a:3:{s:4:"file";s:30:"Amazonas-English-1-200x265.jpg";s:5:"width";s:3:"200";s:6:"height";s:3:"265";}s:13:"species-thumb";a:3:{s:4:"file";s:30:"Amazonas-English-1-288x381.jpg";s:5:"width";s:3:"288";s:6:"height";s:3:"381";}s:17:"indexheader-thumb";a:5:{s:4:"file";s:30:"Amazonas-English-1-400x300.jpg";s:5:"width";s:3:"400";s:6:"height";s:3:"300";s:4:"path";s:38:"2011/12/Amazonas-English-1-400x300.jpg";s:3:"url";s:88:"http://www.xxxxxxxxxxx.com/dev/wp-content/uploads/2011/12/Amazonas-English-1-400x300.jpg";}s:14:"random-thumb-1";a:3:{s:4:"file";s:28:"Amazonas-English-1-56x75.jpg";s:5:"width";s:2:"56";s:6:"height";s:2:"75";}s:14:"random-thumb-2";a:3:{s:4:"file";s:29:"Amazonas-English-1-75x100.jpg";s:5:"width";s:2:"75";s:6:"height";s:3:"100";}s:14:"random-thumb-3";a:3:{s:4:"file";s:29:"Amazonas-English-1-94x125.jpg";s:5:"width";s:2:"94";s:6:"height";s:3:"125";}s:14:"random-thumb-4";a:3:{s:4:"file";s:30:"Amazonas-English-1-113x150.jpg";s:5:"width";s:3:"113";s:6:"height";s:3:"150";}s:14:"random-thumb-5";a:3:{s:4:"file";s:30:"Amazonas-English-1-132x175.jpg";s:5:"width";s:3:"132";s:6:"height";s:3:"175";}s:13:"d4p-bbp-thumb";s:0:"";}s:10:"image_meta";a:10:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";}}
추가 편집
불행하게도, 다른 사례들이 있습니다./dev/
다음과 같은 다른 직렬화된 어레이의 경우:
'a:1:{i:0;a:5:{s:4:"type";s:5:"image";s:3:"loc";s:107:"/home/xxxxx/domains/xxxxxxxxx.com/public_html/dev/wp-content/sp-resources/forum-image-uploads/matt/2012/01/";...
아니면.
a:1:{i:0;a:5:{s:4:"data";s:88:"Your search - <b>link:http://www.xxxxxxxxx.com/dev/</b> - did not match any documents. ";...
이와 같이, 저는 단순하지 않다고 생각합니다.preg_replace
(또는 콜백)이 그 묘기를 부리겠지만, 제 생각에는 고급이 할 수 있을 것 같습니다.
제 질문은 다음과 같습니다.
- 더 간단한 방법이 있을까요?!
- 위의 코드에 문제가 발생합니까?
저는 제 코드에 문제가 있는 것을 보는 것이 끔찍합니다(잘못된 프로그래머, 죄송합니다). 그리고 이 코드로 테스트를 실행하는 것에 대해 약간 걱정합니다.
최종 편집: 작업 코드
내 SQL 덤프가 거의100mb
메모리가 무제한인 WAMP를 사용해야 했습니다.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 'On');
ini_set('memory_limit', '-1');
$handle = @fopen("amend-this.sql", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$newLine = preg_replace_callback('@s:(\d+)(:\\\"[^"]*www.seriouslyfish\.com)/dev@', create_function('$matches', 'return \'s:\'.($matches[1] - 4).$matches[2];'), $buffer);
$newLine = preg_replace_callback('@s:(\d+)(:\\\"[^\\\"]*/home/sfish/domains/seriouslyfish\.com/public_html)/dev@', create_function('$matches', 'return \'s:\'.($matches[1] - 4).$matches[2];'), $newLine);
$newLine = str_replace('http://dunc.seriouslyfish.com/dev/', 'http://www.seriouslyfish.com/', $newLine);
$newLine = str_replace('http://www.seriouslyfish.com/dev/', 'http://www.seriouslyfish.com/', $newLine);
$newLine = str_replace('/dev', '', $newLine);
file_put_contents( "amended.sql", $newLine, FILE_APPEND );
}
fclose($handle);
}
?>
이 코드는 나의 새로운 SQL 파일을 같은 디렉토리에 넣었습니다.X:\wamp\www
)을 추가로 조작할 수 있습니다.
데이터 반복과 관련하여 몇 가지 문제가 있었는데, 67건의 사례가 있었습니다./dev
어떤 이유에서인지 아직 파일에 남아 있지만, 저는 이 모든 것을 정리하기 위해 메모장++과 WinMerge를 사용했고, 결국 9천만자가 넘는 데이터베이스를 검색/교체하는 데 약 45분이 걸렸습니다.
동일한 문제가 발생했을 때 데이터베이스의 mysqdump를 실행한 다음 텍스트 편집기를 열고 값을 검색/교체한 후 SQL을 사용하여 새 데이터베이스를 만들었습니다.아주 간단하고, 놀라울 정도로 빠릅니다. 특히 일회성 작업에 적합합니다.
지적했듯이 직렬화된 데이터에 문제가 있으므로 간단한 PHP 파일로도 유사한 작업을 수행할 수 있습니다.
<?php
$handle = @fopen("/tmp/dump.sql", "r");
if ($handle) {
while (($buffer = fgets($handle, 4096)) !== false) {
$newLine = preg_replace_callback('@s:(\d+)(:\\\"[^"]*xxxxxxxxxxx\.com)/dev@', create_function('$matches', 'return \'s:\'.($matches[1] - 4).$matches[2];'), $buffer);
$newLine = preg_replace_callback('@s:(\d+)(:\\\"[^\\\"]*xxxxxxxxxxx\.com/public_html)/dev@', create_function('$matches', 'return \'s:\'.($matches[1] - 4).$matches[2];'), $newLine);
$newLine = str_replace('http://www.xxxxxxxxxxx.com/dev/', 'http://www.xxxxxxxxxxx.com/', $newLine);
echo $newLine;
}
fclose($handle);
}
?>
참고: 이것은 mysqdump에서 작동합니다. 테스트 중인 경우, 다음을 제거해야 합니다.\\\
"
의 spreg_replace_callback
s - 이것은 단지 내 sqdump 탈출 인용문입니다.
참고 사항:두 개의 사전 대체(일반 URL용 하나와 서버 경로용 하나)와 나머지 표준 URL용 하나가 있습니다.
프로그래머가 아닌 사람을 위한 직렬화 픽서 워드프레스 플러그인이 있습니다. http://davidcoveney.com/575/php-serialization-fix-for-wordpress-migrations/
PHP로도 할 수 있습니다.
또한, 여기 샘플 MySQL 코드가 있습니다. https://data.stackexchange.com/drupal%20answersmeta/query/80128/sql-search-and-replace
이것은 매우 위험한 도구이니 조심하세요.
WP CLI를 사용하면 안 될까요?
wp search-replace https://example.dev https://example.com
언급URL : https://stackoverflow.com/questions/10331843/writing-a-mysql-database-find-replace-script-in-php
'programing' 카테고리의 다른 글
비트 병합 충돌을 해결하기 위해 vimdiff를 어떻게 사용합니까? (0) | 2023.07.02 |
---|---|
SQL Server의 "WITH SCHEMABINDING"의 단점은 무엇입니까? (0) | 2023.07.02 |
SqlServer: 사용자 로그인 실패 (0) | 2023.07.02 |
Vue.js / Vuex + axios가 여러 PUT 요청을 전송함 (0) | 2023.07.02 |
0으로 한 자리 숫자 채우기 (0) | 2023.07.02 |