Prześlij pasek postępu w PHP

82

Czy ktoś wie, jak uzyskać pasek postępu do przesyłania w php? Próbuję napisać kod do programu do przesyłania albumów ze zdjęciami. Chciałbym, aby podczas przesyłania zdjęć był wyświetlany pasek postępu.

Jestem dość nowy w php, więc nie wiem o nim wszystkiego.

Josh Curren
źródło

Odpowiedzi:

70

To zdecydowanie (po wielu godzinach wyszukiwania w Google i wypróbowywania skryptów) najłatwiejszy w konfiguracji i najładniejszy program do przesyłania, jaki znalazłem

https://github.com/FineUploader/fine-uploader

Nie wymaga APC ani żadnych innych zewnętrznych bibliotek PHP, mogę uzyskać informacje o postępie pliku na współdzielonym hoście i twierdzi, że obsługuje przeciąganie i upuszczanie html5 (osobiście niesprawdzone) oraz przesyłanie wielu plików.

Jesse
źródło
11
Uważam, że zamiast tego będziesz chciał użyć tego: github.com/valums/file-uploader - ten sam autor.
Michael Reed
6
Zobacz też Postęp przesyłania sesji, który oferuje PHP, aby uzyskać postęp przesyłania plików po wyjęciu z pudełka.
hakre
7
@jpeskin to trochę niesprawiedliwe dla programisty. tylko dlatego, że „oferujesz im zapłatę”, nie zobowiązuje ich do wykonywania dla Ciebie pracy jak zwykła prostytutka. jeśli nie możesz dowiedzieć się, jak to debugować, nie chodziłbym w kółko, wskazując palcami na nikogo innego niż siebie - oprogramowanie, które znajdujesz w Internecie, jest dostarczane w stanie, w jakim jest, więc nie chodź dookoła i nie atakuj ludzi, którzy są nic więcej niż próba pomocy.
sucitivel
3
@sucitivel Aby być bardziej szczegółowym: zaproponowałem, że zapłacę, a on zgodził się, potem zadaliśmy sobie trud, aby udokumentować wszystkie napotkane błędy, a potem przestał odpowiadać na wszystkie e-maile nadal był zainteresowany pracą). Nie uważam nikogo za zobowiązanego do pracy za pieniądze. To był jedynie punkt danych obserwacyjnych dla innych, którzy chcieliby wiedzieć o dostępności dewelopera i / lub jego zainteresowaniu pracą na zlecenie. Projekt był rozwidlony, więc nie tylko ja wyczułem, że deweloper traci zainteresowanie utrzymaniem.
jpeskin
5
blueimp.github.com/jQuery-File-Upload - to działa naprawdę dobrze. Przynajmniej mi się podoba, ponieważ nie jest w tyle pod Ubuntu =)
BeRocket
13

Jeśli masz zainstalowany APC , ma on haczyk wywołania zwrotnego dla postępu przesyłania.

Rasmus Lerdorf (twórca PHP) ma próbkę tego za pomocą YUI (och, a oto źródło PHP ).

Zobacz dokumentację tutaj .

Władca
źródło
Ani to samo, ani linki źródłowe php już nie działają. Czy masz link do alt?
supersan
@supersan Ta odpowiedź jest bardzo nieaktualna. APC nie żyje, a interfejs API przesyłania sesji jest teraz oddzielną rzeczą . Nie działa również, jeśli serwer używa FastCGI ... co obecnie większość robi ze względów bezpieczeństwa.
Powerlord
12

Przykro mi to mówić, że według mojej najlepszej wiedzy czysty pasek postępu wysyłania PHP, a nawet pasek postępu wysyłania PHP / Javascript nie jest możliwy ze względu na sposób działania PHP. Najlepiej jest użyć jakiejś formy programu do przesyłania Flash.

