File: file-upload.xml

package info (click to toggle)
phpdoc 20020310-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 35,272 kB
  • ctags: 354
  • sloc: xml: 799,767; php: 1,395; cpp: 500; makefile: 200; sh: 140; awk: 51
file content (324 lines) | stat: -rw-r--r-- 14,579 bytes parent folder | download
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<?xml version="1.0" encoding="utf-8"?>
<chapter id="features.file-upload">
	<title>Handling file uploads</title>
	<sect1 id="features.file-upload.post-method">
		<title>POST method uploads</title>
		<simpara>
	PHP는 RFC-1867을 지원하는 브라우저로부터 파일을 업로드 받을 수 있는 기능이 있다. 
	이 기능을 사용하면 Text뿐 아니라 Binary파일도 업로드가 가능하다. 
	여러분은 PHP의 authetication과 파일을 다루는 함수를 사용하여, 
	파일이 Upload된 후에 해야 할 일을 스크립트에 반드시 정해 두어야 한다.
   </simpara>
		<para>
	PHP는 또한 Netscape Composer 와 W3C's Amaya clients를 사용할 경우 
	PUT-method 의 파일 업로드도 지원한다. 자세한 내용은 
	<link linkend="features.file-upload.put-method">PUT Method Support</link>를 읽어보기바란다.
   </para>
		<para>
	파일 업로드 화면은 다음과 같은 좀 특별한 폼을 만들어 띄울 수 있다. : 
    <example>
				<title>File Upload Form</title>
				<programlisting>
