7

現在、特注のウェブサイトを WordPress 主導の CMS に再開発中です。

私が取り組んできたウェブサイトは、既存の URL に を加えたもの/dev/ですhttp://my.website.com/dev/

http://my.website.com週末にこの Web サイトを に移動するので、 /dev/URL へのすべての参照を削除する必要があります。

私がやりたいことは、基本的に/dev、データベースでの「検索と置換」です。dumpどのテーブルにこの値が含まれているかを正確に確認できますが、当然のことながら、 open with notepad++WordPressのインストールによると、これらのフィールドのかなりの部分がシリアル化されたデータ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が、高度なものではうまくいくと思いますか?


私の質問は次のとおりです。

  1. これを行う簡単な方法はありますか?!
  2. 上記のコードで問題が発生しますか?

私は自分のコードの問題を予見するのが苦手で (下手なプログラマーです。申し訳ありません)、このコードでテストを実行することに少し不安があります。


最終編集: 作業コード

私の 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);
    }
?>

このコードは、X:\wamp\wwwさらに操作できるように、新しい SQL ファイルを同じディレクトリ ( ) に配置します。

データの繰り返しにいくつかの問題があり/dev、何らかの理由でまだファイルに67個のインスタンスがありましたが、 Notepad ++WinMergeを使用してこれらすべてを整理し、最終的に検索/置換するのに約45分かかりました9,000 万文字以上のデータベース。

4

3 に答える 3

6

同じ問題が発生したとき、データベースの mysqldump を実行し、テキスト エディターで開き、値を検索/置換してから、SQL を使用して新しいデータベースを作成しました。特に1回限りの場合、非常にシンプルで驚くほど高速です。

指摘したように、シリアル化されたデータに問題があるため、単純な 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);
}
?>

注:これは mysqldump で機能します。テストしている場合は、 s の s の\\\前にある を削除する必要があります。これは、mysqldump が引用符をエスケープしているだけです。"preg_replace_callback

また、注意: 2 つの preg 置換 (1 つは通常の URL 用、もう 1 つはサーバー パス用) と、残りの標準 URL 用の 1 つの str 置換があります。

于 2012-04-26T10:54:07.753 に答える
0

非プログラマー向けのシリアライゼーション修正プログラム wordpress プラグインがあります: http://davidcoveney.com/575/php-serialization-fix-for-wordpress-migrations/

PHPで行うこともできます。

また、これを行うサンプル MySQL コードは次のとおりです

非常に危険なツールですので注意してください。

于 2014-01-06T10:52:58.157 に答える
0

これには WP CLI を使用できませんか?

wp search-replace https://example.dev https://example.com
于 2016-12-29T17:47:40.387 に答える