· 7 years ago · Dec 19, 2018, 10:54 AM
1$dbh = new PDO('mysql:host=localhost;dbname=test;charset=UTF8', 'root', '');
2$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
3
4if($dbh) {
5 echo "Соединение уÑтановлено<br><br>";
6} else {
7 throw new Exception("Ошибка ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð±Ð°Ð·Ð¾Ð¹ данных", 1);
8}
9
10/*
11 ÐаÑтройки Ñкрипта
12*/
13
14// ОпределÑем Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†
15$oldTableName = 'documents';
16$newTableName = 'documents_encoded';
17
18// ОпределÑем переменные Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ±Ð¾Ñ€Ð°
19$limit = 1000;
20$point = 0;
21$offset = 0;
22$oldDbData = array();
23
24
25// Получаем общее количеÑтво запиÑей в таблице `documents`
26$allRows = $dbh->query("SELECT count(*) FROM {$oldTableName}")->fetchColumn();
27
28//Ñоздаем новую таблицу, в которой размеÑтим измененные данные
29$newTableSql = <<<EOL
30create table if not exists {$newTableName}
31(
32 id int(11) not null auto_increment,
33 title varchar(255) not null,
34 document_text text not null,
35 PRIMARY KEY(id)
36) CHARACTER SET utf8 COLLATE utf8_general_ci;
37EOL;
38if ($dbh->exec($newTableSql) === false) {
39 throw new Exception('Ðе удалоÑÑŒ Ñоздать новую таблицу');
40}
41
42//Ñобираем данные из Ñтарой таблицы, обрабатываем и вноÑим в новую. ИÑпользуем вложенных SELECT, чтобы Ñнизить нагрузку на БД
43$oldDbSql = $dbh->prepare("SELECT t.id, t.title, t.document_text
44 FROM ( SELECT id FROM {$oldTableName} ORDER BY id LIMIT :offset, {$limit} ) q
45 JOIN {$oldTableName} t
46 ON t.id = q.id
47 ");
48
49while ($point < $allRows) {
50 if($point % $limit === 0) {
51 $oldDbSql->bindParam(':offset', $offset, PDO::PARAM_INT);
52 $oldDbSql->execute();
53 $oldDbData = $oldDbSql->fetchAll(PDO::FETCH_ASSOC);
54 $offset = $offset + $limit;
55
56 $cnt_rows = count($oldDbData);
57 $row_length = count($oldDbData[0]);
58 $length = $cnt_rows * $row_length;
59
60 $args = implode(',', array_map(
61 function($el) {return '('.implode(',', $el).')'; },
62 array_chunk(array_fill(0, $length, '?'), $row_length)
63 ));
64
65 $params = array();
66
67 // Обрабатываем Ñтроки и менÑем кодировку
68 foreach($oldDbData as $row) {
69 $row['title'] = strip_tags(mb_convert_encoding($row['title'], 'UTF-8', 'windows-1251'));
70 $row['document_text'] = strip_tags(mb_convert_encoding($row['document_text'], 'UTF-8', 'windows-1251'));
71 foreach($row as $value) {
72 $params[] = $value;
73 }
74 }
75
76 // Подготавливаем Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð»Ñ Ð²Ñтавки значений. Будем отправлÑть оптимизированно, одним запроÑом, дабы Ñнизить количеÑтво запроÑов к БД.
77 $stmt = $dbh->prepare("INSERT INTO {$newTableName} (id, title, document_text) VALUES " . $args);
78
79 try {
80 $stmt->execute($params);
81 } catch(PDOException $e) {
82 throw new PDOException("Ошибка вÑтавки данных в таблицы: $e");
83 $dbh->rollBack();
84 }
85 }
86
87 $point++;
88}