&lt;FORM ENCTYPE=&quot;multipart/form-data&quot; ACTION=&quot;_URL_&quot; METHOD=POST&gt;
&lt;INPUT TYPE=&quot;hidden&quot; name=&quot;MAX_FILE_SIZE&quot; value=&quot;1000&quot;&gt;
Send this file: &lt;INPUT NAME=&quot;userfile&quot; TYPE=&quot;file&quot;&gt;
&lt;INPUT TYPE=&quot;submit&quot; VALUE=&quot;Send File&quot;&gt;
&lt;/FORM&gt;
     </programlisting>
			</example>
	여기서 _URL_은 PHP html파일이어야 합니다. 
	hidden 필드인 MAX_FILE_SIZE는 File input 필드들보다 선행되어야 합니다. 
	이 값은 PHP html이 받아들이는 최대 파일 크기를 Byte단위로 나타냅니다. 
   </para>
		<para>
	PHP3에서는 업로드가 완료되면 실행될 스크립트에는 다음 변수들이 설정된다. 
	(물론 <filename>php3.ini</filename> 파일에 <link linkend="ini.register-globals">register_globals</link>가 
	켜져있어야 한다.)
	또한 만약 <link linkend="ini.track-vars">track_vars</link>가 켜져있으면,
	전역변수 <varname>$HTTP_POST_VARS</varname> 내에도 이 변수들이 설정된다.
	다음 예제에 있는 변수명들은 업로드시 'userfile'이라는 필드명을 사용한 것으로 가정한다.:

    <itemizedlist>
				<listitem>
					<simpara>
						<varname>$userfile</varname> - 업로드된 파일 내용이 저장되어 있는 서버의 임시 파일명.
      </simpara>
				</listitem>
				<listitem>
					<simpara>
						<varname>$userfile_name</varname> - 업로드한 시스템에서 사용하는 파일의 원래 이름.
      </simpara>
				</listitem>
				<listitem>
					<simpara>
						<varname>$userfile_size</varname> - byte단위의 Upload된 파일의 크기.
      </simpara>
				</listitem>
				<listitem>
					<simpara>
						<varname>$userfile_type</varname> - 만약 browser가 업로드된 파일의 mime 형식을 안다면, 그 mime 형식. 
      (예: &quot;image/gif&quot;).
      </simpara>
				</listitem>
			</itemizedlist>
	위 변수의 "$userfile"부분은 upload form에서 TYPE=filed을 가진 INPUT 필드의 이름이 된다. 
	위의 예제에서 우리는 그 이름은 "userfile"이라고 정했다.
   </para>
		<para>
	PHP4에서는 동작이 약간 다르다. PHP4에서는 엄로드된 파일에 대한 정보를 가지고 있는
	<varname>$HTTP_POST_FILES</varname> 전역 배열을 지원한다.
	이 변수는 <link linkend="ini.track-vars">track_vars</link>가 켜져 있어야만 사용가능하지만,
	PHP 4.0.2 이후에서는 항상 켜져 있으므로 걱정할 필요는 없다.
   </para>
		<para>
			<varname>$HTTP_POST_FILES</varname>의 내용은 다음과 같다.
	위에 있는 예와 같이 업로드시 'userfile'이라는 필드명을 사용한 것으로 가정한다.:
    <variablelist>
				<varlistentry>
					<term>
						<varname>$HTTP_POST_FILES['userfile']['name']</varname>
					</term>
					<listitem>
						<para>
        클라이언트에서의 원래 파일명
       </para>
					</listitem>
				</varlistentry>
				<varlistentry>
					<term>
						<varname>$HTTP_POST_FILES['userfile']['type']</varname>
					</term>
					<listitem>
						<para>
        해당 파일의 mime 타입. 브라우저가 이 타입 대한 정보를 가지고 있는 경우에만 설정된다. 
        (예 : <literal>&quot;image/gif&quot;</literal>)
        </para>
					</listitem>
				</varlistentry>
				<varlistentry>
					<term>
						<varname>$HTTP_POST_FILES['userfile']['size']</varname>
					</term>
					<listitem>
						<para>
        업로드된 파일의 크기. byte 단위이다.
       </para>
					</listitem>
				</varlistentry>
				<varlistentry>
					<term>
						<varname>$HTTP_POST_FILES['userfile']['tmp_name']</varname>
					</term>
					<listitem>
						<para>
        업로드가 완료된후 서버에 저장된 파일의 파일명. (임시파일이다.)
       </para>
					</listitem>
				</varlistentry>
			</variablelist>
		</para>
		<para>
	업로드된 파일은 <filename>php.ini</filename>의 
	<link linkend="ini.upload-tmp-dir">upload_tmp_dir</link>지시자가 특정 디렉토리를 지정하지 않으면,
	기본적으로 우선 서버의 default temporary directory에 저장된다. 
	이 디폴트 디렉토리는 PHP가 돌아가는 컴퓨터의 환경변수 <envar>TMPDIR</envar>을 설정하여 변경할 수 있다. 
	이를 PHP 스크립트 안에서 <function>putenv</function> 함수를 사용하여 변경하는 것은 동작하지 않는다.
    <example>
				<title>Validating file uploads</title>
				<para>
	다음 예제는 PHP3 3.0.16 이상이나 PHP4 4.0.2 이상에서만 실행이 가능하다.
	그리고 <function>is_uploaded_file</function>과 <function>move_uploaded_file</function>함수를 살펴보자.
     </para>
				<programlisting role="php">
&lt;?php 
if (is_uploaded_file($userfile)) {
    copy($userfile, "/place/to/put/uploaded/file");
} else {
    echo "Possible file upload attack: filename '$userfile'.";
}
/* ...or... */
move_uploaded_file($userfile, "/place/to/put/uploaded/file");
?&gt;
     </programlisting>
				<para>
	 이전 버전의 PHP에서는 다음과 같은 처리하여야 한다. 가 필요하다.
      For earlier versions of PHP, you'll need to do something like
      the following.
      <note>
						<para>
        이 예제는 PHP4 4.0.2이후 버전에서는 동작하지 <emphasis>않는다.</emphasis> 
        4.0.2이후 부터는 내부적으로 처리하는 방법이 달라졌기 때문이다.
       </para>
					</note>
				</para>
				<programlisting role="php">
&lt;?php 
/* Userland test for uploaded file. */ 
function is_uploaded_file($filename) {
    if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
        $tmp_file = dirname(tempnam('', ''));
    }
    $tmp_file .= '/' . basename($filename);
    /* User might have trailing slash in php.ini... */
    return (ereg_replace('/+', '/', $tmp_file) == $filename);
}

