使用 PHP/Joomla,我正在尝试将数据库备份导出到 CSV/sql 文件中进行下载。有些表有大量的记录。当我开始导出时,它给出以下错误: 致命错误:超过 30 秒的最大执行时间
注意:我不想使用 'max_execution_time' 或 'set_time_limit()' 或任何 php.ini 设置。因为我将在不同的客户端服务器上使用此脚本,并且我不会告诉每个客户端更改设置。我需要 PHP/Joomla 脚本,而不是任何扩展。
请帮我。
鉴于您对我之前的回答的评论,我建议您考虑创建一个 Joomla!CLI(查看/cli
您的 Joomla 2.5+ 安装目录)。
对于我们为内部使用而开发的 Easystaging 扩展的 Pro 版本,我们已经做了类似的事情,以管理具有特定内容批准流程的客户网站。内部版本必须处理我们更大的客户需求。
实际上,我们创建了继承自JApplicationCli
CRON 或由我们的组件用户界面启动的类。例如
class EasyStaging_PlanRunner extends JApplicationCli
{
/**
* Entry point for the plan funner (yes it's more fun)
*
* @return void
*
* @since 2.5
*/
public function doExecute()
{
}
}
如果它是由用户从 Joomla 中启动的,我们使用实用程序方法来确保系统正确地分叉它:
/**
* Runs the script in the background by scheduling it with the `at` daemon and returns the result
*
* @param string $pathToScript A path to the script to run e.g. "/path/to/my/cli/app.php"
*
* @return int
*/
private function _runScriptInBackground($pathToScript)
{
$cmdPath = "/usr/bin/php -q $pathToScript";
// We need '2>&1' so we have something to pass back
$cmd = 'echo "' . $cmdPath . '" | at now 2>&1';
$result = shell_exec($cmd);
return $result;
}
由于这是作为命令行脚本有效运行的,因此许多限制要宽松得多,但它们仍然不会让您绕过非常大的桌子。(我们的一些客户拥有数千篇文章或更差的 K2 内容项)。
为了解决这个问题,我们编写了一个从我们doExecute()
的主调度循环调用的导出方法,以合理的批次检索和导出表行。对我们来说,合理是由远程数据库max_allowed_packet
值决定的,我们创建了一个 SQL 文件,其中包含符合此限制的语句,并为各种开销留出了少量余量。您可能没有这些问题,但即便如此,您也应该将 SQL 分解为合理大小的insert
语句。
一旦计划完成运行,我们就会压缩所有文件并将它们发送到存档。
由于某些表的数据量很大,因此需要相当长的时间。结果,连接将超时并且导出将失败。
更好的方法是使用命令行将数据转储为 SQL。您可能想查看 mysqldump 命令。
您还可以从这样的 PHP 脚本调用 mysqldump 命令 -
<?php
# Database Settings
$tmpDir = "/home/<username>/tmp/"; // Temp location the user has access to
$user = "<username>_******"; // MySQL Username for the database
$password = "*******"; // MySQL Password
$dbName = "<username>_******"; // Database name, usually in the pattern: <username>_<dbname>
$dbHost = "localhost"; // Mysql server hostname, usually localhost
$sqlFile = $tmpDir . $dbName . date('Y_m_d') . ".sql"; // The dumped SQL File
$attachment = $tmpDir . $dbName . "_" . date('Y_m_d') . ".tgz"; // TGZed file
$creatBackup = "mysqldump -h '" . $dbHost . "' -u '" . $user . "' --password='" . $password . "' '" . $dbName . "' > '" . $sqlFile . "'"; // Full command
$createZip = "tar cvzf $attachment $sqlFile"; // Full Command
// Execute 'em
system($creatBackup);
system($createZip);
这应该创建一个 SQL 转储并从中创建一个存档。
上面的代码是我构建的一个工具的一部分,用于通过电子邮件向我发送数据库的每日备份。您可以在 Github 上查看并修改它以适合您的目的 - https://github.com/masnun/mysql-backup-to-email
也许您甚至必须将每个表的记录拆分到不同的文件中。
我建议您不要重新发明轮子,而是使用Akeeba Backup,因为它可以让您创建整个站点的自动备份,或者只是文件或特定目录,或者只是数据库或特定表或任何您能想到的组合的。
它也是免费的。
它年复一年地获奖,在Joomla 扩展目录中获得高度评价,我们在所有网站和客户网站上都使用它。
如果您获得Pro 版本,您甚至可以备份到 Amazon 的 S3 或其他有用的系统。
除了我喜欢使用他们的产品外,我与 Akeeba 没有任何关系——他们让我晚上睡觉。