首页 > 解决方案 > php fopen() 没有使用 Symfony/Component/Process 类在同一进程中创建的文件的此类文件或目录

问题描述

我正在尝试进行 mysqldump 备份并将该备份上传到 aws s3。一切都在单独工作,但是当在一个脚本中尝试两者时,即使 file_exists 也无法读取文件,fopen 也找不到该文件。请有人帮忙。这是代码

function db_backup($db)
{
    date_default_timezone_set("Asia/Kolkata");
    $DBUSER = env('DB_USERNAME');
    $DBPASSWD = env('DB_PASSWORD');
    $today = date('YmdHis');
    $output_file = "{$db}_{$today}.sql.gz";
    if (!is_dir(storage_path('backups'))) mkdir(storage_path('backups'));
    $path = escapeshellarg(storage_path("backups/{$output_file}"));
    $process = new Process(
        sprintf(
            'mysqldump --routines=true --compact --comments=false -u%s -p%s %s |gzip > %s',
            escapeshellarg($DBUSER),
            escapeshellarg($DBPASSWD),
            $db,
            $path
        )
    );
    try {
        $process->run();
        if ($process->isSuccessful()) {
            if (file_exists($path)) {
                //$aws = resolve(S3Service::class);
                //$aws->upload($path, $output_file);
                Log::info("Daily Backup Successs {$path}");
            } else {
                echo "File Not Found: {$path} \n";
            }
        }
    } catch (ProcessFailedException $err) {
        Log::error('Daily Backup Failed', (array) $err);
    }
}

总是找不到文件,但备份成功。

标签: phpmysqlamazon-s3processfopen

解决方案


Symfony 的 Process() 构造函数接受一个数组,而不是一个字符串。以下是文档中的一些有用示例,概述了正确的用法。

幸运的是,有一个静态帮助Process::fromShellCommandline()程序可用于从字符串命令创建新的 Process 对象。

然后,您可以将代码修改为类似于:

$process = Process::fromShellCommandline(sprintf(
'mysqldump --routines=true --compact --comments=false -u%s -p%s %s |gzip > %s',            escapeshellarg($DBUSER),
    escapeshellarg($DBPASSWD),
    $db,
    $path
));

您没有收到任何错误的原因可能是由于您的错误报告。为了证明这个工作我不得不修改你的脚本并运行命令'echo "%s:%s %s" | gzip > %s',而不是 ymmv。


推荐阅读