Heim > php教程 > PHP开发 > Verfolgen Sie den Upload-Fortschritt mit PHP und JavaScript

Verfolgen Sie den Upload-Fortschritt mit PHP und JavaScript

高洛峰
Freigeben: 2016-11-28 15:45:08
Original
1232 Leute haben es durchsucht

Ein Problem, das Webentwickler seit vielen Jahren beschäftigt, ist das Hinzufügen von Echtzeitinformationen zu ihren Anwendungen, wie zum Beispiel Fortschrittsbalken für den Datei-Upload. Benutzer sind ungeduldig, sie möchten nicht herumsitzen und warten, während der Browser etwas tut, und sich fragen, ob er eingefroren ist oder ob die Verbindung langsam ist. Bietet eine Fortschrittsanzeige, um dem Benutzer nützliche Informationen bereitzustellen und ihn genau darüber zu informieren, was gerade vor sich geht.

Auf den ersten Blick könnten Sie denken, dass dies leicht zu erreichen wäre, indem Sie zunächst die Größe der Datei vom Computer des Benutzers ermitteln und dann einige einfache Berechnungen für das Verzeichnis durchführen, in das die Datei hochgeladen wird. Abgeschlossen auf dem Server. Was den zweiten Gedanken betrifft, werden Sie feststellen, dass die Dinge nicht so einfach sind, wie Sie denken.

JavaScript kann auf den Namen, den Typ und sogar die Breite und Höhe nativer Bilder einer Datei zugreifen, aber erst mit HTML5 konnte es auf die Größe einer Datei zugreifen. Leider ist HTML5 noch ein unvollendeter Standard und wird nicht von allen Browsern einheitlich unterstützt. Eine andere Lösung besteht darin, sich auf die Installation eines Flash-, Java- oder ActiveX-Plugins zu verlassen, nein danke, das überlasse ich. Eine andere Lösung besteht darin, die optionale PHP-Caching-Erweiterung zu installieren. Abhängig von Ihrer Hosting-Umgebung ist diese jedoch möglicherweise nicht verfügbar, was für eine so kleine Aufgabe wie diese etwas übertrieben erscheint.

Es scheint, als wären alle Optionen voller Ärgernisse und die Mission bereitet schnell Kopfschmerzen. Aber um es mit den Worten von Yoda zu sagen: „Es gibt kein...es gibt eins.“

Einer der vielen Gründe, warum ich PHP liebe, ist, dass es scheinbar schwierige Aufgaben sehr einfach macht. In PHP 5.4 haben sie session.upload_progress erneut mit einem neuen Satz an Konfigurationsoptionen durchgeführt.

In diesem Artikel zeige ich Ihnen, wie Sie mit dieser Funktionalität einen einfachen Upload-Fortschrittsbalken ohne externe Bibliotheken oder Browserabhängigkeiten erstellen können. Ich bespreche zunächst, wie es funktioniert, und führe Sie dann durch die Erstellung der vier Dateien, die zum Abschließen der Aufgabe erforderlich sind (ein Upload-Formular, etwas JavaScript, ein wenig CSS und eine Datei, die den Ladestatus zurückgibt).

Meeting-Upload-Fortschritt

Zusätzlich zu den üblichen Anforderungen, um das Hochladen von Dateien zu ermöglichen, gibt es zwei weitere, um den Fortschritt zu verfolgen. Die Anweisung „session.upload_progress.enabled“ muss aktiviert sein und im Webformular muss ein ausgeblendetes Feld mit dem durch die Anweisung „session.upload_progress.name“ angegebenen Namen vorhanden sein. Wenn session.upload_progress.enabled wahr ist (wie es standardmäßig in PHP 5.4 und vermutlich später der Fall ist) und $_POST[session.upload_progress.name ] in $_SESSION superglobal in Bezug auf Dateiübertragungs-Uploads verfügbar ist, Array.

Das von print_r() ausgegebene Array $_SESSION sieht während einer Dateiübertragung etwa wie folgt aus:

Array ( [upload_progress_myForm] => Array ( [START_TIME] => 1323733740 [CONTENT_LENGTH] = > 721127769 [bytes_processed] => 263178326 [Complete] => [File] =>Array ( [FIELD_NAME] => USERFILE [Name] => -Desktop i386.iso [Wert von tmp_name] => [Error] => 0 [Complete] => [START_TIME] => 1323733740 [bytes_processed] => 263178026 ) ) ) ) )

Wann Wenn Sie lokal oder in einem schnellen Netzwerk entwickeln und kleine Dateien hochladen, können Sie den Fortschritt nicht visuell beobachten, da die Übertragung so schnell erfolgt. In diesem Fall sollten Sie versuchen, große Dateien zu übertragen. Bitte stellen Sie sicher, dass Sie Ihre php.ini-Datei so einrichten, dass größere Uploads zulässig sind, insbesondere die Anweisungen post_max_size und upload_max_filesize, und bestätigen Sie dann, dass es sich um vernünftige Werte handelt, wenn Sie in die Produktion gehen.

Erstellen eines Formulars

Die erste Datei, die ich behandeln werde, ist das Upload-Formular. Um die Sache so einfach wie möglich zu halten, wird dieses Beispiel so veröffentlicht, dass es jeweils nur einen Datei-Upload verarbeiten kann. Außerdem würde ich mir nicht die Mühe machen, die Datei nach dem Hochladen zu speichern.

Hier ist der Code für form.php:

<?PHP
如果($ _SERVER [ “REQUEST_METHOD” ] == “POST” &&!空($ _FILES [ “userfile的” ])){
    / / move_uploaded_file()以
}
?>
<HTML>
 <HEAD>
  <TITLE>文件上传进度条</ TITLE>
  <链接相对= “样式表” 类型= “文/ CSS” HREF = “style.css文件” >
 </ HEAD>
 <BODY>
  <分区编号= “bar_blank” >
   <分区编号= “bar_color” > </ DIV>
  </ DIV>
  <分区编号= “状态” > </ DIV>
  <形式的行动= “<PHP的回声$ _SERVER?[” PHP_SELF “];?>” 方法= “POST”
   ID = “myForm的” 是enctype = “多部分/窗体的数据” 目标= “hidden_iframe” >
   <输入类型= “隐藏” 值= “myForm的”
    名称= “<?PHP的回声ini_get(” session.upload_progress.name ?“);>” >
   <输入类型= “文件” 名称= “USERFILE” > <BR>
   <输入类型= “提交” 值= “开始上传” >
  </ FORM>
  <iframe的ID = “hidden_iframe” 名称= “hidden_iframe” SRC = “关于:空白” > </ IFRAME>
  <脚本类型= “文/ JavaScript的” SRC = “的script.js” > </ SCRIPT>
 </ BODY>
</ HTML>
Nach dem Login kopieren

In diesem Beispiel wurde der Code zum tatsächlichen Verarbeiten der Datei weggelassen. Lassen Sie die Dinge einfach werden. Wenn Sie daran interessiert sind, wie ein solcher Code aussehen sollte, lesen Sie den Artikel Datei-Upload mit PHP von Timothy Boronczyk. Nach dem Header-Abschnitt

, der den Titel der Seite bereitstellt und das Stylesheet enthält, finden Sie eine kleine Sammlung von div-Elementen. Der DIV mit der ID „bar_blank“ ist der Fortschrittsbalken des Containers. Das Div mit der ID „bar_color“ aktualisiert den Datei-Upload-Fortschritt dynamisch. Das Div „Status“ zeigt den hochgeladenen Prozentwert an.

该窗体设置为提交给同一个URL,并将其目标属性指向一个隐藏的iframe元素。 提交表单到一个隐藏的框架可以让你保持访问者在同一页上,而工作在后台正在做。 其实,这是一种常见的做法做“的Ajax文件上传”的时候,因为它是不可能直接发送使用JavaScript的一个文件的内容XmlHttpRequest对象。

在表格中,特殊的隐藏字段需要填充$_SESSION数组,接着出现一个文件上传输入和提交按钮。 提交表单将触发一个名为JavaScript函数startUpload()将被包含的JavaScript文件中定义。

在页面的底部是隐藏的框架,其形式将发布和进口script.js文件。

添加一些样式

下一个文件, style.css ,是相当直接的。 我定义的进度条容器的大小并给予它一个1px的黑色边框,进度条的颜色,因为它的加载,无论是IFRAME和进度条是隐藏的。

#bar_blank {
  边界:固体1px的#000 ;
  高度:20像素;
  宽度:300像素;
}
 
#bar_color {
  背景色:#006666 ;
  高度:20像素;
  宽度:0PX ;
}
 
#bar_blank,#hidden_iframe {
  显示:无;
}
Nach dem Login kopieren

客户端功能

该script.js文件是最大的组文件。 它包含六大功能,我将在下面讨论。 很多人喜欢用jQuery来提供一些功能在这里,你当然可以这样做,如果你愿意的话,但我个人更喜欢老派的做法。 类似于如何日本人放在手工制作的货物价值较高的,我只是觉得更热衷于代码,如果是我自己。

功能toggleBarVisibility(){
    变种E =的document.getElementById(“bar_blank” );
    e.style.display =(e.style.display == “块” ?) “ 无” :“块” ;
}
 
功能createRequestObject(){
    变种的http;
    如果(navigator.appName == “Microsoft Internet Explorer的” ){
        HTTP = 新的ActiveXObject(“Microsoft.XMLHTTP” );
    }
    否则{
        HTTP = 新的XMLHttpRequest();
    }
    返回的http;
}
 
功能sendRequest将(){
    变种的http = createRequestObject();
    http.open(“GET” ,“progress.php” );
    http.onreadystatechange = 函数(){用handleResponse(HTTP);};
    http.send(空);
}
 
功能用handleResponse(HTTP){
    无功响应;
    如果(http.readyState == 4){
        响应= http.responseText;
        的document.getElementById(“bar_color” 。)共0则回应+ “%” ;
        的document.getElementById( “ 地位” 。)的innerHTML =响应+ “%” ;
 
        如果(响应<100){
            的setTimeout(“sendRequest将()” ,1000);
        }
        否则{
            toggleBarVisibility();
            的document.getElementById( “ 地位” 。)的innerHTML = “Done(完成)。” ;
        }
    }
}
 
功能startUpload(){
    toggleBarVisibility();
    的setTimeout(“sendRequest将()” ,1000);
}
 
(函数(){
    的document.getElementById(“myForm会” )的onsubmit = startUpload;
})();
Nach dem Login kopieren

该toggleBarVisibility()函数上的“bar_blank”的div根据需要显示或隐藏进度条设置合适的样式。 最初,它开始时隐藏,但会一次上传开始出现,然后再次隐藏当上载完成。

该createRequestObject()函数创建一个XMLHttpRequest或ActiveXObject根据用户的浏览器对象。 这可能是该功能大多数人都期待的jQuery或其他一些JavaScript框架来提供。

该sendRequest()函数请求progress.php文件与一个GET请求,然后调用handleResponse()函数来处理返回的数据。

该handleResponse()函数处理从响应progress.php这将是依赖于文件上传进度多项1-100之间。 我也更新了“状态”的div适当的值。 如果电流的百分比低于100然后调用JavaScript的原生setTimeout()函数来1秒后发送的更新另一个请求(你可能需要调整该值如适用),否则我再次隐藏进度条和状态设置为“完成”。

该startUpload()函数使得载栏可见,并发送一个更新请求的1秒的延迟。 这个小的延迟是必要的,为了给上传时间才能启动。

最后一个功能是一个自执行的匿名函数,它注册startUpload()与表单的提交事件。

实时进展

带来一切融合在一起的最后一个文件是progress.php文件:

<?PHP
在session_start();
 
美元的关键= ini_get (“session.upload_progress.prefix” )。“myForm的” ;
如果(!空($ _SESSION [ $关键])){
    $电流= $ _SESSION [ $关键] [ “bytes_processed” ];
    共$ = $ _SESSION [ $关键] [ “CONTENT_LENGTH” ];
    回声$电流< $总?CEIL ($电流/ $总量* 100):100;
}
否则{
    回声100;
}
Nach dem Login kopieren

   

该脚本执行上传输的字节数目前在总文件大小,再乘以100,并四舍五入到给一个百分比分成一些简单的数学。

有关传输的信息,关键在于有一套与session.upload_progress.prefix指令的值的串联和隐藏session.upload_progress.name字段的值。 因为我的形式通过了“myForm会”,会议的重点是与确定ini_get("session.upload_progress.prefix") . "myForm"ini_get("session.upload_progress.prefix") . "myForm" 。

下面是在行动进度条的截图:

Verfolgen Sie den Upload-Fortschritt mit PHP und JavaScript

微调行为

PHP提供了一些额外的指令来帮助微调会话上传的行为,你应该知道的。 例如,session.upload_progress.cleanup ,这是默认设置为1,清理后,立即上传已经完成了额外的会话数据。 你必须要小心,以避免潜在的竞争条件。

再看看在代码progress.php ,你会发现,我检查,看看是否$_SESSION[$key]为空或不是,然后再继续。我的JavaScript函数火了每一秒,只要结果从返回progress.php小于100。 如果session.upload_progress.cleanup已启用,我的脚本获取99%的上传和1/2-second后上传完成后,$_SESSION[$key]不会为下一个检查存在的。 如果我不考虑到这一点,然后我的JavaScript函数可能保持射击,上传完成之后也是如此。

Die anderen beiden Anweisungen sind session.upload_progress.freq und session.upload_progress.min_freq, die bestimmen, wie oft die Sitzung aktualisiert werden soll. Der Wert der Häufigkeit kann entweder in Byte (d. h. 100) oder als Prozentsatz der Gesamtzahl der Bytes (d. h. 2 %) angegeben werden. Der Wert von min_freq wird in Sekunden angegeben und stellt die Mindestanzahl von Sekunden zwischen Aktualisierungen dar. Wenn min_freq so eingestellt ist, dass es alle 1 Sekunde aktualisiert, wäre es für JavaScript natürlich sinnlos, alle 100 Millisekunden eine Überprüfung durchzuführen.

Zusammenfassung

Sie sollten nun genau wissen, wie Sie mit der Funktion zum Hochladen von Sitzungen einen Fortschrittsbalken für das Hochladen von Dateien erstellen. Ich empfehle Ihnen, in Zukunft das Hochladen mehrerer Dateien zu versuchen und dabei die Möglichkeit zu geben, einen laufenden Upload abzubrechen, indem Sie $_SESSION[$key]["cancel_upload"] oder andere Ideen verwenden, die Ihnen in den Sinn kommen.


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Aktuelle Ausgaben
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage