PHP
יכולה
לטפל
בקבלת
קבצים
שמועלים
מכל
דפדפן
תואם
RFC-1867
(
שכולל
את
netscape
navigator
3
ומעלה
,
microsoft
internet
explorer
3
עם
תוסף
(patch
)
של
מיקרוסופט
,
או
גירסאות
חדשות
יותר
ללא
התוסף)
.
הפיצ
'ר
הזה
מאפשר
לאנשים
להעלות
גם
קבצי
טקסט
וגם
קבצים
בינאריים
.
עם
האימות
של
PHP
ופונקציות
הטיפול
בקבצים
,
ניתנת
שליטה
מלאה
על
מי
שמורשה
להעלות
את
הקובץ
,
ומה
לעשות
עם
הקובץ
לאחר
שהועלה
.
PHP
גם
תומכת
בשיטת
העלאת
הקבצים
PUT
ש-netscape
composer
והקליינט
של
W3C
,
Amaya
,
משתמשים
בה
.
עוד
פרטים
על
תמיכה
בשיטת
PUT
.
מסך
העלאת
קובץ
יכול
להיבנות
על
ידי
יצירת
טופס
מיוחד
שנראה
בערך
ככה
:
דוגמה
19-1
.
טופס
העלאת
קובץ
form
enctype="
multipart
/
form-data
"
action="_URL_
"
method="post
"
input
type="hidden
"
name="MAX_FILE_SIZE
"
value="1000
"
Send
this
file
:
input
name="userfile
"
type="file
"
input
type="submit
"
value="Send
File
"
/
form
|
|
ה-_URL_ צריך להצביע על קובץ PHP. השדה החבוי MAX_FILE_SIZE חייב
לבוא לפני שדה הקלט של הקובץ וערכו הוא גודל הקובץ המקסימלי
האפשרי. הגודל הוא ביחידות מסום בייט (byte).
אזהרה
|
הגדרת
ה-MAX_FILE_SIZE
היא
בגדר
ייעוץ
לדפדפן
.
קל
ביותר
להערים
על
המקסימום
הזה
.
כדאי
לא
לבנות
על
זה
שהדפדפן
מציית
למשאלתך
!
על
הגדרת
ה-PHP
עבור
הגודל
המקסימלי
,
מצד
שני
,
לא
ניתן
לעבוד
.
So
don
'
t
count
on
it
that
the
browser
obeys
you
wish
!
|
ב-PHP
,
המשתנים
הבאים
יהיו
מוגדרים
בסקריפט
היעד
לאחר
העלאת
קבצים
שהצליחה
,
בהנחה
ש
register_globals
מופעל
ב
-
php.ini
.
אם
track_vars
מופעל
,
הם
יהיו
זמינים
ב-PHP
גם
במערת
הגלובלי
$HTTP_POST_VARS
.
יש
לשים
לב
ששמות
המשתנים
הבאים
מתייחסים
לקובץ
שהועלה
בשדה
בשם
'
userfile
'
,
כמו
בדוגמה
שלמעלה
:
-
$userfile
-
שם
הקובץ
הזמני
שבו
אוחסן
הקובץ
שהועלה
לשרת
.
-
$userfile_name
-
השם
או
הנתיב
המקורי
של
הקובץ
על
המחשב
של
זה
שהעלה
את
הקובץ
-
$userfile_size
-
הגודל
של
הקובץ
ביחידות
של
בייט
(
byte
)
-
$userfile_type
-
ה-mime
type
של
הקובץ
,
במידה
והדפדפן
סיפק
את
הנתון
הזה
.
דוגמה
:
"
image
/
gif
"
.
יש לשים לב שהחלק "$userfile" בשם המשתנה הוא השם של שדה הקלט של
ה-TYPE=file בטופס העלאת הקובץ. בטופס העלאת הקובץ לדוגמה שלמעלה,
בחרנו לקרוא למשנה בשם "userfile".
ב-PHP
4
,
ההתנהגות
שונה
במקצת
,
בכך
שהמערך
הגלובלי
$HTTP_POST_FILES
דואג
להכיל
מידע
על
הקובץ
שהועלה
.
זה
זמין
רק
אם
track_vars
מופעל
,
אבל
track_vars
תמיד
מופעל
בגירסאות
PHP
שבאו
אחרי
4.0.2
.
התכולה
של
$HTTP_POST_FILES
מפורטת
כאן
.
יש
לשים
לב
שהנחת
היסוד
היא
ששם
הקובץ
שמועלה
הוא
'
userfile
'
,
כמו
בדוגמה
למעלה
:
-
$HTTP_POST_FILES['userfile']['name']
-
השם
המקורי
של
הקובץ
על
מחשב
הלקוח
.
-
$HTTP_POST_FILES['userfile']['type']
-
ה-mime
type
של
הקובץ
,
אם
הדפדפן
סיפק
את
המידע
הזה
.
דוגמה
:
"
image
/
gif
"
.
-
$HTTP_POST_FILES['userfile']['size']
-
הגודל
,
ביחידות
בייט
(
byte
)
,
של
הקובץ
שהועלה
.
-
$HTTP_POST_FILES['userfile']['tmp_name']
-
The
temporary
filename
of
the
file
in
which
the
uploaded
file
was
stored
on
the
server
.
שם
הקובץ
הזמני
שבו
נשמר
הקובץ
על
השרת
.
כברירת
מחדל
,
הקבצים
ישמרו
בספרייה
הזמנית
שהיא
ברירת
המחדל
של
השרת
,
אלא
אם
הוגדר
אחרת
ב
upload_tmp_dir
שנמצאת
ב
php.ini
.
ניתן
לשנות
את
ספריית
ברירת
המחדל
של
השרת
על
ידי
הגדרת
משתנה
הסביבה
TMPDIR
בסביבה
בה
PHP
רצה
.
הגדרה
באמצעות
putenv(
)
מתוך
סקריפט
של
PHP
לא
תעבוד
.
כמו
כן
,
משתנה
הסביבה
הזה
יכול
להיות
שימושי
כשרוצים
לוודא
שפעולות
אחרות
מבוצעות
על
קבצים
שהועלו
.
דוגמה
19-2
.
וידוי
העלאת
קבצים
הדוגמאות
הבאות
הן
עבור
גירסאות
של
PHP
המאוחרות
מ-3.0.16
,
וגירסאות
המאוחרות
מ-PHP
בגירסה
4.0.2
.
אפשר
לבדוק
גם
את
הפונציות
is_uploaded_file(
)
ו
-
move_uploaded_file(
)
.
?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")
;
?
|
עבור
גירסאות
קודמות
של
PHP
,
צריך
לעשות
משהו
כמו
בדוגמה
.
הערה
:
זה
לא
יעבוד
בגירסאות
של
PHP
שגדולות
מ-4.0.2
.
זה
תלוי
בתפקודיות
הפנימית
של
PHP
ששונתה
אחרי
הגירסה
הזו
.
?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'
."
;
}
?
|
|
סקריפט
ה-PHP
שמקבל
את
הקובץ
המועלה
צריך
ליישם
כל
לוגיקה
הכרחית
כדי
לקבוע
מה
צריך
לעשות
עם
הקובץ
שהועלה
.
ניתן
,
לדוגמה
,
להשתמש
במשתנה
$file_size
כדי
למחוק
כל
קובץ
,
קטן
או
גדול
מידי
.
אפשר
להשתמש
במשתנה
$file_type
כדי
לזרוק
כל
קובץ
שלא
תואם
לקריטריון
של
סוג
מסויים
.
תהיה
הלוגיקה
אשר
תהיה
,
צריך
למחוק
את
הקובץ
מהספרייה
הזמנית
,
או
להעביר
אותו
למקום
אחר
.
הקובץ
ימחק
מהספרייה
הזמנית
בסוף
הבקשה
אם
הוא
לא
הועבר
,
או
ששמו
לא
שונה
.