>  기사  >  백엔드 개발  >  세션 및 Javascript를 사용하여 PHP에서 파일 업로드 진행률 표시줄 기능을 구현하는 방법을 알아보세요.

세션 및 Javascript를 사용하여 PHP에서 파일 업로드 진행률 표시줄 기능을 구현하는 방법을 알아보세요.

coldplay.xixi
coldplay.xixi앞으로
2020-07-27 16:51:012489검색

세션 및 Javascript를 사용하여 PHP에서 파일 업로드 진행률 표시줄 기능을 구현하는 방법을 알아보세요.

웹 애플리케이션에서는 파일 업로드 기능을 제공해야 하는 경우가 많습니다. 일반적인 시나리오에는 사용자 아바타 업로드, 앨범 사진 업로드 등이 포함됩니다. 업로드할 파일이 상대적으로 큰 경우 업로드 진행 상황을 보여주는 진행 표시줄을 제공해야 합니다.

PHP 5.4 이전에는 이러한 진행 표시줄을 구현하는 것이 쉽지 않았습니다. 크게 세 가지 방법이 있었습니다.

  • Flash, Java, ActiveX 사용

  • PHP의 APC 확장 사용

  • HTML5의 파일 API 사용

관련 학습 권장사항: 초보부터 숙련까지 PHP 프로그래밍

첫 번째 방법은 제3자 브라우저 플러그인을 사용하는데, 이는 충분히 다용도가 아니며 쉽게 보안 위험을 초래할 수 있습니다. 그러나 Flash의 광범위한 사용으로 인해 여전히 Flash를 솔루션으로 사용하는 웹사이트가 많이 있습니다.

두 번째 방법의 단점은 PHP의 APC 확장 라이브러리를 설치해야 하고 사용자가 서버 측 구성을 제어해야 한다는 것입니다. 또한 업로드 진행률 표시줄을 구현하기 위해 APC를 설치했다면 분명히 약간 과잉입니다.

세 번째 방법은 가장 이상적인 방법이어야 하며 서버 측 지원이 필요하지 않으며 브라우저 측에서만 Javascript를 사용합니다. 그러나 HTML5 표준이 아직 확립되지 않았고, 브라우저 제조사마다 지원하는 방식이 다르기 때문에 이 방법은 아직까지 대중화되기에는 어렵습니다.

PHP 5.4에 도입된 세션 기반 업로드 진행 모니터링 기능(session.upload_progress)은 서버 측 업로드 진행 모니터링 솔루션을 제공합니다. PHP 5.4로 업그레이드한 후에는 APC 확장을 설치할 필요가 없습니다. 기본 PHP 및 프런트엔드 Javascript만 사용하여 업로드 진행률 표시줄을 구현할 수 있습니다.

이제 PHP 5.4의 새로운 session.upload_progress 기능을 자세히 소개하겠습니다.

원칙 소개

브라우저가 서버에 파일을 업로드하면 PHP는 파일 업로드에 대한 자세한 정보(예: 업로드 시간, 업로드 진행률 등)를 세션에 저장합니다. 그런 다음 업로드가 진행됨에 따라 세션의 정보가 주기적으로 업데이트됩니다. 이러한 방식으로 브라우저는 Ajax를 사용하여 주기적으로 서버 측 스크립트를 요청할 수 있으며 스크립트는 세션에서 진행률 정보를 반환합니다. 브라우저 측 Javascript는 이 정보를 기반으로 진행률 표시줄을 표시/업데이트할 수 있습니다.

그럼 파일 업로드 정보는 어떻게 저장되나요? 어떻게 접근하나요? 아래에서 자세히 설명드리겠습니다.

PHP 5.4에는 일부 구성 항목이 도입되었습니다(php.ini에 설정됨)

코드는 다음과 같습니다.

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"

그 중 활성화는 기본적으로 켜져 있는 upload_progress 기능을 켤지 여부를 제어합니다. 이후 파일 업로드 요청 시 세션 관련 정보 삭제 여부가 기본적으로 활성화됩니다.