AFAIK Dzieje się tak, ponieważ twój skrypt nie jest wykonywany, dopóki nie zostaną wypełnione wszystkie superglobalne, w tym $ _FILES. W momencie wywołania skryptu PHP plik jest w pełni załadowany.

EDYCJA: To już nie jest prawda. To było w 2010 roku.

Macha
źródło
13
Dlaczego trzy głosy przeciw? To prawda i są całkowicie nieuzasadnione. Odważę się pokazać mi pasek postępu, który działa na natywnym PHP i nie potrzebuje do pracy dodatkowych rozszerzeń / modułów Apache / skryptów perl / innych rzeczy.
Pekka,
1
Cóż, jest rok 2011, a teraz jest to możliwe dzięki HTML5. Zobacz pierwszą odpowiedź tutaj: stackoverflow.com/questions/76976/…
Zarel
10
Cóż, jest rok 2012, a przesyłanie plików w HTML5 przez XMLHttpRequest nadal nie jest dostępne we wszystkich głównych przeglądarkach.
Damien B
3
@Pekka 웃 To nieprawda. Jeśli masz zainstalowany APC (a powinieneś), możesz to zrobić całkowicie natywnie w PHP, bez javascript.
Ariel,
2
@Pekka 웃 Nie wspominając o przesyłaniu przy użyciu informacji o sesji w PHP> = 5.4.
Wookie88
8

Jeden sposób w PHP (5.2+) i bez Flasha, który działał dobrze dla mnie:

Najpierw przeczytaj ten post wyjaśniający, jak uruchomić i uruchomić rozszerzenie „uploadprogress”.

Następnie na stronie zawierającej formularz, z którego przesyłasz pliki, utwórz następującą ramkę iframe:

<iframe id="progress_iframe" src="" style="display:none;" scrolling="no" frameborder="0"></iframe>

Następnie dodaj ten kod do przycisku „Prześlij”:

onclick="function set() { f=document.getElementById('progress_iframe'); f.style.display='block'; f.src='uploadprogress.php?id=<?=$upload_id?>';} setTimeout(set);"

Teraz masz ukrytą ramkę iframe w swoim formularzu, która będzie widoczna i pokaże zawartość uploadprogress.php po kliknięciu "Prześlij", aby rozpocząć przesyłanie plików. $ upload_id musi być tym samym, którego używasz jako wartość ukrytego pola „UPLOAD_IDENTIFIER” w formularzu.

Sam plik uploadprogress.php wygląda mniej więcej tak (napraw i dostosuj do swoich potrzeb):

<html>
<head>
<META HTTP-EQUIV='REFRESH' CONTENT='1;URL=?id=<?=$_GET['id']?>'>
</head>
<body>
Upload progress:<br />
<?php
    if(!$_GET['id']) die;
    $info = uploadprogress_get_info($_GET['id']);
    $kbytes_total = round($info['bytes_total'] / 1024);
    $kbytes_uploaded = round($info['bytes_uploaded'] / 1024);
    echo $kbytes_uploaded.'/'.$kbytes_total.' KB';
?>
</body>
</html>

Pamiętaj, że odświeża się co sekundę. Z pewnością możesz dodać tutaj ładny wizualny pasek postępu (jak 2 zagnieżdżone <div> w różnych kolorach), jeśli chcesz. Element iframe z postępem wczytywania działa naturalnie tylko wtedy, gdy trwa przesyłanie i kończy swój widoczny okres po przesłaniu formularza i ponownym załadowaniu przeglądarki do następnej strony.

IvarsK
źródło
Jak możesz przesłać plik bez $ _FILES w php
4

Implementacja paska postępu przesyłania jest łatwa i nie wymaga żadnego dodatkowego rozszerzenia PHP, JavaScript ani Flash. Ale potrzebujesz PHP 5.4 i nowszego .

Musisz włączyć zbieranie informacji o postępie przesyłania, ustawiając dyrektywę session.upload_progress.enabledna Onin php.ini.

Następnie dodaj ukryte dane wejściowe do formularza przesyłania HTML, tuż przed innymi danymi wejściowymi pliku. Atrybut HTML nametego ukrytego wejścia powinien być taki sam jak wartość dyrektywy session.upload_progress.namez php.ini(ewentualnie poprzedzona session.upload_progress.prefix). valueAtrybut jest do ciebie, będzie on używany jako część klucza sesji.

Formularz HTML mógłby wyglądać następująco:

<form action="upload.php" method="POST" enctype="multipart/form-data">
   <input type="hidden" name="<?php echo ini_get('session.upload_progress.prefix').ini_get('session.upload_progress.name'); ?>" value="myupload" />
   <input type="file" name="file1" />
   <input type="submit" />
</form>

Kiedy wysyłasz ten formularz, PHP powinno utworzyć nowy klucz w $_SESSIONstrukturze superglobalnej, który zostanie wypełniony informacjami o statusie wysyłania. Klucz jest konkatenowany namei zawiera valueukryte dane wejściowe.

W PHP możesz spojrzeć na wypełnione informacje o przesyłaniu:

var_dump($_SESSION[
    ini_get('session.upload_progress.prefix')
   .ini_get('session.upload_progress.name')
   .'_myupload'
]);

Wynik będzie wyglądał podobnie do następującego:

$_SESSION["upload_progress_myupload"] = array(
  "start_time" => 1234567890,   // The request time
  "content_length" => 57343257, // POST content length
  "bytes_processed" => 54321,   // Amount of bytes received and processed
  "done" => false,              // true when the POST handler has finished, successfully or not
  "files" => array(
    0 => array(
      "field_name" => "file1",    // Name of the <input /> field
      // The following 3 elements equals those in $_FILES
      "name" => "filename.ext",
      "tmp_name" => "/tmp/phpxxxxxx",
      "error" => 0,
      "done" => false,            // True when the POST handler has finished handling this file
      "start_time" => 1234567890, // When this file has started to be processed
      "bytes_processed" => 54321, // Number of bytes received and processed for this file
    )
  )
);

Są tam wszystkie informacje potrzebne do stworzenia paska postępu - masz informacje, czy przesyłanie nadal trwa, informacje, ile bajtów zostanie przesłanych w sumie i ile bajtów zostało już przesłanych.

Aby przedstawić użytkownikowi postęp wczytywania, napisz inny skrypt PHP niż przesyłający, który będzie sprawdzał tylko informacje o wysyłaniu w sesji i zwróci je na przykład w formacie JSON. Ten skrypt może być wywoływany okresowo, na przykład co sekundę, przy użyciu AJAX i informacji prezentowanych użytkownikowi.

Jesteś nawet w stanie zrezygnować z przesyłania przez ustawienie $_SESSION[$key]['cancel_upload']TO true.

Szczegółowe informacje, dodatkowe ustawienia i komentarze użytkownika znajdują się w podręczniku PHP .

David Ferenczy Rogožan
źródło
2

Inny pełny JS do przesyłania: http://developers.sirika.com/mfu/

  • Jest wolny (licencja BSD)
  • Umiędzynarodowienie
  • zgodność z różnymi przeglądarkami
  • masz wybór, czy zainstalować APC, czy nie (niedokończony pasek postępu VS określony pasek postępu)
  • Możliwość dostosowania wyglądu, ponieważ wykorzystuje mechanizm szablonów dojo. Możesz dodać swoją klasę / identyfikatory w szablonach te zgodnie z twoim css

baw się dobrze

Valdelievre
źródło
2

HTML5 wprowadzono API przesyłania plików , który pozwala na monitorowanie postępów wysyłania plików, ale dla starszych przeglądarek nie plupload ramy że wykonany specjalnie do wysyłania plików monitora i informacje otrzymano około nich. ponadto ma wiele wywołań zwrotnych, dzięki czemu może działać we wszystkich przeglądarkach

