Buscar y reemplazar URLs en toda la base de datos (respetando datos serializados)

Autor: Ángel Julian
php code
<?php /** * Script para reemplazar una URL por otra en TODA la base de datos de WordPress, * respetando datos serializados. * * USO: * 1. Sube este archivo a la raíz del WordPress (junto a wp-config.php). * 2. Accede a https://tudominio.com/search-replace-url.php * 3. Espera a que termine. * 4. Borra el archivo del servidor. */ set_time_limit(0); ini_set('memory_limit', '512M'); // URLs a reemplazar (CONFIGURADAS) $old_url = 'https://dominio.com'; $new_url = 'https://nuevodominio.com'; // Seguridad básica if ($old_url === '' || $new_url === '') { die('URLs no configuradas.'); } // Cargar WordPress para usar $wpdb y funciones serializadas require_once __DIR__ . '/wp-load.php'; global $wpdb; // Reemplazo recursivo dentro de arrays/objetos (para datos serializados) function recursive_str_replace($search, $replace, $data) { if (is_array($data)) { $new = []; foreach ($data as $key => $value) { $new[$key] = recursive_str_replace($search, $replace, $value); } return $new; } elseif (is_object($data)) { foreach ($data as $key => $value) { $data->$key = recursive_str_replace($search, $replace, $value); } return $data; } elseif (is_string($data)) { return str_replace($search, $replace, $data); } else { return $data; } } echo "<pre>"; echo "=============================================n"; echo " Search & Replace de URLs en WordPressn"; echo "=============================================nn"; echo "Reemplazando:n"; echo " DE: {$old_url}n"; echo " A : {$new_url}nn"; $tables = $wpdb->get_col('SHOW TABLES'); foreach ($tables as $table) { echo "Tabla: {$table}n"; $columns = $wpdb->get_results("DESCRIBE {$table}"); if (!$columns) { echo " - No se pudieron leer columnasn"; continue; } $text_columns = []; $primary_keys = []; foreach ($columns as $col) { $type = strtolower($col->Type); if (strpos($type, 'text') !== false || strpos($type, 'char') !== false) { $text_columns[] = $col->Field; } if ($col->Key === 'PRI') { $primary_keys[] = $col->Field; } } if (empty($text_columns)) { echo " - Sin columnas de textonn"; continue; } if (empty($primary_keys)) { echo " - ⚠️ Sin clave primaria → se omite por seguridadnn"; continue; } foreach ($text_columns as $col) { echo " > Columna: {$col}n"; $like = '%' . $wpdb->esc_like($old_url) . '%'; $rows = $wpdb->get_results( $wpdb->prepare("SELECT * FROM {$table} WHERE {$col} LIKE %s", $like), ARRAY_A ); if (!$rows) { echo " - Sin coincidenciasn"; continue; } $updated = 0; foreach ($rows as $row) { $original = $row[$col]; $unserialized = maybe_unserialize($original); if (is_array($unserialized) || is_object($unserialized)) { $replaced = recursive_str_replace($old_url, $new_url, $unserialized); $new_value = serialize($replaced); } else { $new_value = str_replace($old_url, $new_value = $new_value = $original, $original); $new_value = str_replace($old_url, $new_url, $original); } if ($new_value === $original) { continue; } // Construcción de WHERE según clave primaria $where = []; $params = [$new_value]; foreach ($primary_keys as $pk) { $where[] = "{$pk} = %s"; $params[] = $row[$pk]; } $sql = "UPDATE {$table} SET {$col} = %s WHERE " . implode(' AND ', $where); $result = $wpdb->query($wpdb->prepare($sql, $params)); if ($result !== false) { $updated++; } } echo " - Actualizadas: {$updated}n"; } echo "n"; } echo "=============================================n"; echo " PROCESO COMPLETADOn"; echo " Borra este archivo del servidor.n"; echo "=============================================n"; echo "</pre>";

Este snippet en PHP te permite actualizar una URL antigua por una nueva en toda la base de datos de WordPress, algo especialmente útil tras migrar un proyecto de un dominio a otro o de un subdirectorio a la raíz (por ejemplo, de https://tudominio.com/store a https://nuevo.tudominio.com).

A diferencia de un simple REPLACE en SQL, este script:

  • Carga el entorno de WordPress usando wp-load.php.
  • Utiliza $wpdb y maybe_unserialize() para no romper datos serializados (opciones, metadatos, constructores visuales, etc.).
  • Recorre todas las tablas y todas las columnas de texto, actualizando únicamente las filas donde realmente aparece la URL antigua.

Cómo usarlo

  1. Haz una copia de seguridad de la base de datos (imprescindible).
  2. Copia el snippet en un archivo, por ejemplo: search-replace-url.php.
  3. Sube el archivo a la raíz de tu instalación (donde está wp-config.php).
  4. Edita las variables $old_url y $new_url con tus dominios.
  5. Accede a https://tusitio.com/search-replace-url.php y deja que termine el proceso.
  6. Comprueba que la web funciona correctamente.
  7. Borra el archivo del servidor cuando hayas terminado.

Ideal para:

  • Migraciones rápidas sin plugins adicionales.
  • Entornos donde prefieres tener control total sobre lo que se ejecuta.
  • Casos en los que hay muchos datos serializados (constructores, WooCommerce, plugins de SEO, etc.).