Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How this extension can be used to append to existing files. #12

Closed
ndobromirov opened this issue May 11, 2017 · 7 comments
Closed

How this extension can be used to append to existing files. #12

ndobromirov opened this issue May 11, 2017 · 7 comments

Comments

@ndobromirov
Copy link
Contributor

I have a very slow process and HUGE CSV files.

The idea is whenever a reasonable sized piece of data is ready for it to be appended to a temporary FTP file. When the whole process finishes, the file is renamed to it's final position (name), so some 3rd party starts the processing with the whole data-set.

I know that this can be done with file_put_contents and some stream hacks, but it's ugly to have 2 ways of doing a single thing.

Any guidelines would be appreciated.

@hguenot
Copy link
Owner

hguenot commented May 11, 2017

I think you can't because FTP protocol can't merge file.

@ndobromirov
Copy link
Contributor Author

ndobromirov commented May 11, 2017

So after some more research, the FTP protocol allows it to have append.
http://stackoverflow.com/questions/2536592/use-of-ftp-append-command it is documented also in the RFC search for APPEND (with create) (APPE).

The thing is that for some reason the PHP's ftp api has not implemented this.

Thugh you can achieve it through ftp:// stream and using the APPEND flags there.

The problem with that solution is that the authentication and all the network communication will be doubled for a single append of a file, even though a handle is already created.

I am pretty sure that this should be possible through exec or a raw command. I will be testing it tomorrow.

@ndobromirov
Copy link
Contributor Author

I've made it work with the proposal from the first comment but that's more of a hack than a solution, as it is not using the existing handle, but making a new connection on each append...

class FtpComponent extends \gftp\FtpComponent
{
    public function __construct($config = array())
    {
        parent::__construct($config);
    }

    public function append($localFile, $remoteFile)
    {
        if (($contents = file_get_contents($localFile)) === false) {
            throw new FtpException("Failed reading from local file: $localFile!");
        }

        $connection = rtrim($this->getConnectionString(), '/');
        $path = "$connection/" . ltrim($remoteFile, '/');

        ($result = file_put_contents($path, $contents, FILE_APPEND));
        if ($result === false) {
            throw new FtpException("Failed writing to file: $remoteFile");
        }

        if (($expected = strlen($contents)) !== (int) $result) {
            throw new FtpException("Written only $result out of $expected bytes to the remote file!");
        }

        return $result;
    }

}

@ndobromirov
Copy link
Contributor Author

Is it an option to have a driver that will handle stream-based connections?
It will be based on the PHP primitives for file management and fallback to the streaming API underneath.

That way the communication will at least be consistent within the driver.

@ndobromirov
Copy link
Contributor Author

So I was not able to make this work with the ftp_* APIs so this propagated to PHP.

@hguenot
Copy link
Owner

hguenot commented May 18, 2017

Hi, yes it is possible to implements such driver but I no time to develop it.

@hguenot
Copy link
Owner

hguenot commented May 19, 2017

I just added support for resource in put and get method... I see ftp_fget / ftp_fput have an extra parameter resumePos (http://php.net/manual/en/function.ftp-fget.php) / startPos (http://php.net/manual/en/function.ftp-fput.php)
I think it can be use to append file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants