Search code examples
phpmysqlamazon-s3processfopen

php fopen() No such file or directory for file created in same process using Symfony/Component/Process class


I am trying to make mysqldump backup and upload that backup to aws s3. everything is working separately but when trying both in a single script then the file is not found by fopen even file_exists is not able to read the file. please, someone, help. here is the code

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

always getting File Not Found, but backup is successful.


Solution

  • Problem is solved by just removing escapeshellarg() function from file path. because of that function fopen was not able to read that path.

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