Heim >Backend-Entwicklung >PHP-Tutorial >Erfahren Sie, wie Sie mit Session und Javascript die Fortschrittsbalkenfunktion für den Datei-Upload in PHP implementieren

Erfahren Sie, wie Sie mit Session und Javascript die Fortschrittsbalkenfunktion für den Datei-Upload in PHP implementieren

coldplay.xixi
coldplay.xixinach vorne
2020-07-27 16:51:012521Durchsuche

Erfahren Sie, wie Sie mit Session und Javascript die Fortschrittsbalkenfunktion für den Datei-Upload in PHP implementieren

Webanwendungen müssen häufig Funktionen zum Hochladen von Dateien bereitstellen. Typische Szenarien umfassen das Hochladen von Benutzeravataren, das Hochladen von Albumbildern usw. Wenn die hochzuladende Datei relativ groß ist, muss ein Fortschrittsbalken bereitgestellt werden, der den Upload-Fortschritt anzeigt.

Vor PHP 5.4 war es nicht einfach, einen solchen Fortschrittsbalken zu implementieren. Es gab drei Hauptmethoden:

  • Verwenden Sie Flash, Java, ActiveX

  • Verwenden Sie die APC-Erweiterung von PHP

  • Verwenden Sie die Datei-API von HTML5

Verwandte Lernempfehlungen: PHP Programmieren vom Anfänger bis zum Experten

Die erste Methode basiert auf Browser-Plug-Ins von Drittanbietern, was nicht vielseitig genug ist und leicht Sicherheitsrisiken mit sich bringen kann. Aufgrund der weit verbreiteten Verwendung von Flash gibt es jedoch immer noch viele Websites, die Flash als Lösung verwenden.

Der Nachteil der zweiten Methode besteht darin, dass sie die Installation der APC-Erweiterungsbibliothek von PHP erfordert und vom Benutzer die Kontrolle über die serverseitige Konfiguration erfordert. Wenn Sie APC außerdem nur installieren, um einen Upload-Fortschrittsbalken zu implementieren, ist das natürlich etwas übertrieben.

Die dritte Methode sollte die idealste sein. Sie erfordert keine serverseitige Unterstützung und verwendet nur Javascript auf der Browserseite. Da der HTML5-Standard jedoch noch nicht etabliert ist und die Unterstützung verschiedener Browserhersteller unterschiedlich ist, ist die Popularisierung dieser Methode noch schwierig.

Die in PHP 5.4 eingeführte sitzungsbasierte Funktion zur Überwachung des Upload-Fortschritts (session.upload_progress) bietet eine serverseitige Lösung zur Überwachung des Upload-Fortschritts. Nach dem Upgrade auf PHP 5.4 müssen Sie die APC-Erweiterung nicht installieren. Sie können den Upload-Fortschrittsbalken nur mit nativem PHP und Front-End-Javascript implementieren.

Jetzt stellen wir die neue Funktion session.upload_progress von PHP 5.4 im Detail vor.

Prinzipielle Einführung

Wenn der Browser eine Datei auf den Server hochlädt, lädt PHP die detaillierten Informationen der Datei hoch (z. B. Upload-Zeit, Upload-Fortschritt usw.). ) wird in der Sitzung gespeichert. Während der Upload fortschreitet, werden die Informationen in der Sitzung dann regelmäßig aktualisiert. Auf diese Weise kann der Browser Ajax verwenden, um regelmäßig ein serverseitiges Skript anzufordern, und das Skript gibt die Fortschrittsinformationen in der Sitzung zurück. Das browserseitige Javascript kann den Fortschrittsbalken basierend auf diesen Informationen anzeigen/aktualisieren.

Wie werden also die Datei-Upload-Informationen gespeichert? Wie greifen wir darauf zu? Lassen Sie es uns weiter unten im Detail erklären.

PHP 5.4 führte einige Konfigurationselemente ein (in php.ini festgelegt)

Der Code lautet wie folgt:

