baltun
Администратор
- Сообщения
- 13.110
- Реакции
- 3.334
- Баллы
- 1.833
После переноса форума со старого домена на новый потребовалось массово заменить в дополнительных полях доменное имя на новое и был написан такой скрипт fix_rm_custom_fields.php:
Скрипт кидается в корень форума и запускается в моем случае так /opt/php82/bin/php fix_rm_custom_fields.php ответ будет такой в конце
PHP:
<?php
// fix_rm_custom_fields.php — поддержка JSON и serialize
error_reporting(E_ALL & ~E_DEPRECATED & ~E_NOTICE);
$configFile = __DIR__ . '/src/config.php';
if (!file_exists($configFile)) {
die("❌ Файл config.php не найден.\n");
}
$config = [];
require $configFile;
if (empty($config['db']['dbname'])) {
die("❌ Не удалось прочитать настройки БД.\n");
}
$host = $config['db']['host'] ?? '127.0.0.1';
$dbname = $config['db']['dbname'];
$user = $config['db']['username'];
$pass = $config['db']['password'] ?? '';
$port = $config['db']['port'] ?? 3306;
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;port=$port;dbname=$dbname;charset=$charset";
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
} catch (PDOException $e) {
die("❌ Ошибка подключения к БД: " . $e->getMessage() . "\n");
}
// === Замена во всех строках рекурсивно ===
function replace_in_data($data, $search, $replace) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[$key] = replace_in_data($value, $search, $replace);
}
} elseif (is_string($data)) {
$data = str_replace($search, $replace, $data);
}
return $data;
}
echo "🔍 Обрабатываю custom_fields (поддержка JSON и serialize)...\n";
$stmt = $pdo->query('
SELECT resource_id, custom_fields
FROM xf_rm_resource
WHERE custom_fields IS NOT NULL AND custom_fields != ""
');
$updatedCount = 0;
$total = 0;
while ($row = $stmt->fetch()) {
$total++;
$resourceId = $row['resource_id'];
$raw = $row['custom_fields'];
$decoded = null;
$isJson = false;
$isSerialized = false;
// Попытка 1: JSON
if (str_starts_with(trim($raw), '{') || str_starts_with(trim($raw), '[')) {
$decoded = json_decode($raw, true);
if (json_last_error() === JSON_ERROR_NONE) {
$isJson = true;
}
}
// Попытка 2: PHP serialize
if ($decoded === null && is_string($raw) && str_starts_with($raw, 'a:')) {
$decoded = @unserialize($raw, ['allowed_classes' => false]);
if ($decoded !== false) {
$isSerialized = true;
}
}
if ($decoded === null) {
continue; // Неизвестный формат
}
// Выполняем замену
$originalDecoded = $decoded;
$replacements = [
'https://web-zones.ru' => 'https://xenweb.ru',
'http://web-zones.ru' => 'https://xenweb.ru',
];
foreach ($replacements as $old => $new) {
$decoded = replace_in_data($decoded, $old, $new);
}
// Проверяем, были ли изменения
if ($decoded !== $originalDecoded) {
if ($isJson) {
$newRaw = json_encode($decoded, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
} elseif ($isSerialized) {
$newRaw = serialize($decoded);
} else {
continue;
}
$updateStmt = $pdo->prepare('UPDATE xf_rm_resource SET custom_fields = ? WHERE resource_id = ?');
$updateStmt->execute([$newRaw, $resourceId]);
$updatedCount++;
echo "✅ Обновлено: resource_id = $resourceId\n";
}
}
echo "\n✅ Готово!\n";
echo "Обработано записей: $total\n";
echo "Обновлено записей: $updatedCount\n";
// Совместимость с PHP < 8.0
if (!function_exists('str_starts_with')) {
function str_starts_with($haystack, $needle) {
return substr($haystack, 0, strlen($needle)) === $needle;
}
}
Код:
✅ Обновлено: resource_id = 4750
✅ Обновлено: resource_id = 4751
✅ Готово!
Обработано записей: 4200
Обновлено записей: 216