if (is_uploaded_file($userfile)) {
    copy($userfile, "/place/to/put/uploaded/file");
} else {
    echo "Possible file upload attack: filename '$userfile'.";
}
?>
     </programlisting>
			</example>
		</para>
		<simpara>
	업로드된 파일을 다루는 PHP 스크립트는 그 파일을 다루는 작업을 설정해 줄 필요가 있다. 
	예를들어, <varname>$file_size</varname> 변수를 사용하여 너무 작거나 큰 파일을 버릴 수도 있다. 
	또한 <varname>$file_type</varname> 변수를 가지고 특정한 타입에 맞지 않는 파일을 버릴 수 있다. 
	어떤 로직이던, 임시 디렉토리에 있는 파일을 지우거나 나중에 필요할 경우에는 다른 곳에 이동시켜야 한다. 
   </simpara>
		<simpara>
	만약 임시 디렉토리에 있는 파일을 해당 request가 끝날 때 까지도 지우거나 이동시키지 않았다면, 
	이 파일은 해당 request가 종료되는 시점에서 자동으로 지워진다.
   </simpara>
	</sect1>
	<sect1 id="features.file-upload.common-pitfalls">
		<title>일반적인 주의사항 (Common Pitfalls)</title>
		<simpara>
	MAX_FILE_SIZE 아이템의 값은  php3.ini에 설정된 upload_max_filesize의 값이나 
	Apache의 .conf에 설정한 php3_upload_max_filesize의 값보다 크게 설정할 수 없다. 
	기본값은 2메가 바이트이다.
   </simpara>
		<simpara>
     업로드된 파일에 대한 검사를 게을리하면 일반 사용자들이 시스템이나 
	다른 디렉토리내의 보안에 관한 정보에 접근할 수도 있으니 주의하기 바란다.
   </simpara>
		<simpara>
	CERN httpd 서버는 client로부터 입력받은 mime header의 앞쪽 여백을 모두 strip off 시켜버리므로, 
	CERN httpd 서버에서는 File Upload 기능이 동작하지 않는다. 
   </simpara>
	</sect1>
	<sect1 id="feature-fileupload.multiple">
		<title>여러 파일을 Upload하기 (Uploading multiple files)</title>
		<simpara>
	한번에 여러개의 파일을 동시에 전송하는 것도 가능하다. 
	이때 PHP는 이 파일들에 대한 정보를 배열로 전달한다. 
	따라서 이런 경우에는 여러개를 선택하는 select나 checkbox 때처럼 HTML의 form의 아이템에 
	동일한 array명을 적어주어야 한다.:
   </simpara>
		<note>
			<para>
     여러 파일 전송 기능은 3.0.10부터 추가된 기능이다. 
    </para>
		</note>
		<para>
			<example>
				<title>Uploading multiple files</title>
				<programlisting>
&lt;form action=&quot;file-upload.php&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
  Send these files:&lt;br&gt;
  &lt;input name=&quot;userfile[]&quot; type=&quot;file&quot;&gt;&lt;br&gt;
  &lt;input name=&quot;userfile[]&quot; type=&quot;file&quot;&gt;&lt;br&gt;
  &lt;input type=&quot;submit&quot; value=&quot;Send files&quot;&gt;
