php - 最佳实践 : Import mySQL file in PHP; split queries

标签 php mysql

我有一种情况,我必须在共享托管服务提供商上更新网站。该网站有一个 CMS。使用 FTP 上传 CMS 的文件非常简单。

我还必须导入一个大的(相对于 PHP 脚本的限制)数据库文件(大约 2-3 MB 未压缩)。 Mysql 对外部访问是关闭的,所以我必须使用 FTP 上传一个文件,然后启动一个 PHP 脚本来导入它。遗憾的是,我无权访问 mysql 命令行功能,因此我必须使用 native PHP 解析和查询它。我也不能使用 LOAD DATA INFILE。我也不能使用任何类型的交互式前端,如 phpMyAdmin,它需要以自动化方式运行。我也不能使用 mysqli_multi_query()

有没有人知道或有一个已经编码的简单解决方案可以可靠地将这样的文件拆分为单个查询(可能有多行语句)并运行查询。由于我可能会遇到许多陷阱,我想避免自己开始摆弄它(如何检测字段定界符是否是数据的一部分;如何处理备注字段中的换行符;等等)上)。 必须为此准备好解决方案。

最佳答案

这是一个内存友好的函数,它应该能够在单个查询中拆分一个大文件,而无需一次打开整个文件:

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;
}

我在一个大的 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;

以及相应的输出:

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;

关于php - 最佳实践 : Import mySQL file in PHP; split queries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1883079/

相关文章:

php - 使用 cURL 请求 instagram api 访问 token

php - 获取特定日期不在另一个表中的记录。 MySQL

MySQL存储过程——插入多行

java - 无法将 mysql 驱动程序与 Wildfly 9.0.2 一起使用,但它似乎已正确加载

php - 如何在 Wordpress 数据库的 mysql 中将行值转换为列标题

javascript - 将 php 变量保存到函数中的脚本变量

php - 通过 Facebook Graph API 编辑评论

php - PHP 中的双向加密 - 需要一些指导

PHP Mysql - 在 Select 语句中使用变量作为列名

MySql JOIN 两个表 SUM 左表的错误结果