접두사 및 이름은 세션에서 진행 정보가 저장되는 변수 이름/키 이름을 설정하는 데 사용됩니다. 이 두 항목의 자세한 사용법은 아래를 참조하세요.

freq 및 min_freq는 서버 측에서 진행 정보 업데이트 빈도를 설정하는 데 사용됩니다. 이 두 항목을 적절하게 설정하면 서버의 부하를 줄일 수 있습니다.

파일 업로드 양식에서 이 업로드에 대한 식별자를 설정하고 이 식별자를 사용하여 후속 프로세스에서 진행 정보를 참조해야 합니다. 특히, 업로드 양식에는 숨겨진 입력이 있어야 하며, 해당 이름 속성은 php.ini의 session.upload_progress.name 값이며, 해당 값은 사용자가 정의한 식별자입니다.

코드는 다음과 같습니다.

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

파일 업로드 양식을 받은 후 PHP는 $_SESSION 변수에 새 키를 생성합니다. 키 이름은 사용자 정의 식별자와 연결된 session.upload_progress.prefix 값입니다. 위와 같이 얻은 문자열을 얻을 수 있습니다.

코드는 다음과 같습니다.

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

$_SESSION[$key]이 변수의 구조는 다음과 같습니다.$_SESSION[$key]这个变量的结构是这样的:

代码如下:

$_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( ... ),
 )
);

这样,我们就可以使用其中的 content_length 和 bytes_processed 两项来得到进度百分比。

程序示例

原理介绍完了,下面我们来完整的实现一个基于PHP和Javascript的文件上传进度条。

上传表单

首先,来编写我们的上传表单页面 index.php,代码如下:

代码如下:

<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>

注意表单中的session.upload_progress.name隐藏项,值设置为了test。表单中仅有一个文件上传input,如果需要,你可以添加多个。

这里需要特别注意一下表单的target属性,这里设置指向了一个当前页面中的iframe。这一点很关键,通过设置target属性,让表单提交后的页面显示在iframe中,从而避免当前的页面跳转。因为我们还得在当前页面显示进度条呢。

#progress

코드는 다음과 같습니다. 다음과 같습니다:

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;]}");
}
?>

이런 방식으로 content_length와 bytes_processed 두 항목을 사용하여 진행률을 얻을 수 있습니다.

프로그램 예제


이제 원리가 소개되었으니 PHP와 Javascript 기반의 파일 업로드 진행 표시줄을 완벽하게 구현해 보겠습니다.

🎜🎜업로드 양식🎜🎜🎜먼저 업로드 양식 페이지 index.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.upload_progress.name에 주의하세요. form이고 값은 test로 설정됩니다. 양식에는 파일 업로드 입력이 하나만 있으며 필요한 경우 여러 개를 추가할 수 있습니다. 🎜🎜양식의 대상 속성에 특별한 주의가 필요합니다. 여기 설정은 현재 페이지의 iframe을 가리킵니다. 이는 target 속성을 설정함으로써 양식이 제출된 후의 페이지가 iframe에 표시되므로 현재 페이지 이동을 방지하는 데 중요합니다. 현재 페이지에 진행률 표시줄을 표시해야 하기 때문입니다. 🎜🎜#progress 이 p는 진행률 표시줄을 표시하는 데 사용됩니다. 🎜🎜참고: index.php 시작 부분에 session_start()를 추가하는 것을 잊지 마세요. 🎜🎜🎜업로드된 파일 처리🎜🎜🎜양식의 작업은 upload.php를 가리킵니다. upload.php에서 업로드된 파일을 처리하고 현재 디렉터리로 전송합니다. 여기에는 일반적인 업로드 처리와 차이가 없습니다. 🎜🎜

 代码如下:

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() 则不能保证这一点,有可能导致进度条出现'不进反退'。

위 내용은 세션 및 Javascript를 사용하여 PHP에서 파일 업로드 진행률 표시줄 기능을 구현하는 방법을 알아보세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 jb51.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제