Created
April 29, 2021 02:54
-
-
Save cheryllium/af52aefd8a9a3772f5f776beeb0b8b48 to your computer and use it in GitHub Desktop.
[Laravel] custom console command for converting utf8 VARCHAR columns to utf8mb4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Console\Commands; | |
use Illuminate\Console\Command; | |
use DB; | |
/** | |
* Tested on Laravel 8.x, PHP 8 and MySQL 8 - but may work on lower versions (?) | |
* | |
* Put this in your app/Console/Commands directory. | |
* You can run this with `php artisan fix:utf8` | |
* Make sure to set your database name in the first line of the handle() function first. | |
* | |
* This command will query your DB for all VARCHAR columns that are still in utf8 | |
* It will then run ALTER queries to update the charset to utf8mb4 and resize each column. | |
* If the column is too large to be resized, it is skipped. You could modify this script | |
* to change it to a TEXT column if you wish. | |
* | |
* In either case, a log is output, so you could capture this, for instance: | |
* `php artisan fix:utf8 > out.log` | |
* | |
* A count is output at the end if you might find it helpful. :) | |
* | |
*/ | |
class FixUTF8 extends Command | |
{ | |
protected $signature = 'fix:utf8'; | |
protected $description = 'Finds utf8 VARCHAR columns and resizes and updates to utf8mb4 if they are small enough'; | |
public function handle(){ | |
$database = ''; // name of your database | |
$results = DB::select("SELECT table_name, column_name, character_maximum_length FROM information_schema.`COLUMNS` where table_schema='{$database}' and character_set_name='utf8' and collation_name='utf8_unicode_ci' and data_type='varchar';"); | |
$count = 0; | |
foreach($results as $row) { | |
if($row->CHARACTER_MAXIMUM_LENGTH > 32767) { | |
echo "Skipping {$row->TABLE_NAME}.{$row->COLUMN_NAME} (exceeded max length) \n"; | |
} else { | |
$length = $row->CHARACTER_MAXIMUM_LENGTH * 2; | |
echo "Altering {$row->TABLE_NAME}.{$row->COLUMN_NAME} (new length: {$length})\n"; | |
$count += DB::statement("ALTER TABLE `{$row->TABLE_NAME}` MODIFY `{$row->COLUMN_NAME}` VARCHAR({$length}) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"); | |
} | |
} | |
echo "Total altered: {$count}\n"; | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment