Câu hỏi Viết một cơ sở dữ liệu MySQL tìm / thay thế kịch bản lệnh trong PHP


Tôi hiện đang trong quá trình xây dựng lại trang web riêng biệt của mình cho CMS dựa trên WordPress.

Trang web tôi đang làm chỉ đơn giản là URL hiện có của tôi /dev/, I E. http://my.website.com/dev/.

Tôi sẽ chuyển trang web này đến http://my.website.com cuối tuần, và như vậy sẽ cần phải xóa tất cả các tham chiếu đến /dev/ URL.

Những gì tôi muốn làm là, về cơ bản, một "tìm và thay thế" cho /dev trên cơ sở dữ liệu của tôi. Tôi có thể thấy chính xác bảng nào có giá trị này, nhưng tự nhiên theo một cài đặt WordPress, khá nhiều các trường này là dữ liệu được tuần tự hóa - một cách đơn giản dump > open with notepad++ > find & replace sẽ phá vỡ.

Mã tôi đã phát triển cho mục đích này là ở đây:

<?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 );

?>

Ví dụ về dữ liệu được tuần tự hóa:

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:"";}}

BỔ SUNG THÊM

Thật không may, có những trường hợp khác của /dev/ trong các mảng tuần tự hóa khác, chẳng hạn như ví dụ này:

'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/";...

Hoặc là,

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. ";...

Như vậy, tôi không nghĩ đơn giản preg_replace (hoặc gọi lại) sẽ làm các trick, nhưng tôi đoán một tiên tiến có thể?


Câu hỏi của tôi là:

  1. Có cách nào đơn giản hơn để làm điều này ?!
  2. Mã trên có chạy vào bất kỳ vấn đề nào không?

Tôi đang khủng khiếp tại các vấn đề tham quan với mã của tôi (lập trình xấu, tôi xin lỗi) và như vậy một chút sợ hãi về chạy thử nghiệm với mã này.


EDIT CUỐI CÙNG: MÃ LÀM VIỆC

Bởi vì kết xuất SQL của tôi đã gần 100mb, Tôi đã phải sử dụng WAMP với bộ nhớ không giới hạn.

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

Mã này đặt tệp SQL mới của tôi vào cùng một thư mục (X:\wamp\www) để tôi thao túng hơn nữa.

Tôi đã có một vài vấn đề với sự lặp lại dữ liệu và đã có 67 trường hợp /dev vẫn còn trong tập tin vì lý do nào đó nhưng tôi đã sử dụng Notepad ++ và WinMerge để sắp xếp tất cả điều này và cuối cùng tôi mất khoảng 45 phút để tìm kiếm / thay thế một cơ sở dữ liệu với hơn 90 triệu ký tự.


7
2018-04-26 10:45


gốc


Bạn đang cố gắng làm gì với việc khai báo $ look_at []? - NullPoiиteя
Chỉ định các bảng / trường cần xem xét khi thực hiện tìm / thay thế. Có một số trường trên một số bảng sẽ không bao giờ chứa bất kỳ tham chiếu nào /dev. - dunc


Các câu trả lời:


Khi tôi có cùng một vấn đề, tôi chạy một mysqldump của cơ sở dữ liệu, sau đó mở trong một trình soạn thảo văn bản và chỉ tìm kiếm / thay thế các giá trị, trước khi sử dụng SQL để tạo cơ sở dữ liệu mới. Rất đơn giản, đáng ngạc nhiên nhanh chóng, đặc biệt là cho một off.

Như đã chỉ ra, bạn có vấn đề với dữ liệu tuần tự hóa, vì vậy bạn có thể làm một điều tương tự với một tệp PHP đơn giản:

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

Chú thích: điều này hoạt động trên mysqldump, nếu bạn đang thử nghiệm, bạn sẽ cần xóa \\\ trước "s trong preg_replace_callbacks - đây chỉ là báo giá thoát của mysqldump.

Cũng lưu ý: Có hai preg thay thế (một cho URL bình thường và một cho đường dẫn máy chủ), và một đường thay thế cho các URL tiêu chuẩn còn sót lại.


6
2018-04-26 10:54



Chào Leonard. Thật không may, nếu tôi làm điều này, nó sẽ phá vỡ dữ liệu tuần tự hóa của tôi. PHP serialize số đếm hàm trên độ dài của chuỗi của nó chứa, tức là .com/dev/ là 9 ký tự, .com chỉ là 4. PHP do đó sẽ không nhận ra dữ liệu tuần tự hóa như đang được tuần tự hóa nếu định dạng / độ dài không chính xác. - dunc
Ahh - Nếu tôi nhớ chính xác tôi đã sử dụng dev.domain.tld và thay đổi thành www.domain.tld - xin lỗi về điều đó. Nếu tôi thành thật, bước tiếp theo của tôi là xem liệu tôi có thể tìm kiếm ở cấp độ cao hơn hay không, thay đổi dữ liệu tuần tự hóa để có độ dài phù hợp. - LeonardChallis
Vâng, đó là những gì tôi đang cố gắng làm với mã PHP, vì tôi không biết về bất kỳ trình soạn thảo văn bản nào có thể xử lý dữ liệu được tuần tự hóa. - dunc
Hãy đăng một ví dụ về dữ liệu được tuần tự hóa - LeonardChallis
Hầu hết các loại của bạn :) cũng được thực hiện trên nhận được nó được sắp xếp. - LeonardChallis


Có plugin wordpress fixer wordpress mà nó cho người không lập trình: http://davidcoveney.com/575/php-serialization-fix-for-wordpress-migrations/

Bạn cũng có thể làm điều đó với PHP.

Ngoài ra, đây là một mã mẫu MySQL mà nó: http://data.stackexchange.com/drupal%20answersmeta/query/80128/sql-search-and-replace

Hãy cẩn thận, vì đây là một công cụ rất nguy hiểm.


0
2018-01-06 10:52





Bạn có thể không chỉ sử dụng WP CLI cho điều này?

wp search-replace https://example.dev https://example.com

0
2017-12-29 17:47