简体   繁体   中英

File upload to FTP server from Linux machine using PHP doubles line breaks (but works on Windows)

I usually generate files on my local Windows PC and upload the files programmatically via FTP. Which works 100%.

The same code released to Ubuntu generates the files, the format is 100% identical to the Windows generated file, but when it's transferred via FTP, the file format is changed somehow.

Every second line is blank. I think it has something to do with the end-of-line control character.

But I have no idea what to change for Linux specifically to fix it?

It's generated like this:

700036NAT0373PV36K   20200624228000300119
511193K62904361  7307180317084SHANGASE                 RL      202007010
511193K64710351  9105235602081MBONANE                  H       202007010

But after upload it looks like this:

700036NAT0373PV36K   20200624228000300119                              
                                                                        
511193K62904361  7307180317084SHANGASE                 RL      202007010
                                                                        
511193K64710351  9105235602081MBONANE                  H       202007010

My code:

namespace App\Chains\Persal\InputFile\Processes;

use Illuminate\Support\Facades\File;

use App\Chains\Persal\InputFile\Chain;
use App\Chains\Persal\InputFile\Settings;

class UploadFile extends Chain
{
    public function create(Settings $settings)
    {
        if (isset($settings->args['upload_file']) &&
            (int)$settings->args['upload_file'] === 1 &&
            File::exists($settings->outputFile))
        {
            $settings->currentProcess = static::class;
            info($settings->name.':'.$settings->currentProcess);

            $ftpConnection  = ftp_connect(config('persal_ftp.host')) or die("ERROR: Could not connect to ftp host");

            if (ftp_login($ftpConnection,$settings->mainframe->username,$settings->mainframe->password))
            {
                $commandExecuted = ftp_exec($ftpConnection,config('persal_ftp.ftp_command')); // e.g. quote site lrecl=300 blksize=22800 recfm=fb
                $passiveModeSet  = ftp_pasv($ftpConnection, true);

                if ($commandExecuted && $passiveModeSet)
                {
                    try
                    {
                        $upload = ftp_put($ftpConnection,"'".basename($settings->outputFile)."'",$settings->outputFile, FTP_ASCII);

                        if ($upload)
                        {
                            info("File {{$settings->outputFile}} Successfully Uploaded");
                        }
                    }
                    catch (\Exception $e)
                    {
                        dd('ERROR: Could not upload file:'.$e->getMessage());
                    }
                }

                ftp_close($ftpConnection);
            }

            $this->next($settings);
        }
    }
}

When I use FTP_BINARY instead, it does not work. Neither on Linux, nor on Windows.

The file is most probably created in the wrong format already. I assume it has Windows line endings (CR+LF).

When you upload it using the ascii mode from the Windows machine, the Windows CR+LF line endings are converted to the right format (possibly Linux LF, but maybe even different).

But if you use the ascii mode on the Linux machine, where line endings are just LF, the CR's in the file are left alone and make it to the target machine. There they seem to be misinterpreted as another line break.

And if you use the binary mode (on either Windows or Linux), the CR+LF are preserved on the transfer, and again treated as two line breaks on the target machine.

To correct this, either:

  • Generate the file in the format you want to have on the target machine. And use the binary mode to transfer the file as is.
  • Or generate the file in the correct local format for that specific platform (Windows or Linux). You can use the PHP_EOL constant . Then you can use the ascii mode to transparently upload the file using the right format for the remote system, whatever that is.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM