Skip to content

Instantly share code, notes, and snippets.

@ozh
Created November 23, 2025 18:49
Show Gist options
  • Select an option

  • Save ozh/553c2519878984271584939355e91b8e to your computer and use it in GitHub Desktop.

Select an option

Save ozh/553c2519878984271584939355e91b8e to your computer and use it in GitHub Desktop.
YOURLS plugin : Master and Slave Databases (requires YOURLS 1.10.3+)
<?php
/*
Plugin Name: MySQL Master & Slave for YOURLS 1.10.3+
Plugin URI: https://gist.github.com/ozh/553c2519878984271584939355e91b8e
Description: Configure a MySQL Master & Slave setup for YOURLS
Version: 0.1
Author: Ozh
Author URI: https://ozh.org/
*/
// Init when plugins load
yourls_add_action('plugins_loaded', 'mysql_master_slave_init');
function mysql_master_slave_init() {
// the WRITE connection is the one used for all write operations (insert, update, delete)
// It should probably be the same as the default YOURLS database settings
$write = [
'dns' => 'mysql:host=localhost;dbname=yourls_empty;charset=utf8mb4',
'user' => 'root',
'pass' => '',
];
// the READ connection is used for read-only operations (select)
// Use settings of your SLAVE database
$read = [
'dns' => 'mysql:host=localhost;dbname=yourls_empty;charset=utf8mb4',
'user' => 'root',
'pass' => '',
];
MySQL_Master_Slave_Manager::init($read, $write);
}
// Handle database connections
class MySQL_Master_Slave_Manager {
private static $connections = null;
public static function init($read, $write) {
self::$connections = new Aura\Sql\ConnectionLocator();
self::$connections->setDefault(function () use ($write) {
$ydb = new \YOURLS\Database\YDB( $write['dns'], $write['user'], $write['pass'], [], [] );
$ydb->init();
yourls_debug_log('Init default connection');
return $ydb;
});
self::$connections->setWrite('master', function () use ($write) {
$ydb = new \YOURLS\Database\YDB( $write['dns'], $write['user'], $write['pass'], [], [] );
$ydb->init();
yourls_debug_log('Init master connection');
return $ydb;
});
self::$connections->setRead('slave', function () use ($read) {
$ydb = new \YOURLS\Database\YDB( $read['dns'], $read['user'], $read['pass'], [], [] );
$ydb->init();
yourls_debug_log('Init slave connection');
return $ydb;
});
}
public static function getConnections() {
return self::$connections;
}
public static function isInitialized() {
return self::$connections !== null;
}
}
// Intercept all yourls_get_db() calls and use the appropriate connection based on the context
yourls_add_filter('get_db', 'mysql_master_slave_get_db');
function mysql_master_slave_get_db($db, $context) {
if (!MySQL_Master_Slave_Manager::isInitialized()) {
return $db;
}
// if $context starts with 'other-', use the default connection
if (strpos($context, 'other-') === 0) {
// log context, but not if the context is 'other-debug_log' which is in function yourls_debug_log(), otherwise infinite loop
if ($context != 'other-debug_log') {
yourls_debug_log('DB context : '.$context);
}
return $db;
}
$connections = MySQL_Master_Slave_Manager::getConnections();
// if $context starts with 'read-', use the read connection
if (strpos($context, 'read-') === 0) {
yourls_debug_log('DB context : '. $context . ' - Using read connection');
return $connections->getRead();
}
// if $context starts with 'write-', use the write connection
if (strpos($context, 'write-') === 0) {
yourls_debug_log('DB context : '. $context . ' - Using write connection');
return $connections->getWrite();
}
// otherwise, use the default connection
return $db;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment