Skip to content

Instantly share code, notes, and snippets.

@JayWood
Last active March 25, 2017 20:05
Show Gist options
  • Save JayWood/a72f5e615852dcb65948a8f92c484bfc to your computer and use it in GitHub Desktop.
Save JayWood/a72f5e615852dcb65948a8f92c484bfc to your computer and use it in GitHub Desktop.
This script was inspired by the script from Blogestudio located at https://github.com/Blogestudio/Fix-Serialization. For yearsI used this script to fix serialization, however, just recently I needed to fix a 1GB+ file and the methods in use on the original script was not ideal for reading a large file.Therefore this script was built.
<?php
/**
* Jays Fix Serialization
*
* Fixes serialization in SQL files after replacements are done.
* License: GPL version 3 or later - http://www.gnu.org/licenses/gpl.txt
* By: Jay Wood ( [email protected] )
* http://plugish.com
*
* Usage:
* /usr/bin/php/jw-fix-serialized.php my-sql-file.php
*
* When complete, you should have a my-sql-file-fixed.php in the same directory as your script.
*
* Versions:
* 1.0 2016-10-24 Initial Release
*
* Known Issues:
* None at this time!
*
* Features:
* Streams large files, 1GB+
* Absolute path s allowed for files
* Outputs to a *-fixed.ext file, so the original is not overwritten
*
* Description:
*
* This script was inspired by the script from Blogestudio located at https://github.com/Blogestudio/Fix-Serialization. For years
* I used this script to fix serialization, however, just recently I needed to fix a 1GB+ file and the methods in use on the
* original script was not ideal for reading a large file.
*
* Therefore this script was built ( keeping a couple of his functions, and the preg_replace ) with file-streaming in mind, instead
* of trying to open the entire file for replacing. This saves the "Allowed memory size exhausted" errors.
*
*/
// Unescape to avoid dump-text issues
function unescape_mysql( $value ) {
return str_replace( array( "\\\\", "\\0", "\\n", "\\r", "\Z", "\'", '\"' ),
array( "\\", "\0", "\n", "\r", "\x1a", "'", '"' ),
$value );
}
// Fix strange behaviour if you have escaped quotes in your replacement
function unescape_quotes( $value ) {
return str_replace( '\"', '"', $value );
}
function line( $message, $level = 0 ) {
switch( $level ) {
case 3:
$message = 'Error: ' . $message;
break;
case 2:
$message = 'Warning: ' . $message;
break;
default:
$message = 'Info: ' . $message;
break;
}
echo "\n" . $message . "\n";
}
if ( ! ( isset( $argv ) && isset( $argv[1] ) ) ) {
line( 'No input file specified', 3 ); die;
}
$file = $argv[1];
if ( ! file_exists( $file ) ) {
line( sprintf( 'File does not exist, or cannot access it: %s', $file ), 3 ); die;
}
$orig_file = fopen( $file, 'r' );
if ( ! $orig_file ) {
line( sprintf( 'Cannot open file, check that we have read perms: %s', $file ), 3 ); die;
}
// Create a new file
$path_info = pathinfo( $file );
$new_name = dirname( __FILE__ ) . '/' . $path_info['filename'] . '-fixed.' . $path_info['extension'];
if ( file_exists( $new_name ) ) {
line( sprintf( 'A Fixed file already exists, delete it and start again: %s', $new_name ), 3 ); die;
}
line( 'Starting process, this could take a bit...' );
// So the script doesn't time out.
@set_time_limit( 0 );
echo "\n";
echo "==========================================\n";
// Walk over the file line by line, copying to the new file.
$lines = 0;
$replacements = 0;
while ( false !== ( $line = fgets( $orig_file ) ) ) {
$old = $line;
$line = preg_replace( '!s:(\d+):([\\\\]?"[\\\\]?"|[\\\\]?"((.*?)[^\\\\])[\\\\]?");!e', "'s:'.strlen(unescape_mysql('$3')).':\"'.unescape_quotes('$3').'\";'", $line );
if ( $line !== $old ) {
$replacements++;
echo 'R ';
} else {
echo '. ';
}
file_put_contents( $new_name, $line, FILE_APPEND );
$lines++;
}
fclose( $orig_file );
echo "\n";
echo "==========================================";
line( sprintf( '%d Replacements', $replacements ) );
line( sprintf( '%d Lines Read', $lines ) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment