Ilerleme ftp_put Başlarken

2 Cevap php

Ben ftp_put üzerinden başka bir uzak sunucuya bir dosya yüklediği bir web sunucusu üzerinde bir php komut dosyası var.

Nasıl kullanıcıya geçerli yükleme ilerleme gösterebilir?

Gördüğüm sadece benzer bir sistem sunucu üzerinde yüklenen dosyanın yerel boyutunu kontrol etmek ajax istekleri ile, kullanıcının dosya yüklemeleri içindir.

Eşdeğer bir sistem web sunucusuna ajax istekleri olurdu, o zaman uzak sunucuda dosya boyutlarını kontrol ve döndü kullanıcının clientscript veri.

Bu benim için korkunç verimsiz görünmektedir. Daha iyi bir yolu var mı?

2 Cevap

Diğer makine destekleri REST komutu (belirli bir noktadan itibaren yeniden başlatma yükleme) ftp sunucusu uygulamak için kirli bir yolu varsa:

  1. geçici dosya oluşturmak
  2. Yüklemek istediğiniz dosyayı bu dosyaya X bayt koymak
  3. geçici dosya upload
  4. başka bir dosyaya durumunu yazmak (veya oturumda, ama emin değilim bu iş olacak eğer)
  5. temp dosyasına başka bir X bayt append
  6. Form X bayt başlayan geçici dosyası yükle
  7. Dosyaya kriter durum
  8. tüm dosya yüklenene kadar 5-7 tekrarlayın
  9. temp & silme durum dosyaları.

Örnek kod:

$fs = filesize('file.bin');
define('FTP_CHUNK_SIZE', intval($fs * 0.1) ); // upload ~10% per iteration

$ftp = ftp_connect('localhost') or die('Unable to connect to FTP server');
ftp_login($ftp, 'login', 'pass') or die('FTP login failed');

$localfile = fopen('file.bin','rb');

$i = 0;
while( $i < $fs )
{
    $tmpfile = fopen('tmp_ftp_upload.bin','ab');
    fwrite($tmpfile, fread($localfile, FTP_CHUNK_SIZE));
    fclose($tmpfile);

    ftp_put($ftp, 'remote_file.bin', 'tmp_ftp_upload.bin', FTP_BINARY, $i);
    // Remember to put $i as last argument above

    $progress = (100 * round( ($i += FTP_CHUNK_SIZE)  / $fs, 2 ));
    file_put_contents('ftp_progress.txt', "Progress: {$progress}%");
}
fclose($localfile);
unlink('ftp_progress.txt');
unlink('tmp_ftp_upload.bin'); // delete when done

Ve ajax ile kontrol dosyası:

if(file_exists('ftp_progress.txt'))
    echo file_get_contents('ftp_progress.txt');
else
    echo 'Progress: 0%';
exit;

Tamamlayana kadar tek yolu kullanarak (ftp_put) Uzak FTP sunucusu yoklamak ve hangi dosya boyutu görmek için olacağını söyledi şekilde PHP işlevi ftp_put, geri dönmeyecek genellikle yüklenenler onlar% 100 tamamlandığında sadece yerine konduğunu, geçici bir dosyaya gidin çünkü zaten çalışmıyor olabilir, olduğunu.

Ne var onun yerine yapacağını yükleme yapmak, ve wget veya curl gibi bir şey kullanmak için ikinci bir işlem spawn edilir. Sen curl dan çıkışını ayrıştırmak ve ilerleme ayıklamak.

Yani (bunu yapmak için çeşitli yollar var, ve bu sadece bir öneri ...) I önermek

  1. Kullanıcı yüklenenler PHP komut dosyası
  2. Sizin PHP komut dosyası benzersiz bir kimliktir $ uploadId üretir
  3. Sizin PHP komut exec() bir arka plan iş olarak curl yumurtlama, curl dosya yüklemek için ve gibi bazı dosyaya çıkış yönlendirme için kullandığı {[(3) }]
  4. upload_progress.php?id=$uploadId: PHP komut dosyası gibi bir şey için bir periodiclly yürütme AJAX çağrı vardır kullanıcıya bir sayfa görüntüler
  5. upload_progress.php inceler "curlprogress-$uploadId.txt" özü ve yapılan yüzdesini verir.
  6. curl durum dosyaları temizlemek için bir yol bulun. Muhtemelen yerine 3. adımda curl, doğrudan yürütme yerine, curl çağıran bir bash betiği çalıştırmak ve otomatik olarak o bitmiştir dosya silme, çıktısı yönlendirir. Ilerleme% 100 ise Veya, sadece upload_progress.php "curlprogress-$uploadId.txt" dosyasını silmek var.

Bu easy olmadığını unutmayın. Ben kod sağlayacak ama biz burada gelişme saatlerce konuşuyor ;-)