session.upload_progress.enabled = "1"
session.upload_progress.cleanup = "1"
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.freq = "1%"
session.upload_progress.min_freq = "1"

Unter anderem steuert „enabled“, ob die Funktion „upload_progress“ aktiviert ist Standardmäßig wird durch „Aktivieren“ festgelegt, ob sitzungsbezogene Informationen gelöscht werden sollen, nachdem die Datei-Upload-Anfrage gesendet wurde.

Das Präfix und der Name werden verwendet, um den Variablennamen/Schlüsselnamen festzulegen, in dem die Fortschrittsinformationen in der Sitzung gespeichert werden. Nachfolgend finden Sie eine detaillierte Beschreibung der Verwendung dieser beiden Elemente.

freq und min_freq werden verwendet, um die Häufigkeit der Aktualisierung der Fortschrittsinformationen auf der Serverseite festzulegen. Durch die richtige Einstellung dieser beiden Elemente kann die Belastung des Servers verringert werden.

Im Formular zum Hochladen von Dateien müssen Sie eine Kennung für diesen Upload festlegen und diese Kennung verwenden, um im nachfolgenden Prozess auf Fortschrittsinformationen zu verweisen. Insbesondere muss im Upload-Formular eine versteckte Eingabe vorhanden sein, deren Namensattribut der Wert von session.upload_progress.name in php.ini ist; sein Wert ist ein von Ihnen definierter Bezeichner. Der Code lautet wie folgt:

Der Code lautet wie folgt:

<input type="hidden"
    name="<?php echo ini_get(&#39;session.upload_progress.name&#39;); ?>"
    value="test" />

Nach Erhalt des Datei-Upload-Formulars erstellt PHP einen neuen Schlüssel in der Variablen $_SESSION. Der Schlüsselname ist der Wert von session.upload_progress.prefix und dem oben genannten. Die nach der Verkettung Ihrer benutzerdefinierten Bezeichner erhaltene Zeichenfolge kann wie folgt erhalten werden:

Der Code lautet wie folgt:

