Skip to content

Instantly share code, notes, and snippets.

@cheryllium
Created April 29, 2021 02:54
Show Gist options
  • Save cheryllium/af52aefd8a9a3772f5f776beeb0b8b48 to your computer and use it in GitHub Desktop.
Save cheryllium/af52aefd8a9a3772f5f776beeb0b8b48 to your computer and use it in GitHub Desktop.
[Laravel] custom console command for converting utf8 VARCHAR columns to utf8mb4
<?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