&lt;/form&gt;
     </programlisting>
			</example>
		</para>
		<simpara>
	위의 폼이 전송될 때 <computeroutput>$userfile</computeroutput>,
    <computeroutput>$userfile_name</computeroutput>, 
    <computeroutput>$userfile_size</computeroutput>의 배열이 전역 변수로 만들어진다. 
	($HTTP_POST_FILES(PHP3 에서는 $HTTP_POST_VARS)에도 만들어진다.) 
	이 배열들은 전송된 파일의 정보를 가지고 있고, 각 배열은 번호로 인덱스되어 있다.
   </simpara>
		<simpara>
	예를 들어, 위의 예에서 <filename>/home/test/review.html</filename>와
	<filename>/home/test/xwp.out</filename> 의 두 개의 파일을 전송했다면 
	<computeroutput>$userfile_name[0]</computeroutput> 에는 
	<computeroutput>review.html</computeroutput>이라는 값이, 
	<computeroutput>$userfile_name[1]</computeroutput>에는 
	<computeroutput>xwp.out</computeroutput>이라는 값이 저장되게 된다. 
	동시에, <computeroutput>$userfile_size[0]</computeroutput> 에는 
	<filename>review.html</filename>의 파일 크기가 저장되는 식이 된다
   </simpara>
		<simpara>
			<computeroutput>$userfile['name'][0]</computeroutput>,
    <computeroutput>$userfile['tmp_name'][0]</computeroutput>,
    <computeroutput>$userfile['size'][0]</computeroutput>, and
    <computeroutput>$userfile['type'][0]</computeroutput> are also set.
   </simpara>
	</sect1>
	<sect1 id="features.file-upload.put-method">
		<title>PUT method support</title>
		<para>
	PHP는 Netscape Composer나 W3C Amaya같은 클라이언트에 대해 HTTP PUT 방식(method)을 지원한다. 
	PUT 요구(request)는 file upload보다 훨씬 쉽다. 단지 다음과 같이 하면 된다. :
    <informalexample>
				<programlisting>
PUT /path/filename.html HTTP/1.1
     </programlisting>
			</informalexample>
		</para>
		<para>
	이것은 보통 원격 클라이언트가 보낸 내용을 웹 트리 밑의 /path/filename.html로 저장하라는 의미이다. 
	그런데 여러분의 웹 트리밑에 있는 파일들을 아무나 덮어 쓸 수 있다는 것은 
	Apache나 PHP에 있어서 좋지 않은 생각이다. 
	따라서 이와 같은 요구를 다루기 전에, 우선 웹 서버에게 이런 요구를 다루는 
	PHP 스크립트를 미리 지정해 주어야 한다. 
	아파치에서는 <emphasis>Script</emphasis> 지시자로 그 내용을 지정한다. 
	이 지시자는 Apache 설정 파일중의 어느 위치에 있어도 괜찮으나, 
	보통 &lt;Directory&gt; 블록 안이나 &lt;Virtualhost&gt; 블록 안에 위치하는 것이 일반적이다. 
	보통 다음과 같이 설정한다. :
    <informalexample>
				<programlisting>
Script PUT /put.php3
     </programlisting>
			</informalexample>
		</para>
		<simpara>
	이것은 이 라인이 속하는 블록의 URI에 해당되는 모든 PUT 요구를 
	put.php3 스크립트에게 전달하라고 Apache에게 알려 준다. 
	물론 이 경우 .php3 확장자에 대하여 PHP설정이 완료되어 있고, PHP가 작동중이어야 한다.
   </simpara>
		<simpara>
	put.php3 파일은 보통 다음과 같이 구성될 수 있다. :
   </simpara>
		<para>
			<informalexample>
				<programlisting>
&lt;?php copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI); ?&gt;
    </programlisting>
			</informalexample>
		</para>
		<simpara>
	위의 명령은 해당 파일을 원격 클라이언트가 요청한 위치에 복사하는 것이다. 
	아마 여러분은 복사하기 전에 사용자를 확인하거나 파일을 검사하는 등의 기능을 원할 것이다. 
	여기서 알 수 있는 것은 PHP가 <link linkend="features.file-upload.post-method">POST-method</link>의 요구를 받았을 때 
	POST-method기능과 마찬가지로 임시 파일에 해당 내용을 저장한다는 것이다. 
	즉, 요구가 끝나게 되면 임시파일은 지워진다. 
	따라서 PUT을 다루는 PHP 스크립트는 해당 파일을 어디 다른 곳에 복사해 두어야 한다. 
	임시파일의 이름은 $PHP_PUT_FILENAME 이라는 변수에 저장되고, 
	$REQUEST_URI 변수에 클라이언트에서 보내온 저장할 파일의 경로와 이름이 저장된다.
	(Apache가 아닌 웹서버에서는 모양이 조금 달라진다.) 
	물론 여러분은 이 경로명과 파일명이 아닌 전혀 다른 위치에 다른 파일명을 사용할 수도 있다.
   </simpara>
	</sect1>
</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:"../../manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
-->