$name = ini_get(&#39;session.upload_progress.name&#39;);
$key = ini_get(&#39;session.upload_progress.prefix&#39;) . $_POST[$name];
$_SESSION[$key]; // 这里就是此次文件上传的进度信息了

$_SESSION[$key]Die Struktur dieser Variablen lautet wie folgt:

Der Code lautet wie folgt:

$_SESSION["upload_progress_test"] = array(
 "start_time" => 1234567890,   // 开始时间
 "content_length" => 57343257, // POST请求的总数据长度
 "bytes_processed" => 453489,  // 已收到的数据长度
 "done" => false,              // 请求是否完成 true表示完成,false未完成
 // 单个文件的信息
 "files" => array(
  0 => array( ... ),
  // 同一请求中可包含多个文件
  1 => array( ... ),
 )
);

Auf diese Weise können wir die beiden Elemente content_length und bytes_processed verwenden, um den Fortschrittsprozentsatz zu erhalten.

Programmbeispiel

Nachdem das Prinzip eingeführt wurde, implementieren wir vollständig einen Datei-Upload-Fortschrittsbalken auf Basis von PHP und Javascript.

Formular hochladen

Schreiben wir zunächst unsere Upload-Formularseite index.php. Der Code lautet wie folgt:

Der Code lautet wie folgt:

<form id="upload-form"
    action="upload.php" method="POST" enctype="multipart/form-data"
    style="margin:15px 0" target="hidden_iframe">
        <input type="hidden" name="" value="test" />
        <p><input type="file" name="file1" /></p> 
        <p><input type="submit" value="Upload" /></p>
</form>    
<iframe id="hidden_iframe" name="hidden_iframe" src="about:blank" style="display:none;"></iframe>
<p id="progress" class="progress" style="margin-bottom:15px;display:none;">
        <p class="bar" style="width:0%;"></p>
        <p class="label">0%</p>
</p>

Achten Sie auf das versteckte Element session.upload_progress.name im Formular und der Wert wird auf test gesetzt. Es gibt nur eine Datei-Upload-Eingabe im Formular, Sie können bei Bedarf mehrere hinzufügen.

Besonderes Augenmerk muss hier auf das Zielattribut des Formulars gelegt werden. Die Einstellung verweist hier auf einen Iframe auf der aktuellen Seite. Dies ist von entscheidender Bedeutung, da die Seite nach dem Absenden des Formulars im Iframe angezeigt wird, wodurch ein aktueller Seitensprung vermieden wird. Denn wir müssen den Fortschrittsbalken noch auf der aktuellen Seite anzeigen.

#progress Dieses p wird verwendet, um den Fortschrittsbalken anzuzeigen.

Hinweis: Vergessen Sie nicht, session_start() am Anfang von index.php hinzuzufügen.

Verarbeitung der hochgeladenen Datei

Die Aktion des Formulars zeigt auf upload.php. Wir verarbeiten die hochgeladene Datei in upload.php und übertragen sie in das aktuelle Verzeichnis. Es gibt keinen Unterschied zur üblichen Upload-Verarbeitung.

 代码如下:

if(is_uploaded_file($_FILES[&#39;file1&#39;][&#39;tmp_name&#39;])){
        move_uploaded_file($_FILES[&#39;file1&#39;][&#39;tmp_name&#39;], "./{$_FILES[&#39;file1&#39;][&#39;name&#39;]}");
}
?>

Ajax获取进度信息

这一步是关键,我们需要建立一个 progress.php 文件,用来读取session中的进度信息; 然后我们在 index.php 中增加Javascript代码,向 progress.php 发起Ajax请求,然后根据获得的进度信息更新进度条。

progress.php 的代码如下:

代码如下:

session_start();
$i = ini_get(&#39;session.upload_progress.name&#39;);
$key = ini_get("session.upload_progress.prefix") . $_GET[$i];
if (!empty($_SESSION[$key])) {
        $current = $_SESSION[$key]["bytes_processed"];
        $total = $_SESSION[$key]["content_length"];
        echo $current < $total ? ceil($current / $total * 100) : 100;
}else{
        echo 100;
}
?>

在这里我们获得$_SESSION变量中的进度信息,然后输出一个进度百分比。

在 index.php 中,我们将如下代码添加到页面底部 (为简便,这里使用jQuery):

代码如下:

function fetch_progress(){
        $.get(&#39;progress.php&#39;,{ &#39;&#39; : &#39;test&#39;}, function(data){
                var progress = parseInt(data);
                $(&#39;#progress .label&#39;).html(progress + &#39;%&#39;);
                $(&#39;#progress .bar&#39;).css(&#39;width&#39;, progress + &#39;%&#39;);
                if(progress < 100){
                        setTimeout(&#39;fetch_progress()&#39;, 100);
                }else{
            $(&#39;#progress .label&#39;).html(&#39;完成!&#39;);
        }
        }, &#39;html&#39;);
}
$(&#39;#upload-form&#39;).submit(function(){
        $(&#39;#progress&#39;).show();
        setTimeout(&#39;fetch_progress()&#39;, 100);
});


当#upload-form被提交时,我们把进度条显示出来,然后反复调用 fetch_progress() 获得进度信息,并更新进度条,直到文件上传完毕,显示'完成!'。

注意事项

input标签的位置

name为session.upload_progress.name的input标签一定要放在文件input 73fb0a88f70dfc104fc3e769bdf0b422 的前面。

取消上传

通过设置 $_SESSION[$key]['cancel_upload'] = true 可取消当次上传。但仅能取消正在上传的文件和尚未开始的文件。已经上传成功的文件不会被删除。

setTimeout vs. setInterval

应该通过 setTimeout() 来调用 fetch_progress(),这样可以确保一次请求返回之后才开始下一次请求。如果使用 setInterval() 则不能保证这一点,有可能导致进度条出现'不进反退'。

Das obige ist der detaillierte Inhalt vonErfahren Sie, wie Sie mit Session und Javascript die Fortschrittsbalkenfunktion für den Datei-Upload in PHP implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:jb51.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen