Подтвердить что ты не робот

Как удалить значения htmlentities() из базы данных?

Задолго до того, как я что-то знал - не то, что я знаю многое даже сейчас - я отложил веб-приложение на php, которое вставляло данные в мою базу данных mysql после запуска значений через htmlentities(). Я в конце концов опомнился и снял этот шаг и застрял на выходе, а не на входе, и продолжил свой веселый путь.

Однако с тех пор мне пришлось пересмотреть некоторые из этих старых данных, и, к сожалению, у меня есть проблема, когда она отображается на экране, я получаю значения, которые эффективно отображаются дважды.

Итак, есть ли способ mysql или phpmyadmin изменить все старые, затронутые строки обратно на соответствующие символы или мне придется написать script, чтобы читать каждую строку, декодировать и обновлять все 17 миллионов строк в 12 таблицах

EDIT:

Спасибо за помощь всем, я написал свой собственный ответ ниже с некоторым кодом, это не очень, но он работал над тестовыми данными ранее, поэтому запрет кому-то указывать на вопиющую ошибку в моем коде, пока я нахожусь в постели я Завтра буду запускать его на резервной БД, а затем на живую, если все будет хорошо.

4b9b3361

Ответ 1

Я закончил тем, что использовал это, а не красиво, но я устал, он 2 утра, и он сделал свою работу! (Изменить: по тестовым данным)

$tables = array('users', 'users_more', 'users_extra', 'forum_posts', 'posts_edits', 'forum_threads', 'orders', 'product_comments', 'products', 'favourites', 'blocked', 'notes');
foreach($tables as $table)
    {       
        $sql = "SELECT * FROM {$table} WHERE data_date_ts < '{$encode_cutoff}'";
        $rows = $database->query($sql);
        while($row = mysql_fetch_assoc($rows))
            {
                $new = array();
                foreach($row as $key => $data)
                    {
                        $new[$key] = $database->escape_value(html_entity_decode($data, ENT_QUOTES, 'UTF-8'));
                    }
                array_shift($new);
                $new_string = "";
                $i = 0;
                foreach($new as $new_key => $new_data)
                    {
                        if($i > 0) { $new_string.= ", "; }
                        $new_string.= $new_key . "='" . $new_data . "'";
                        $i++;
                    }
                $sql = "UPDATE {$table} SET " . $new_string . " WHERE id='" . $row['id'] . "'";
                $database->query($sql);
                // plus some code to check that all out
            }
    }

Ответ 2

Поскольку PHP был методом кодирования, вы захотите использовать его для декодирования. Вы можете использовать html_entity_decode, чтобы преобразовать их обратно в исходные символы. Gotta loop!

Просто будьте осторожны, чтобы не расшифровать строки, которые ему не нужны. Не знаете, как вы это определите.

Ответ 3

Я думаю, что писать php script - хорошая вещь в этой ситуации. Вы можете использовать, как сказал Дэйв, функцию html_entity_decode() для преобразования ваших текстов назад.

Попробуйте использовать script в таблице с небольшим количеством записей. Это позволит вам сэкономить много времени на тестирование. Конечно, не забудьте сделать резервную копию своих таблиц перед запуском PHP скрипт.

Я боюсь, что нет более короткой возможности. Вычисление для миллионов строк остается довольно дорогостоящим, независимо от того, как вы конвертируете данные. Так что идите на php script... это самый простой способ

Ответ 4

Это немного kludgy, но я думаю, что массовое обновление - единственный способ пойти...

$Query = "SELECT row_id, html_entitied_column FROM table";
$result = mysql_query($Query, $connection);
while($row = mysql_fetch_array($result)){
    $updatedValue = html_entity_decode($row['html_entitied_column']);
    $Query = "UPDATE table SET html_entitied_column = '" . $updatedValue . "' ";
    $Query .= "WHERE row_id = " . $row['row_id'];
    mysql_query($Query, $connection);
}

Это упрощено, без обработки ошибок и т.д. Не уверен, что время обработки будет на миллионы строк, поэтому вам может понадобиться разбить его на куски, чтобы избежать таймаутов script.

Ответ 5

У меня была такая же проблема. Поскольку у меня было несколько клиентов, работающих под управлением приложения, я хотел бы избежать использования PHP script для очистки базы данных для каждого из них.

Я придумал решение, которое далека от совершенства, но делает работу безболезненно.

  • Отслеживайте все пятна в коде, где вы используете htmlentities(), перед тем как вставлять данные, и удаляйте их.
  • Измените свой метод "отображения данных как HTML" на что-то вроде этого:

    return html_entity_decode (htmlentities ($ chaine, ENT_NOQUOTES), ENT_NOQUOTES);

Отказоустойчивый процесс выглядит нелепо, но он выполняет эту работу. И ваша база данных будет медленно очищаться каждый раз, когда пользователи обновляют неверные данные.

Ответ 6

Это моя пуленепробиваемая версия. Он выполняет итерацию по всем столбцам Tables и String в базе данных, определяет первичный ключ и выполняет обновления.

Предполагается запустить php файл из командной строки, чтобы получить информацию о ходе.

<?php
$DBC = new mysqli("localhost", "user", "dbpass", "dbname");
$DBC->set_charset("utf8");

$tables = $DBC->query("SHOW FULL TABLES WHERE Table_type='BASE TABLE'");
while($table = $tables->fetch_array()) {
    $table = $table[0];
    $columns = $DBC->query("DESCRIBE `{$table}`");
    $textFields = array();
    $primaryKeys = array();
    while($column = $columns->fetch_assoc()) {
        // check for char, varchar, text, mediumtext and so on
        if ($column["Key"] == "PRI") {
            $primaryKeys[] = $column['Field'];
        } else if (strpos( $column["Type"], "char") !== false || strpos($column["Type"], "text") !== false ) {
            $textFields[] = $column['Field'];
        }
    }
    if (!count($primaryKeys)) {
        echo "Cannot convert table without primary key: '$table'\n";
        continue;
    }
    foreach ($textFields as $textField) {
        $sql = "SELECT `".implode("`,`", $primaryKeys)."`,`$textField` from `$table` WHERE `$textField` like '%&%'";
        $candidates = $DBC->query($sql);
        $tmp = $DBC->query("SELECT FOUND_ROWS()");
        $rowCount = $tmp->fetch_array()[0];
        $tmp->free();
        echo "Updating $rowCount in $table.$textField\n";
        $count=0;
        while($candidate = $candidates->fetch_assoc()) {
            $oldValue = $candidate[$textField];
            $newValue = html_entity_decode($candidate[$textField], ENT_QUOTES | ENT_XML1, 'UTF-8');
            if ($oldValue != $newValue) {
                $sql = "UPDATE `$table` SET `$textField` = '"
                    . $DBC->real_escape_string($newValue)
                    . "' WHERE ";
                foreach ($primaryKeys as $pk) {
                    $sql .= "`$pk` = '" . $DBC->real_escape_string($candidate[$pk]) . "' AND ";
                }
                $sql .= "1";
                $DBC->query($sql);
            }
            $count++;
            echo "$count / $rowCount\r";
        }
    }
}
?>

веселит Roland