Този архивен скрипт е смешен и никой не трябва да прави друга версия на него. Виждал съм този скрипт преди, както и подобни опити, и те имат много проблеми:
- Не разделя имената на таблици в обратни отметки
- Не обработва NULL числа
- Не обработва набори от знаци
- Не обработва двоични данни
- Не създава резервни копия на VIEW
- Не създава резервно копие на TRIGGERS или ЗАХРАНЕНИ ПРОЦЕДУРИ или СЪХРАНЕНИ ФУНКЦИИ или СЪБИТИЯ
- Използва остаряло разширение на mysql (но ето защо искате PDO версия, нали?)
- Използва addslashes() вместо правилна функция за екраниране на MySQL.
- Добавя всички данни за всички таблици в един наистина дълъг низ, преди да изведе цялото съдържание. Това означава, че трябва да можете да съхранявате цялата си база данни в един низ, което почти сигурно ще надхвърли ограничението на вашата PHP максимална памет.
Вижте също миналия ми отговор относно злополучния скрипт за архивиране на Дейвид Уолш:
Отново вашия коментар:
Прочетете коментарите на страницата, към която сте дали връзка. Много хора са идентифицирали проблеми, а някои имат поправки или поне предложения.
Фактът, че този скрипт добавя всичко в един низ, е проблем, според мен, но не би трябвало да е трудно да промените скрипта, за да отворите изходния файл първо , след това изведете данните на всеки ред по време на цикъла, след което затворете файла след цикъла. Това е нещо безсмислено, не съм сигурен защо сценарият не го прави. Но е доста ясно, че скриптът не е тестван много добре.
Но така или иначе, не бих се опитал да изобретя това колело. Mysqldump или mydumper вършат добре тази работа. FWIW, не е нужно да стартирате mysqldump на същия сървър, където се намира базата данни. Mysqldump поддържа опция за --host
така че можете да стартирате mysqldump навсякъде, за да архивирате отдалечена база данни, стига защитните стени да не блокират свързването на вашия клиент. По принцип, ако можете да свържете PHP приложение към базата данни от някакъв клиентски хост, можете да свържете mysqldump.
Ако това наистина не е опция, тогава бих използвал функцията за изхвърляне на база данни на phpmyadmin. Те са зрели и добре тествани и изхвърлят всичко правилно. Ето статия, която описва как да използвате функцията за изхвърляне:
http://www.techrepublic. com/blog/smb-technologist/import-and-export-databases-using-phpmyadmin/
[Копиране на моите коментари от вашия отговор:]
Това навлиза в прегледа на кода, което не е целта на StackOverflow. Но накратко:
- няма правилна поддръжка за NULL (преобразувате ги в '');
- непоследователно разделяне на имена на таблици;
- използване на двойни кавички извън ANSI като разделители на низове;
- използването на буферирани заявки за огромни таблици ще наруши максималния лимит на паметта на PHP;
- прибавянето на всички редове за огромна таблица ще наруши максималния лимит на паметта на PHP;
- използване на addslashes() вместо PDO::quote();
- проверка за грешки в заявката само в края на функцията;
- не проверява за неуспешно създаване на файл;
- разширението gzip може да не е заредено
- Освен това вероятно все още не поддържа UTF8 данни.
Да, това е по-добре от оригиналния сценарий на Дейвид Уолш. :-)
NULL не е същото като '' в SQL (освен в Oracle, но те не отговарят на SQL стандарта в този случай). Вижте MySQL, по-добре да вмъкнете NULL или празно низ?
Погрешно прочетох кода относно проблема с ограничението на паметта. Пишете изход за всеки ред, така че това е добре (освен ако редът не съдържа 1GB blob или нещо подобно).
Но не трябва просто да извеждате един израз INSERT с набор от редове, разделени със запетая. Дори mysqldump --extended-insert
извежда данни с ограничена дължина, след което стартира нов оператор INSERT. Критерият е дали дължината на израза INSERT се вписва в аргумента на опцията за --net-buffer-length
.
В ANSI SQL единични кавички '' се използват за ограничаване на низови литерали или литерали за дата. Двойните кавички "" се използват за разделяне на идентификатори като име на таблица или имена на колони. По подразбиране MySQL ги третира по същия начин, но това е нестандартно. Вижте Различните бази данни използват ли различни цитати на имена? . Ако се опитате да импортирате вашите архивни данни на MySQL сървър, където сте SET SQL_MODE=ANSI_QUOTES
, импортирането ще бъде неуспешно.
Пример:query('SELECT * FROM '.$table);
и всъщност всеки от другите случаи, когато използвате $table в заявка. Вие сте разделили таблицата само веднъж, в оператора INSERT, който извежда вашият скрипт.
MySQL винаги разпознава обратните отметки като разделители на идентификатори и единични кавички за низове/дати. Но двойните кавички променят значението си в зависимост от SQL_MODE, който споменах. Не можете да предположите кой SQL_MODE е в сила върху екземпляра на MySQL, който възстановявате, така че е най-добре да използвате обратните отметки за идентификатори и единични кавички за низове. Причината да ги разграничите, докато заявявате вашата таблица, е, че може да имате имена на таблици, които са запазени от SQL думи или които съдържат специални знаци и т.н.
Можете да вмъквате всички числови типове без разделители. Само низове и дати се нуждаят от разделители. Вижте dev.mysql.com/doc/refman/5.6/en/literals.html