mistrz
źródło
2

Gears i HTML5 mają zdarzenie postępu w HttpRequestobiekcie do przesyłania pliku przez AJAX.

http://developer.mozilla.org/en/Using_files_from_web_applications

Twoje inne opcje, na które odpowiedzieli już inni, to:

  1. Program do przesyłania oparty na technologii Flash.
  2. Program do przesyłania oparty na języku Java.
  3. Drugie żądanie w stylu komety do serwera WWW lub skryptu, aby zgłosić rozmiar otrzymanych danych. Niektóre serwery WWW, takie jak Lighttpd, udostępniają moduły umożliwiające wykonanie tej czynności w trakcie, aby zaoszczędzić na kosztach wywołania zewnętrznego skryptu lub procesu.

Z technicznego punktu widzenia istnieje czwarta opcja, podobna do przesyłania do YouTube, w przypadku Gears lub HTML5 można użyć obiektów blob do podzielenia pliku na małe fragmenty i przesłania każdego z nich osobno. Po ukończeniu każdej porcji możesz zaktualizować stan postępu.

Steve-o
źródło
1

Aby utworzyć pasek postępu, musisz użyć Javascript. Proste wyszukiwanie w Google doprowadziło mnie do tego artykułu: WebAppers Simple Javascript Progress Bar with CSS .

Widżet paska postępu przesyłania plików Dojo to kolejna opcja korzystająca ze środowiska Dojo Javascript.

EDYCJA: Zakładając, że przesyłasz dużą liczbę obrazów (takich jak album ze zdjęciami) i wysyłasz je do skryptu PHP, możesz użyć javascript, aby odczytać wyniki z postu i zaktualizować pasek postępu w oparciu o liczbę przesłanych obrazów / łączna liczba obrazów. Ma to efekt uboczny aktualizacji tylko po zakończeniu każdego postu. Sprawdź tutaj, aby uzyskać informacje na temat publikowania za pomocą JS.

Joey Robert
źródło
6
-1 Pasek postępu Javascript jest ładny, ale o ile widzę, nie ma nic wspólnego z przesyłaniem plików. A pasek postępu ładowania Dojo nie zapewnia żadnego interfejsu dla PHP. Jeśli się mylę, oczywiście popraw mnie.
Pekka,
1

Można zrobić pasek postępu php / ajax. (Sprawdź bibliotekę Html_Ajax w kolorze gruszkowym). Jednak wymaga to zainstalowania niestandardowego modułu w php.

Inne metody wymagają użycia ramki iframe, przez którą php sprawdza, jaka część pliku została przesłana. Jednak ta ukryta ramka iframe może być blokowana przez niektóre dodatki przeglądarki, ponieważ ukryte ramki iframe są często używane do wysyłania złośliwych danych do komputera użytkownika.

Jeśli nie masz kontroli nad swoim serwerem, najlepiej jest użyć jakiegoś rodzaju paska postępu flash.

Ali Lown
źródło
Niektóre dodatki mogą blokować ramki iframe, ale przeglądarki? Czy możesz podać przykład?
ya 23
Wyszukiwanie w Google terminów „przesyłanie pliku PHP w AJAX” zwraca 4 z 5 najlepszych wyników, wszystkie przy użyciu ramek iframe (nie wiadomo, czy piąta tak (strona się nie załaduje)). Spójrz na przykłady na każdej z witryn.
Ali Lown
Rzeczywiście używają ramek iframe, ale nie wspominaj, że w każdym przypadku można je zablokować. A może przegapiłem to?
ya
Przepraszam, źle przeczytałem to, o co próbujesz zapytać, nie, nie mogę podać żadnych przykładów przeglądarek, które bezpośrednio blokują ramki iframe, myślałem o dodatkach, których ludzie używają do ich obsługi, takich jak noscript, który blokuje ramki iframe. Zaktualizowany tekst w poście do wykorzystania w przyszłości.
Ali Lown