raful Sat Jan 26 06:36:56 2002 EDT Added files: /phpdoc/he/features file-upload.xml Log: first edition, you know...
Index: phpdoc/he/features/file-upload.xml +++ phpdoc/he/features/file-upload.xml <?xml version="1.0" encoding="iso-8859-8-i"?> <!-- $Revision: 1.28 $ --> <chapter id="features.file-upload"> <title>טיפול בהעלאת קבצים</title> <sect1 id="features.file-upload.post-method"> <title>POST method uploads</title> <simpara> PHP יכולה לטפל בקבלת קבצים שמועלים מכל דפדפן תואם RFC-1867 (שכולל את netscape navigator 3 ומעלה, microsoft internet explorer 3 עם תוסף (patch) של מיקרוסופט, או גירסאות חדשות יותר ללא התוסף). הפיצ'ר הזה מאפשר לאנשים להעלות גם קבצי טקסט וגם קבצים בינאריים. עם האימות של PHP ופונקציות הטיפול בקבצים, ניתנת שליטה מלאה על מי שמורשה להעלות את הקובץ, ומה לעשות עם הקובץ לאחר שהועלה. </simpara> <para> PHP גם תומכת בשיטת העלאת הקבצים PUT ש-netscape composer והקליינט של W3C, Amaya, משתמשים בה. עוד פרטים על <link linkend="features.file-upload.put-method">תמיכה בשיטת PUT</link>. </para> <para> מסך העלאת קובץ יכול להיבנות על ידי יצירת טופס מיוחד שנראה בערך ככה: <example> <title>טופס העלאת קובץ</title> <programlisting role="html"> <![CDATA[ <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> ]]> </programlisting> </example> ה-_URL_ צריך להצביע על קובץ PHP. השדה החבוי MAX_FILE_SIZE חייב לבוא לפני שדה הקלט של הקובץ וערכו הוא גודל הקובץ המקסימלי האפשרי. הגודל הוא ביחידות מסום בייט (byte). <warning> <para> הגדרת ה-MAX_FILE_SIZE היא בגדר ייעוץ לדפדפן. קל ביותר להערים על המקסימום הזה. כדאי לא לבנות על זה שהדפדפן מציית למשאלתך! על הגדרת ה-PHP עבור הגודל המקסימלי, מצד שני, לא ניתן לעבוד. The MAX_FILE_SIZE is advisory to the browser. It is easy to circumvent this maximum. So don't count on it that the browser obeys you wish! The PHP-settings for maximum-size, however, cannot be fooled. </para> </warning> </para> <para> ב-PHP, המשתנים הבאים יהיו מוגדרים בסקריפט היעד לאחר העלאת קבצים שהצליחה, בהנחה ש<link linkend="ini.register-globals">register_globals</link> מופעל ב-<filename>php.ini</filename>. אם <link linkend="ini.track-vars">track_vars</link> מופעל, הם יהיו זמינים ב-PHP גם במערת הגלובלי <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) </simpara> </listitem> <listitem> <simpara> <varname>$userfile_type</varname> - ה-mime type של הקובץ, במידה והדפדפן סיפק את הנתון הזה. דוגמה: "image/gif". </simpara> </listitem> </itemizedlist> יש לשים לב שהחלק "$userfile" בשם המשתנה הוא השם של שדה הקלט של ה-TYPE=file בטופס העלאת הקובץ. בטופס העלאת הקובץ לדוגמה שלמעלה, בחרנו לקרוא למשנה בשם "userfile". </para> <para> ב-PHP 4, ההתנהגות שונה במקצת, בכך שהמערך הגלובלי <varname>$HTTP_POST_FILES</varname> דואג להכיל מידע על הקובץ שהועלה. זה זמין רק אם <link linkend="ini.track-vars">track_vars</link> מופעל, אבל <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 type של הקובץ, אם הדפדפן סיפק את המידע הזה. דוגמה: <literal>"image/gif"</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> The temporary filename of the file in which the uploaded file was stored on the server. שם הקובץ הזמני שבו נשמר הקובץ על השרת. </para> </listitem> </varlistentry> </variablelist> </para> <para> כברירת מחדל, הקבצים ישמרו בספרייה הזמנית שהיא ברירת המחדל של השרת, אלא אם הוגדר אחרת ב<link linkend="ini.upload-tmp-dir">upload_tmp_dir</link> שנמצאת ב<filename>php.ini</filename>. ניתן לשנות את ספריית ברירת המחדל של השרת על ידי הגדרת משתנה הסביבה <envar>TMPDIR</envar> בסביבה בה PHP רצה. הגדרה באמצעות <function>putenv</function> מתוך סקריפט של PHP לא תעבוד. כמו כן, משתנה הסביבה הזה יכול להיות שימושי כשרוצים לוודא שפעולות אחרות מבוצעות על קבצים שהועלו. <example> <title>וידוי העלאת קבצים</title> <para> הדוגמאות הבאות הן עבור גירסאות של PHP המאוחרות מ-3.0.16, וגירסאות המאוחרות מ-PHP בגירסה 4.0.2. אפשר לבדוק גם את הפונציות <function>is_uploaded_file</function> ו-<function>move_uploaded_file</function>. </para> <programlisting role="php"> <![CDATA[ <?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"); ?> ]]> </programlisting> <para> עבור גירסאות קודמות של PHP, צריך לעשות משהו כמו בדוגמה. <note> <para> זה <emphasis>לא</emphasis> יעבוד בגירסאות של PHP שגדולות מ-4.0.2. זה תלוי בתפקודיות הפנימית של PHP ששונתה אחרי הגירסה הזו. </para> </note> </para> <programlisting role="php"> <![CDATA[ <?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> הקובץ ימחק מהספרייה הזמנית בסוף הבקשה אם הוא לא הועבר, או ששמו לא שונה. </simpara> </sect1> <sect1 id="features.file-upload.common-pitfalls"> <title>מלכודות נפוצות</title> <simpara> המאפיין <literal>MAX_FILE_SIZE</literal> לא יכול להגדיר גודל קובץ הגדול מגודל הקובץ שהוגדר בהגדרת ה-ini - <link linkend="ini.upload-max-filesize">upload_max_filesize</link>. ברירת המחדל היא 2 מגה-בייט. </simpara> <simpara> ללא וידוי הקבצים שמועלים לשרת, משתמשים יכולים לחדור למידע רגיש בספריות אחרות. </simpara> <simpara> Please note that the CERN httpd seems to strip off everything starting at the first whitespace in the content-type mime header it gets from the client. As long as this is the case, CERN httpd will not support the file upload feature. </simpara> </sect1> <sect1 id="features.file-upload.multiple"> <title>העלאת קבצים מרובים</title> <simpara> ניתן להעלות כמה קבצים בו-זמנית, ושהמידע עליהם יאסף במערכים בשבילך. כדי לעשות את זה, יש להשתמש באותו תחביר שליחת מערך בטופס ה-HTML כמו שעושים עם תיבות בחירה וצ'קבוקסים: </simpara> <note> <para> תמיכה בהעלאת קבצים מרובים נוספה בגירסה 3.0.10. </para> </note> <para> <example> <title>העלאת קבצים מרובים</title> <programlisting role="html"> <![CDATA[ <form action="file-upload.php" method="post" enctype="multipart/form-data"> Send these files:<br> <input name="userfile[]" type="file"><br> <input name="userfile[]" type="file"><br> <input type="submit" value="Send files"> </form> ]]> </programlisting> </example> </para> <simpara> כשהטופס שלמעלה נשלח, המערכים <varname>$userfile</varname>, <varname>$userfile_name</varname> ו-<varname>$userfile_size</varname> יווצרו בתחום הגלובלי (ממש כמו ב-$HTTP_POST_FILES ($HTTP_POST_VARS ב-PHP 3)). כל אחד מהנ"ל יאנדקס, בצורה מספרית, מערך של הערכים המתאימים, לפי הקבצים שנשלחו. </simpara> <simpara> לדוגמה, בהנחה שהקבצים <filename>/home/test/review.html</filename> ו-<filename>/home/test/xwp.out</filename> נשלחו. במקרה הזה, <varname>$userfile_name[0]</varname> יכיל את הערך <filename>review.html</filename>, ו-<varname>$userfile_name[1]</varname> יכיל את הערך <filename>xwp.out</filename>. באותו האופן, <varname>$userfile_size[0]</varname> יכיל את גודל הקובץ <filename>review.html</filename> וכיוצא בזה. </simpara> <simpara> <varname>$userfile['name'][0]</varname>, <varname>$userfile['tmp_name'][0]</varname>, <varname>$userfile['size'][0]</varname> ו-<varname>$userfile['type'][0]</varname> גם הם קבועים. </simpara> </sect1> <sect1 id="features.file-upload.put-method"> <title>תמיכה בשיטת PUT</title> <para> PHP מספקת תמיכה בשיטת HTTP PUT שבה משתמשים netscape composer ו-W3C Amaya. בקשת PUT פשוטות יותר מהעלאת קבצים, והן נראות בערך ככה: <informalexample> <programlisting> PUT /path/filename.html HTTP/1.1 </programlisting> </informalexample> </para> <para> בדרך כלל זה יציין שהלקוח רוצה לשמור את התוכן שבא אחרי, כמו: /path/filename.html בעץ הרשת שלך. מובן מאליו שזה לא רעיון טוב עבור Apache או PHP לאשר לכולם באופן אוטומטי לכתוב על קבצים קיימים בעץ הרשת שלך. כדי לטפל בבקשות כאלה, צריך להגיד לשרת שברצונך להפנות בקשות כאלה לסקריפט PHP. על Apache הדבר נעשה על ידי ספריית <emphasis>Script</emphasis>. אפשר לשים את זה כמעט בכל מקום בקובץ הקונפיגורציה של Apache. מקום נפוץ הוא בתוך הבלוק <Directory>או אולי בתוך הבלוק <Virtualhost>. שורה כזו תעשה את הטריק: <informalexample> <programlisting> Script PUT /put.php </programlisting> </informalexample> </para> <simpara> זה אומר ל-Apache לשלוח את כל בקשות PUT ל-URI שתואם את המיקום בו שמתם את השורה שמציינת את מיקום הסקריפט put.php. זה בהנחה, כמובן, ש-PHP מאפשרת סיומות .php וש-PHP פעילה. </simpara> <simpara> בתוך הקובץ put.php צריך לכתוב משהו כזה: </simpara> <para> <informalexample><programlisting role="php"> <![CDATA[ <?php copy($PHP_UPLOADED_FILE_NAME,$DOCUMENT_ROOT.$REQUEST_URI); ?> ]]> </programlisting></informalexample> </para> <simpara> זה יעתיק את הקובץ למיקום המבוקש על ידי הלקוח. בטח יתעורר בך הרצון לבצע כמה בדיקות ו/או לאמת את המשתמש לפני ביצוע העתקת הקובץ. הטריק היחיד כאן הוא שכש-PHP רואה בבקשה בשיטת PUT, היא מאחסנת את הקובץ שהועלה בקובץ זמני ממש כמו אלה שטופלו מלבד <link linkend="features.file-upload.post-method">שיטת POST</link>. כשהבקשה מסתיימת, הקובץ הזמני הזה נמחק. לכן, סקריפט ה-PHP שמטפל ב-PUT צריך להעתיק את הקובץ למיקום כלשהו. שם הקובץ של הקובץ הזמני נמצא בתוך המשתנה $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: vim600: syn=xml fen fdm=syntax fdl=2 si vim: et tw=78 syn=sgml vi: ts=1 sw=1 -->