7

StackOverflow はこの件について十分に説明していないように見えるので、これは質問に値すると思います。

プログレスバー付きのPHPを使用してSFTPしたい

プログレスバーが大好きです。しかし、今回は少し違うことをしたいと思っています。PHPで次のことをしたいのですが、これは前回よりもずっと難しいようです:

  • SFTP経由でダウンロードを実行します(SSH経由?)
  • ユーザーにダウンロードの進行状況を視覚的に示す
  • ダウンロードの一時停止と続行を有効にする

FileZillaを考えてみてください。ただし、PHP で構築されたブラウザー内です。Apache をハッキングしたり、Apache の mod を追加したりしたくありません。


実際のダウンロードのオプション

基本的な SFTP ダウンロードについては、ここここここここにたくさんの質問があります。

これらのドキュメントは、 PHP の SSH2 拡張機能(現在使用しています - これは pecl 経由でインストールします) と、私が使用していない代わりのPHPSecLibですが、後で調べる可能性があります。
私のインターフェースは簡単にスワップイン/アウトできます-実装ではなくインターフェースへのコーディングなど...

それは素晴らしいことですが、彼らは実際のダウンロードを実行するだけです。

ダウンロードの進行状況

PHP には と呼ばれる非常に興味深いコールバックがstream_notification_callbackあります。詳細については、こちらを参照してください

これは見栄えがよく、有望なステップでしたが、誰かが PHP のソース コードを調べたところ、残念ながら SSH2 / SFTPではこれとの統合が許可されていないことがわかりました。
これを調査する努力をしてくれた hek2mgl に感謝します。

アイデアstream_notification_callbackは、データが取得されるたびに現在のダウンロード サイズの通知を渡すことでした。したがって、現在ダウンロードされている量と合計ファイル サイズを使用してパーセンテージを計算するために必要なデータを提供します。しかし、それはSSH2とSFTPには当てはまりません...

そして、一時停止/継続はどうですか?

私の意見では、これは達成するのが最も難しいでしょう。データを一時ファイルにダウンロードすることは可能です...これが私がなんとか掘り起こしたものです: http://ee.php.net/manual/en/function.fread.php#84115 - しかし、そのようなコードをプログレスバーがおかしいようです。

ついに

cURL もありますが、これを SFTP 経由でダウンロードを一時停止/再開することはできませんでした。私が間違っている場合は修正してください。

では、PHP を使用してブラウザー内で前述の要件を統合するにはどうすればよいでしょうか。クライアント側のことは忘れて、ブラウザにデータを取得するだけで十分なので、これを実行するための推奨事項は素晴らしいでしょう.

4

2 に答える 2

2

これは私がこのサイトから取ったサンプルです:

    // Write from our remote stream to our local stream
    $read = 0;
    $fileSize = filesize("ssh2.sftp://$sftp/$fileName");
    while ($read < $fileSize && ($buffer = fread($remoteStream, $fileSize - $read))) {
        // Increase our bytes read
        $read += strlen($buffer);

        // Write to our local file
        if (fwrite($localStream, $buffer) === FALSE) {
            throw new Exception("Unable to write to local file: /localdir/$fileName");
        }
    }

ファイルのサイズがあり、 fread でファイルから読み取るため、進行状況を判断するのは簡単です。

一時停止は、ユーザーが [一時停止] ボタンをクリックした場合に設定した APC などの値を確認することで実行できます (メイン スクリプトを停止しないように iframe でこれを行います)。

于 2013-09-09T01:55:41.807 に答える
1

PHP で大きなファイルをダウンロードすると、チェックアウトサーバーが失敗します。あなたにいくつかのアイデアを与えるかもしれません。

要約すると...答えの1つは、チャンクが受信されるたびにデータをエコーアウトするようにphpseclibを変更することを提案しています。別の答えは、チャンクでダウンロードし、ダウンロード時にチャンクを出力することを提案しています。

それは、stream_notification_callback を使用するというあなたの考えとかなり一致しているようです。

幸運を!

于 2013-03-27T19:25:26.913 に答える