-
Notifications
You must be signed in to change notification settings - Fork 81
Expand file tree
/
Copy pathupload-progress.xml
More file actions
148 lines (143 loc) · 6.61 KB
/
upload-progress.xml
File metadata and controls
148 lines (143 loc) · 6.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 184f3f7bd45643cb80f828d0bb001991ec3a5fad Maintainer: takagi Status: ready -->
<!-- Credits: mumumu -->
<chapter xml:id="session.upload-progress" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>セッションのアップロード状況</title>
<para>
INI オプション
<link linkend="ini.session.upload-progress.enabled">session.upload_progress.enabled</link>
を有効にすると、アップロード中の個々のファイルの進捗状況を PHP で追えるようになります。
この情報は、アップロードのリクエスト自体にとっては特に有用ではありませんが、
ファイルのアップロード中にアプリケーションから別のエンドポイントに POST リクエストを
(<acronym>XHR</acronym> などで) 送って状態をチェックできるようになります。
</para>
<para>
アップロードが進行中かつ、INI オプション
<link linkend="ini.session.upload-progress.name">session.upload_progress.name</link>
に設定されているのと同じ名前の変数が POST されていると、アップロードの状況を
スーパーグローバル <varname>$_SESSION</varname> から取得できます。
PHP 側では、この POST リクエストを検出すると
<varname>$_SESSION</varname> 内の配列に値を格納します。配列のインデックスは、INI オプション
<link linkend="ini.session.upload-progress.prefix">session.upload_progress.prefix</link>
と
<link linkend="ini.session.upload-progress.name">session.upload_progress.name</link>
の値をつなげたものです。つまり、これらの INI 設定を読んで次のようにキーを取得することになります。
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$key = ini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")];
var_dump($_SESSION[$key]);
?>
]]>
</programlisting>
</informalexample>
</para>
<para>
現在進行中のファイルアップロードを<emphasis>キャンセル</emphasis>することもできます。
キャンセルするには、<literal>$_SESSION[$key]["cancel_upload"]</literal> に
&true; を設定します。複数のファイルをひとつのリクエストでアップロードしている場合は、
これでキャンセルできるのは現在進行中のアップロードとそれ以降にアップロードする予定だったファイルだけです。
既にアップロードが完了したファイルは削除されません。この方法でアップロードをキャンセルした場合、
<varname>$_FILES</varname> 配列のキー <literal>error</literal> に
<constant>UPLOAD_ERR_EXTENSION</constant> が設定されます。
</para>
<para>
INI オプション
<link linkend="ini.session.upload-progress.freq">session.upload_progress.freq</link>
および
<link linkend="ini.session.upload-progress.min-freq">session.upload_progress.min_freq</link>
で、アップロードの進捗状況を再計算する頻度を制御します。
これらを適切に設定すれば、進捗状況の取得によるオーバーヘッドはほぼ無視できる程度になります。
</para>
<para>
<example>
<title>情報の例</title>
<para>
アップロード進捗状況の配列の構造を示す例です。
</para>
<programlisting role="html" xml:id="session.upload-progress.example-form">
<![CDATA[
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="submit" />
</form>
]]>
</programlisting>
<para>
セッションに格納されるデータは、このようになります。
</para>
<programlisting role="php" xml:id="session.upload-progress.example-array">
<![CDATA[
<?php
$_SESSION["upload_progress_123"] = array(
"start_time" => 1234567890, // リクエストされた時刻
"content_length" => 57343257, // POST されたコンテンツの長さ
"bytes_processed" => 453489, // 受信して処理済みのバイト数
"done" => false, // POST ハンドラが (正常かどうかにかかわらず) 完了した場合に true
"files" => array(
0 => array(
"field_name" => "file1", // <input/> フィールドの name
// 次の 3 つの要素は $_FILES と同じ内容です
"name" => "foo.avi",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => true, // POST ハンドラがこのファイルの処理を終えたときに true
"start_time" => 1234567890, // このファイルの処理が始まった時刻
"bytes_processed" => 57343250, // このファイルにおける、受信して処理済みのバイト数
),
// 同じリクエスト内で、まだアップロードが完了していない別のファイル
1 => array(
"field_name" => "file2",
"name" => "bar.avi",
"tmp_name" => NULL,
"error" => 0,
"done" => false,
"start_time" => 1234567899,
"bytes_processed" => 54554,
),
)
);
]]>
</programlisting>
</example>
</para>
<warning>
<para>
ウェブサーバーのリクエストバッファリングを無効にしておかないと、うまく動作しません。
リクエストバッファリングが有効になっていると、PHP 側ではアップロードが完全に終わるまでアップロードされたことがわかりません。
たとえば Nginx などのサーバーは、大きなリクエストをバッファリングするようになっています。
</para>
</warning>
<caution>
<para>
アップロード状況の情報は、あらゆるスクリプトを実行する前に、セッションに書き込まれます。
よって、セッション名を <function>ini_set</function> 関数や
<function>session_name</function> 関数で変更してしまうと、
アップロード状況の情報が欠落したセッションが提供されることになります。
</para>
</caution>
</chapter>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->