我有一种情况,我必须更新共享主机提供商的网站.该网站有一个CMS.使用FTP上传CMS的文件非常简单.
我还必须导入一个大的(相对于PHP脚本的限制)数据库文件(大约2-3 MB未压缩).Mysql因外部访问而关闭,因此我必须使用FTP上传文件,并启动PHP脚本进行导入.遗憾的是,我无法访问mysql
命令行函数,所以我必须使用本机PHP解析和查询它.我也不能使用LOAD DATA INFILE.我也不能像phpMyAdmin一样使用任何一种交互式前端,它需要以自动化的方式运行.我也不能用mysqli_multi_query()
.
有没有人知道或者有一个已编码的简单解决方案,可以将这样的文件可靠地拆分成单个查询(可能有多行语句)并运行查询.我想避免自己开始摆弄它,因为我可能遇到很多问题(如何检测字段分隔符是否是数据的一部分;如何处理备忘录字段中的换行符;等等上).有必须是这个现成的解决方案.
Ali*_*xel 50
这是一个内存友好的函数,应该能够在单个查询中拆分大文件,而无需一次打开整个文件:
function SplitSQL($file, $delimiter = ';')
{
set_time_limit(0);
if (is_file($file) === true)
{
$file = fopen($file, 'r');
if (is_resource($file) === true)
{
$query = array();
while (feof($file) === false)
{
$query[] = fgets($file);
if (preg_match('~' . preg_quote($delimiter, '~') . '\s*$~iS', end($query)) === 1)
{
$query = trim(implode('', $query));
if (mysql_query($query) === false)
{
echo '<h3>ERROR: ' . $query . '</h3>' . "\n";
}
else
{
echo '<h3>SUCCESS: ' . $query . '</h3>' . "\n";
}
while (ob_get_level() > 0)
{
ob_end_flush();
}
flush();
}
if (is_string($query) === true)
{
$query = array();
}
}
return fclose($file);
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我在一个大的phpMyAdmin SQL转储上测试它,它工作得很好.
一些测试数据:
CREATE TABLE IF NOT EXISTS "test" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"description" TEXT
);
BEGIN;
INSERT INTO "test" ("name", "description")
VALUES (";;;", "something for you mind; body; soul");
COMMIT;
UPDATE "test"
SET "name" = "; "
WHERE "id" = 1;
Run Code Online (Sandbox Code Playgroud)
各自的输出:
SUCCESS: CREATE TABLE IF NOT EXISTS "test" ( "id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" TEXT, "description" TEXT );
SUCCESS: BEGIN;
SUCCESS: INSERT INTO "test" ("name", "description") VALUES (";;;", "something for you mind; body; soul");
SUCCESS: COMMIT;
SUCCESS: UPDATE "test" SET "name" = "; " WHERE "id" = 1;
Run Code Online (Sandbox Code Playgroud)
单页PHPMyAdmin - Adminer - 只需一个PHP脚本文件.检查:http://www.adminer.org/en/