Chapterبەش 8 · Lectureوانە 8.7
Uploading Filesبارکردنی فایل
Let visitors upload pictures safely: the upload form and php.ini, the temporary folder and $_FILES, checks for errors, size, extension and real type that really block bad files, move_uploaded_file(), safe storage, and the BLOB method with prepared statements.
ڕێگە بدە سەردانکەران بە سەلامەتی وێنە بار بکەن: و php.ini، کاتی و $_FILES، پشکنینی و قەبارە و و جۆری ڕاستەقینە کە بە ڕاستی خراپ ڕادەگرن، move_uploaded_file()، هەڵگرتنی سەلامەت و ڕێگای BLOB بە .
What you will learnچی فێر دەبیت
- Build an upload form with the right method, enctype and field name, and configure php.ini.
- Explain the journey of an upload: temporary folder, $_FILES, checks, move_uploaded_file().
- Read every key of $_FILES and know which values can be trusted.
- Check the error code, size, extension and real type so that every failed check blocks the upload.
- Store uploads safely: unique names, outside the web root or with scripts blocked.
- Store a file in a database BLOB column with a prepared statement.
- دروست بکەیت بە method و enctype و ناوی دروستی و php.ini ڕێکبخەیت.
- ڕێگای ڕوون بکەیتەوە: کاتی، $_FILES، پشکنینەکان، move_uploaded_file().
- هەموو $_FILES بخوێنیتەوە و بزانیت کام جێی متمانەیە.
- کۆدی ، قەبارە، و جۆری ڕاستەقینە بپشکنیت بە شێوەیەک کە هەر پشکنینێکی شکستخواردوو ڕابگرێت.
- بارکراوەکان بە سەلامەتی هەڵبگریت: ناوی بێهاوتا، لە دەرەوەی ڕەگی وێب یان بە ڕاگرتنی .
- لە BLOBـی بە هەڵبگریت.
Why file uploads need careبۆچی بارکردنی فایل وردبینی دەوێت
Many websites let visitors send a file: a profile photo, a homework PDF, a picture of a product. Sending a file from the visitor's computer to the server is called . In PHP it takes a special , the $_FILES , and the move_uploaded_file().
زۆر ڕێگە بە سەردانکەران دەدەن بنێرن: وێنەی پرۆفایل، PDFـی ئەرکی ماڵەوە، وێنەی کاڵایەک. ناردنی لە سەردانکەرەوە بۆ پێی دەوترێت . لە PHPـدا پێویستی بە تایبەت، $_FILES و move_uploaded_file() هەیە.
Uploads are useful, but they are also one of the riskiest features of a website: a stranger puts a whole file on your server. If you keep any file that arrives, someone can fill your disk, overwrite other people's files, or upload a PHP program and run it on your server. This lecture first builds the upload step by step, as the course does, and then makes it safe.
بەسوودە، بەڵام یەکێکە لە مەترسیدارترین تایبەتمەندییەکانی : کەسێکی نەناسراو تەواو لەسەر دادەنێت. ئەگەر هەر گەیشت هەڵیبگریت، کەسێک دەتوانێت دیسکەکەت پڕ بکات، خەڵکی تر بسڕێتەوە و جێیان بگرێتەوە، یان PHP بار بکات و لەسەر جێبەجێی بکات. ئەم وانەیە سەرەتا وەک کۆرسەکە هەنگاو بە هەنگاو دروست دەکات و پاشان سەلامەتی دەکات.
When a parcel arrives at the post office, it does not go straight to the shelves. It waits in a parcel room under a temporary number. A clerk checks it: is the address right, is it too heavy, is it really what the label says? Only then does it get a proper place on a shelf. Parcels that nobody takes are thrown away at the end of the day. An upload works the same way: PHP keeps the file in a temporary folder, your script is the clerk that checks it, and move_uploaded_file() puts it on the shelf.
کاتێک بەستەیەک دەگاتە پۆستەخانە، ڕاستەوخۆ ناچێتە سەر ڕەفەکان. لە ژووری بەستەکاندا بە ژمارەیەکی کاتی چاوەڕێ دەکات. فەرمانبەرێک دەیپشکنێت: ئایا ناونیشانەکەی ڕاستە، ئایا زۆر قورسە، ئایا بە ڕاستی ئەوەیە کە لەسەر لیبڵەکەی نووسراوە؟ تەنها دوای ئەوە شوێنێکی ڕاستەقینەی لەسەر ڕەفێک پێدەدرێت. ئەو بەستانەی کەس نایانبات لە کۆتایی ڕۆژدا فڕێ دەدرێن. بە هەمان شێوە کار دەکات: PHP لە کاتیدا ڕادەگرێت، ئەو فەرمانبەرەیە کە دەیپشکنێت و move_uploaded_file() دەیخاتە سەر ڕەفەکە.
Where the analogy stops workingسنووری ئەم نموونەیە
A post-office clerk checks every parcel by habit. PHP does not check anything by itself, not even for viruses. If your script does not check the file, nobody does.
فەرمانبەری پۆستەخانە بە خوو هەموو بەستەیەک دەپشکنێت. بەڵام PHP خۆی هیچ شتێک ناپشکنێت، تەنانەت ڤایرۆسیش. ئەگەر نەپشکنێت، کەس نایپشکنێت.
Explains why accepting files from visitors is dangerous and which basic checks keep your website safe.
ڕوون دەکاتەوە بۆچی وەرگرتنی لە سەردانکەران مەترسیدارە و کام پشکنینە سەرەتاییانە پارێزراو دەهێڵنەوە.
Watch 6:32–8:46: the file upload security chapter.
لە 6:32 تا 8:46 سەیر بکە: بەشی .
What you need before you startئەوەی پێش دەستپێکردن پێویستتە
To upload a file to the server with <input type="file">, take care of these points:
بۆ بۆ بە <input type="file">، ئاگات لەم خاڵانە بێت:
- Always use the to send the form:
method="post". A file cannot travel in the URL. - Add the
enctype="multipart/form-data"to the<form>tag. Without this attribute, the file is not uploaded: PHP receives only its name. - Give the file input a
name; PHP finds the file by that name in$_FILES. - Make sure that PHP allows uploads: in , the directive
file_uploadsmust beOn.
- هەمیشە بە بنێرە:
method="post". ناتوانێت لە ناو URLـدا بگوازرێتەوە. -
enctype="multipart/form-data"بۆ<form>زیاد بکە. بەبێ ئەم بار ناکرێت: PHP تەنها ناوەکەی وەردەگرێت. - ناوێک (
name) بدە بە ؛ PHP بەو ناوە لە$_FILESدا دەدۆزێتەوە. - دڵنیابە کە PHP ڕێگە بە دەدات: لە ، ڕێنمایی
file_uploadsدەبێتOnبێت.
<form action="index.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>Select image to upload: [Choose File] No file chosen [Upload Image]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<form action="index.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 1
method="post"andenctype="multipart/form-data"are both required.actionnames the PHP file that receives the upload.هەردووکی
method="post"وenctype="multipart/form-data"پێویستن.actionناوی ئەو PHPـیە کە وەردەگرێت.- Lineدێڕی 3
PHP uses the
name(image), not theid.PHP ناوەکە (
name، واتەimage) بەکار دەهێنێت، نەکid.
The course deck shows a shorter form with no action (the form posts back to the same page) and a field called photo:
کۆرسەکە کورتتر پیشان دەدەن بەبێ action ( دەنێردرێتەوە بۆ هەمان لاپەڕە) و بە ناوی photo:
<form method="post" enctype="multipart/form-data">
<input type="file" name="photo">
<input type="submit">
</form>What you need before you startئەوەی پێش دەستپێکردن پێویستتە
Configure the php.ini fileفایلی php.ini ڕێکبخە
First, ensure that PHP is configured to allow file uploads. In your php.ini file (in XAMPP: C:\xampp\php\php.ini), search for the file_uploads directive and set it to On:
سەرەتا دڵنیابە کە PHP ڕێکخراوە بۆ ئەوەی ڕێگە بە بدات. لە php.iniـەکەتدا (لە XAMPPـدا: C:\xampp\php\php.ini)، بەدوای ڕێنمایی file_uploadsدا بگەڕێ و بیکە بە On:
file_uploads = OnOn is already the default. Three more settings limit the size and number of uploads. After changing php.ini, restart Apache in the XAMPP Control Panel.
On پێشتر بنەڕەتییە. سێ تر قەبارە و ژمارەی سنووردار دەکەن. دوای گۆڕینی php.ini، Apache لە XAMPPـدا دابخە و دووبارە هەڵیبکەرەوە.
| Directiveڕێنمایی | PHP's defaultبنەڕەتی PHP | Meaningواتا |
|---|---|---|
file_uploads | On | Allow uploads at all.ڕێگەدان بە بە گشتی. |
upload_max_filesize | 2M | The largest single file. A bigger file arrives with error code 1.گەورەترین تاکە . گەورەتر بە کۆدی 1 دەگات. |
post_max_size | 8M | The largest whole request (all fields and files). Bigger: PHP empties $_POST and $_FILES.گەورەترین تەواو (هەموو و ). گەورەتر: PHP $_POST و $_FILES بەتاڵ دەکات. |
max_file_uploads | 20 | The most files in one request.زۆرترین ژمارەی لە یەک . |
<?php
echo "file_uploads: " . ini_get("file_uploads") . "\n";
echo "upload_max_filesize: " . ini_get("upload_max_filesize") . "\n";
echo "post_max_size: " . ini_get("post_max_size") . "\n";
echo "max_file_uploads: " . ini_get("max_file_uploads") . "\n";file_uploads: 1 upload_max_filesize: 2M post_max_size: 8M max_file_uploads: 20
These are PHP's own defaults. XAMPP's php.ini may use bigger values; run this on your computer to see yours.
ئەمانە بنەڕەتییەکانی خودی PHPـن. لەوانەیە php.ini ـی XAMPP بەهای گەورەتر بەکاربهێنێت؛ ئەمە لەسەر جێبەجێ بکە بۆ ئەوەی هی خۆت ببینیت.
Two ways to keep an uploaded fileدوو ڕێگا بۆ هەڵگرتنی فایلی بارکراو
The course names two methods for storing uploaded files:
کۆرسەکە ناوی دوو ڕێگا دەهێنێت بۆ هەڵگرتنی بارکراوەکان:
- Copy the file to a local folder and store its path in the database. The file sits in a folder such as
Uploads/; the keeps only its name or path. - Store the file itself in the database as a (Binary Large Object): the bytes of the file go into a column of type
LONGBLOB.
- بۆ ناوخۆیی کۆپی بکە و لە هەڵبگرە. لە وەک
Uploads/دایە؛ تەنها ناو یان هەڵدەگرێت. - خۆی لە وەک هەڵبگرە (Binary Large Object): دەچنە ناو لە جۆری
LONGBLOB.
Method 1 is the usual recommendation, and most of this lecture builds it (the slides show it in five steps). Method 2 is shown at the end, in Storing the file in the database (BLOB).
ڕێگای ١ ئامۆژگاریی باوە و زۆربەی ئەم وانەیە ئەو دروست دەکات ( لە پێنج هەنگاودا پیشانی دەدەن). ڕێگای ٢ لە کۆتاییدا پیشان دراوە، لە هەڵگرتنی فایل لە بنکەدراوەدا (BLOB).
Where the file goes: the temporary folderفایلەکە بۆ کوێ دەچێت: فۆڵدەری کاتی
When a form with a file arrives, PHP does not put the file where you want it. It saves it in a temporary folder (set by upload_tmp_dir in php.ini, or the system's temp folder) under a random name, for example /tmp/phpA1b2C3. Then it fills $_FILES with information about the file and runs your script.
کاتێک بە دەگات، PHP لەو شوێنەدا دانانێت کە تۆ دەتەوێت. لە کاتیدا بە ناوێکی هەڕەمەکی خەزنی دەکات، بۆ نموونە /tmp/phpA1b2C3 (ئەو بە upload_tmp_dir لە php.iniدا دیاری دەکرێت، یان کاتیی سیستەمەکەیە). پاشان $_FILES بە زانیاری دەربارەی پڕ دەکاتەوە و جێبەجێ دەکات.
This is a holding area. Your script looks at it and decides: keep it (move it with move_uploaded_file()) or not. If the script does not move it, PHP deletes the temporary file automatically when the request ends. So a rejected file simply disappears.
شوێنێکی ڕاگرتنە. سەیری دەکات و بڕیار دەدات: هەڵیبگرێت (بە move_uploaded_file() بیگوازێتەوە) یان نا. ئەگەر نەیگوازێتەوە، PHP لە کۆتایی خۆی دەسڕێتەوە. بۆیە ڕەتکراوە بە سادەیی ون دەبێت.
$_FILES: what PHP tells you about the file$_FILES: ئەوەی PHP دەربارەی فایلەکە پێت دەڵێت
The $_FILES superglobal holds information about the files that arrived with a POST request. For each file input it has an with six . $_FILES itself does not upload anything; the browser and PHP did that before your script started. Here is what PHP filled in when we uploaded cat.png through the form above:
$_FILES زانیاری دەربارەی ئەو هەڵدەگرێت کە لەگەڵ POST گەیشتوون. بۆ هەر بە شەش هەیە. $_FILES خۆی هیچ شتێک بار ناکات؛ و PHP پێش دەستپێکردنی ئەو کارەیان کردووە. ئەمە ئەوەیە کە PHP پڕی کردەوە کاتێک cat.pngمان لە ڕێگەی سەرەوە بار کرد:
<?php
echo "<pre>";
print_r($_FILES);
echo "</pre>";Array
(
[image] => Array
(
[name] => cat.png
[full_path] => cat.png
[type] => image/png
[tmp_name] => /tmp/phptm83pgd5ep2sffpBGei
[error] => 0
[size] => 123
)
)The tmp_name is random and changes with every upload.
tmp_name هەڕەمەکییە و لەگەڵ هەموو دەگۆڕێت.
| Key | What it holdsچی تێدایە | Can you trust it?دەتوانیت متمانەی پێ بکەیت؟ |
|---|---|---|
name | The original file name on the visitor's computer, e.g. cat.png.ناوی ڕەسەنی لەسەر سەردانکەر، بۆ نموونە cat.png. | No: the visitor chooses it.نەخێر: سەردانکەر هەڵیدەبژێرێت. |
full_path | The name with any folder part the browser sent (PHP 8.1+).ناوەکە لەگەڵ هەر بەشێکی کە ناردبێتی (PHP 8.1 و دواتر). | No.نەخێر. |
type | The that the browser claims, e.g. image/png.، بەو شێوەیەی دەیڵێت، بۆ نموونە image/png. | No: it can be faked.نەخێر: دەکرێت ساختە بکرێت. |
tmp_name | The path of the temporary file on the server. لەسەر . | Yes: PHP made it.بەڵێ: PHP دروستی کردووە. |
error | An error code; 0 (UPLOAD_ERR_OK) means the upload worked.کۆدێکی ؛ 0 (UPLOAD_ERR_OK) واتە سەرکەوتوو بوو. | Yes.بەڵێ. |
size | The size in bytes.قەبارەکە بە . | Yes: PHP measured it.بەڵێ: PHP پێوانەی کردووە. |
The deck's short example reads three of them:
نموونە کورتەکەی سێیان دەخوێنێتەوە:
<?php
if (isset($_FILES["photo"])) {
echo $_FILES["photo"]["name"] . "<br>";
echo $_FILES["photo"]["size"] . "<br>";
echo $_FILES["photo"]["type"] . "<br>";
}cat.png 123 image/png
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
cat.png<br>123<br>image/png<br>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Only read
$_FILESwhen a file was really sent.تەنها کاتێک
$_FILESبخوێنەوە کە بە ڕاستی نێردرابێت.
Shows the upload form and what the $_FILES array holds for an uploaded file: its name, type, temporary name, error and size.
پیشان دەدات و ئەوەی $_FILES بۆ بارکراو هەڵیدەگرێت: ناو، جۆر، ناوی کاتی، و قەبارەکەی.
Watch 0:05–2:39: the upload form and what $_FILES holds.
لە 0:05 تا 2:39 سەیر بکە: و ئەوەی $_FILES تێیدایە.
$_FILES: what PHP tells you about the file$_FILES: ئەوەی PHP دەربارەی فایلەکە پێت دەڵێت
Upload error codesکۆدەکانی هەڵەی بارکردن
The error key always holds one of these numbers. PHP gives each number a name (a constant), so you can write UPLOAD_ERR_OK instead of 0:
error هەمیشە یەکێک لەم ژمارانەی تێدایە. PHP ناوێک () دەدات بە هەر ژمارەیەک، بۆیە دەتوانیت لە جیاتی 0 بنووسیت UPLOAD_ERR_OK:
| Constant | Value | Meaningواتا |
|---|---|---|
UPLOAD_ERR_OK | 0 | No error: the file arrived.هیچ نییە: گەیشت. |
UPLOAD_ERR_INI_SIZE | 1 | Bigger than upload_max_filesize in php.ini.گەورەترە لە upload_max_filesize لە php.iniدا. |
UPLOAD_ERR_FORM_SIZE | 2 | Bigger than a MAX_FILE_SIZE field in the form.گەورەترە لە MAX_FILE_SIZE لە . |
UPLOAD_ERR_PARTIAL | 3 | Only part of the file arrived.تەنها بەشێکی گەیشت. |
UPLOAD_ERR_NO_FILE | 4 | No file was chosen.هیچ هەڵنەبژێردرا. |
UPLOAD_ERR_NO_TMP_DIR | 6 | The temporary folder is missing. کاتی نییە. |
UPLOAD_ERR_CANT_WRITE | 7 | The file could not be written to disk. نەتوانرا لەسەر دیسک بنووسرێت. |
UPLOAD_ERR_EXTENSION | 8 | A PHP extension stopped the upload. PHP ڕاگرت. |
Step 1: read the file's informationهەنگاوی ١: زانیارییەکانی فایلەکە بخوێنەوە
The course builds the upload script step by step. The first step checks whether the user clicked submit and puts each piece of information about the file into a . Here is that step, corrected, with a few echo lines so that you can see the values. We uploaded a photo called Erbil Photo.JPG:
کۆرسەکە هەنگاو بە هەنگاو دروست دەکات. هەنگاوی یەکەم دەپشکنێت ئایا کرتەی لە ناردن کردووە و هەر پارچە زانیارییەک دەربارەی دەخاتە ناو . ئەمە ئەو هەنگاوەیە، ڕاستکراوە، لەگەڵ چەند دێڕێکی echo بۆ ئەوەی ببینیت. وێنەیەکمان بە ناوی Erbil Photo.JPG بار کرد:
<?php
if (isset($_POST["submit"])) { // did the user click the submit button?
$target_dir = "Uploads/"; // the folder where files are saved
$errors = []; // collects error messages
$file_name = basename($_FILES["image"]["name"]); // the file's original name
$file_size = $_FILES["image"]["size"]; // its size in bytes
$file_tmp = $_FILES["image"]["tmp_name"]; // where PHP keeps it for now
$file_type = $_FILES["image"]["type"]; // type sent by the browser: do not trust it
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION)); // e.g. "jpg"
$target_file = $target_dir . $file_name; // the path we plan to save to
$extensions = ["jpeg", "jpg", "png"]; // allowed extensions
echo "Name: $file_name<br>";
echo "Size: $file_size bytes<br>";
echo "Temporary file: $file_tmp<br>";
echo "Type (from the browser): $file_type<br>";
echo "Extension: $file_ext<br>";
echo "Target: $target_file<br>";
}Name: Erbil Photo.JPG Size: 653 bytes Temporary file: /tmp/phpcvg2s2k7tu90chpbbKk Type (from the browser): image/jpeg Extension: jpg Target: Uploads/Erbil Photo.JPG
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Name: Erbil Photo.JPG<br>Size: 653 bytes<br>Temporary file: /tmp/phpcvg2s2k7tu90chpbbKk<br>Type (from the browser): image/jpeg<br>Extension: jpg<br>Target: Uploads/Erbil Photo.JPG<br>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Check if the user clicked submit. Everything else is inside this
if, so a normal visit does not touch$_FILES.بپشکنە ئایا کرتەی لە ناردن کردووە. هەموو شتێکی تر لەناو ئەم
ifـەدایە، بۆیە سەردانێکی ئاسایی دەست لە$_FILESنادات.- Lineدێڕی 3
The folder where the file should be saved. It must exist; the name is case-sensitive on Linux (
Uploadsis notuploads).ئەو دەبێت تێیدا خەزن بکرێت. دەبێت هەبێت؛ لەسەر Linux ناوەکە هەستیارە بە پیتی گەورە و بچووک (
Uploadsهەمانuploadsنییە).- Lineدێڕی 4
Collects error messages (an empty array).
کۆ دەکاتەوە ( بەتاڵ).
- Lineدێڕی 5
Get the file name.
basename()removes any folder part.ناوی وەربگرە.
basename()هەر بەشێکی لادەبات.- Lineدێڕی 6
Get the selected file's size in bytes.
قەبارەی هەڵبژێردراوەکە بە وەربگرە.
- Lineدێڕی 7
Get the temporary file name.
ناوی وەربگرە.
- Lineدێڕی 8
Get the file type, as the browser reports it.
وەربگرە، وەک دەیڵێت.
- Lineدێڕی 9
Get the file extension in lower case.
بە پیتی بچووک وەربگرە.
- Lineدێڕی 10
Build the path where the file will be saved. This line only builds a string;
move_uploaded_file()saves the file later.ئەو دروست بکە کە تێیدا خەزن دەکرێت. ئەم دێڕە تەنها دروست دەکات؛ دواتر
move_uploaded_file()خەزن دەکات.- Lineدێڕی 11
The array of allowed extensions.
کە ڕێگەپێدراون.
Step 1: read the file's informationهەنگاوی ١: زانیارییەکانی فایلەکە بخوێنەوە
Getting the extension: pathinfo() instead of end(explode())وەرگرتنی پاشگری فایل: pathinfo() لە جیاتی end(explode())
The course gets the extension with strtolower(end(explode('.', $name))). explode() breaks a string into an array at each dot; end() takes the last element; strtolower() makes it lower case:
کۆرسەکە بە strtolower(end(explode('.', $name))) وەردەگرێت. explode() لە هەر خاڵێکدا دەشکێنێت بۆ ؛ end() کۆتا وەردەگرێت؛ strtolower() دەیکاتە پیتی بچووک:
<?php
print_r(explode('.', "my.cat.png"));Array
(
[0] => my
[1] => cat
[2] => png
)But end() needs a real variable, because it moves the array's internal pointer. Given the result of a function directly, PHP 7 and 8 print a notice:
بەڵام end() پێویستی بە ڕاستەقینە هەیە، چونکە ئاماژەی ناوەکیی دەجووڵێنێت. ئەگەر ڕاستەوخۆ ئەنجامی پێبدرێت، PHP 7 و 8 ئاگادارییەک چاپ دەکەن:
<?php
$file_ext = strtolower(end(explode('.', "photo.png")));
echo $file_ext;Notice: Only variables should be passed by reference in /var/www/html/extension.php on line 2 png
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<br />
<b>Notice</b>: Only variables should be passed by reference in <b>/var/www/html/extension.php</b> on line <b>2</b><br />
pngUse pathinfo() instead; it was made for this job. (Or store the parts in a variable first, as the second line of this example does.)
لە جیاتی ئەوە pathinfo() بەکاربهێنە؛ بۆ ئەم کارە دروست کراوە. (یان سەرەتا پارچەکان لە هەڵبگرە، وەک دێڕی دووەمی ئەم نموونەیە دەیکات.)
<?php
$name = "Holiday.Photo.JPG";
$parts = explode('.', $name); // ["Holiday", "Photo", "JPG"]
echo strtolower(end($parts)), "<br>"; // jpg
echo strtolower(pathinfo($name, PATHINFO_EXTENSION)), "<br>"; // jpg
echo "[" . pathinfo("README", PATHINFO_EXTENSION) . "]"; // no dot: emptyjpg jpg []
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
jpg<br>jpg<br>[]Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 5
A name without a dot has no extension:
pathinfo()returns an empty string. (Theend(explode())way would return the whole name,readme.)ناوێک بەبێ خاڵ هیچ نییە:
pathinfo()بەتاڵ دەگەڕێنێتەوە. (ڕێگایend(explode())هەموو ناوەکە دەگەڕێنێتەوە،readme.)
Step 1: read the file's informationهەنگاوی ١: زانیارییەکانی فایلەکە بخوێنەوە
basename(): the file name from a pathbasename(): ناوی فایل لە ڕێڕەوێکەوە
The basename() function gets the file name from a . It takes the path as an and returns the last part of the path, which is usually the file name:
basename() بەکار دێت بۆ بەدەستهێنانی ناوی لە . وەک وەردەگرێت، دواتر دوایین بەشی دەهێنێتەوە کە بەگشتی بریتییە لە ناوی :
<?php
$path = '/var/www/html/index.php';
$filename = basename($path);
echo $filename; // Outputs: index.phpindex.php
To remove the as well, give the extension as a in the second argument:
ئەگەر بتەوێت لابەیت، واتە ناوی بەبێ وەربگریت، دەتوانیت لە دووەمدا وەک دیاری بکەیت:
<?php
$path = '/var/www/html/index.php';
$filename = basename($path, '.php');
echo $filename; // Outputs: indexindex
In uploads, basename() makes sure that a name like ../../config.php cannot climb out of your folder:
لە ، basename() دڵنیا دەبێتەوە کە ناوێکی وەک ../../config.php ناتوانێت لە دەربچێت:
<?php
echo basename("Uploads/sub/pic.png"), "<br>";
echo basename("../../config.php"), "<br>";
echo basename("holiday photo.JPG"), "<br>";pic.png config.php holiday photo.JPG
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
pic.png<br>config.php<br>holiday photo.JPG<br>Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
Now we can add some restrictions. Each check below adds a message to $errors when something is wrong. After all checks, the file is moved only if $errors is still empty (see Every check must stop the upload).
ئێستا دەتوانین هەندێک سنوور زیاد بکەین. هەر پشکنینێکی خوارەوە کاتێک شتێک هەڵە بێت پەیامێک بۆ $errors زیاد دەکات. دوای هەموو پشکنینەکان، تەنها ئەو کاتە دەگوازرێتەوە کە $errors هێشتا بەتاڵ بێت (بڕوانە هەموو پشکنینێک دەبێت بارکردنەکە ڕابگرێت).
Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
Did the upload work?ئایا بارکردنەکە سەرکەوتوو بوو؟
Before anything else, look at the error key. Only UPLOAD_ERR_OK (0) means that a complete file is waiting in the temporary folder.
پێش هەموو شتێک، سەیری error بکە. تەنها UPLOAD_ERR_OK (0) واتای ئەوەیە کە تەواو لە کاتییەکەدا چاوەڕێ دەکات.
// Did the upload itself work?
if ($_FILES["image"]["error"] !== UPLOAD_ERR_OK) {
$errors[] = "The upload failed (error code " . $_FILES["image"]["error"] . ").";
}With PHP's default upload_max_filesize = 2M, our 3 MB picture did not even reach the script's checks: PHP stopped it and set the error code to 1. The complete script below shows:
بە بنەڕەتیی PHP، واتە upload_max_filesize = 2M، وێنە ٣ مێگابایتییەکەمان نەگەیشتە پشکنینەکانی : PHP ڕایگرت و کۆدی کردە 1. تەواوەکەی خوارەوە پیشان دەدات:
Upload a photo The upload failed (error code 1).
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: red">The upload failed (error code 1).</p>Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
Does the file already exist?ئایا فایلەکە پێشتر هەیە؟
First, we check whether a file with the same name already exists in the Uploads folder. If it does, an error message is added, so that the new file does not silently replace the old one:
سەرەتا دەپشکنین ئایا بە هەمان ناو پێشتر لە Uploadsدا هەیە. ئەگەر هەبێت، زیاد دەکرێت، بۆ ئەوەی نوێیەکە بە بێدەنگی جێی کۆنەکە نەگرێتەوە:
// Check if the file already exists
if (file_exists($target_file)) {
$errors[] = "Sorry, this file already exists.";
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
file_exists()returnstrueif a file or folder with this path exists.file_exists()ئەگەر یان بەم هەبێتtrueدەگەڕێنێتەوە.
In the safe version at the end of this lecture, every file gets a new random name, so two uploads can no longer have the same name; the file_exists() check stays only as a safety net.
لە وەشانە سەلامەتەکەی کۆتایی ئەم وانەیەدا، هەموو ناوێکی نوێی هەڕەمەکی وەردەگرێت، بۆیە ئیتر دوو ناتوانن هەمان ناویان هەبێت؛ پشکنینی file_exists() تەنها وەک تۆڕی سەلامەتی دەمێنێتەوە.
Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
Limit the file sizeقەبارەی فایل سنووردار بکە
Next, we check the size of the file. If the file is larger than 500,000 bytes (about 500 KB), an error message is added:
دواتر قەبارەی دەپشکنین. ئەگەر لە ٥٠٠،٠٠٠ (نزیکەی ٥٠٠ ) گەورەتر بێت، زیاد دەکرێت:
// Check the file size (here: at most 500000 bytes)
if ($file_size > 500000) {
$errors[] = "Sorry, your file is too large.";
}The course uses three different limits. Here is what they mean (1 KB = 1024 bytes, 1 MB = 1024 KB):
کۆرسەکە سێ سنووری جیاواز بەکار دەهێنێت. ئەمە واتاکەیانە (١ = ١٠٢٤ ، ١ = ١٠٢٤ ):
<?php
echo 500000 / 1024, " KB<br>";
echo 2 * 1024 * 1024, " bytes<br>";
echo 5000000 / (1024 * 1024), " MB<br>";488.28125 KB 2097152 bytes 4.7683715820312 MB
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
488.28125 KB<br>2097152 bytes<br>4.7683715820312 MB<br>| Limit in the codeسنوور لە کۆدەکەدا | Whereلە کوێ | In KB / MBبە / |
|---|---|---|
500000 | Lecture 6 and Lab 6, size checkوانەی ٦ و تاقیگەی ٦، پشکنینی قەبارە | about 488 KBنزیکەی ٤٨٨ |
2097152 | Complete scripts (lecture, lab, summary) تەواوەکان (وانە، تاقیگە، پوختە) | exactly 2 MB (2 × 1024 × 1024)ڕێک ٢ (2 × 1024 × 1024) |
5000000 | A student's practice codeکۆدی ڕاهێنانی قوتابییەک | about 4.77 MBنزیکەی ٤.٧٧ |
Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
Limit the file typeجۆری فایل سنووردار بکە
Then we allow only certain file types. First we create an array of allowed extensions; after that we check whether the file's extension appears in the list:
پاشان تەنها ڕێگە بە هەندێک دەدەین. سەرەتا لە کە ڕێگەپێدراون دروست دەکەین؛ دوای ئەوە دەپشکنین ئایا لە لیستەکەدا هەیە:
// Allow only certain file extensions
$extensions = ["jpeg", "jpg", "png"];
if (in_array($file_ext, $extensions) === false) {
$errors[] = "Extension not allowed, please choose a JPEG or PNG file.";
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
in_array()returnstrueif the value is in the array.=== falsemeans "not in the list".in_array()ئەگەر لە بێتtrueدەگەڕێنێتەوە.=== falseواتە «لە لیستەکەدا نییە».
The triple equals sign === checks that two values are equal and of the same type:
نیشانەی سێ یەکسانی === دەپشکنێت کە دوو یەکسانن و هەمان جۆریان هەیە:
<?php
var_dump(0 == false); // same value after conversion
var_dump(0 === false); // different types: integer and booleanbool(true) bool(false)
Step 2: check the fileهەنگاوی ٢: فایلەکە بپشکنە
The extension is not proof: check the real typeپاشگری فایل بەڵگە نییە: جۆری ڕاستەقینە بپشکنە
A file's name and its type are chosen by the visitor. Anyone can rename shell.php to cat.jpg, and the browser will happily report image/jpeg. To know what a file really is, look at its content. PHP's fileinfo functions read the first bytes of the file and give its real :
ناو و typeی لەلایەن سەردانکەرەوە هەڵدەبژێردرێن. هەر کەسێک دەتوانێت ناوی shell.php بگۆڕێت بۆ cat.jpg و بە خۆشحاڵییەوە image/jpeg ڕادەگەیەنێت. بۆ ئەوەی بزانیت بە ڕاستی چییە، سەیری ناوەڕۆکەکەی بکە. fileinfo لە PHPـدا یەکەم دەخوێننەوە و جۆری ڕاستەقینەی () دەدەن:
<?php
$finfo = finfo_open(FILEINFO_MIME_TYPE);
foreach (["cat.png", "erbil.jpg", "fake.jpg", "notes.txt"] as $file) {
echo $file . " is really: " . finfo_file($finfo, $file) . "<br>\n";
}cat.png is really: image/png erbil.jpg is really: image/jpeg fake.jpg is really: text/x-php notes.txt is really: text/plain
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
cat.png is really: image/png<br>
erbil.jpg is really: image/jpeg<br>
fake.jpg is really: text/x-php<br>
notes.txt is really: text/plain<br>fake.jpg is a text file that contains PHP code. Its name says .jpg, but finfo sees text/x-php.
fake.jpg دەقییە کە کۆدی PHPـی تێدایە. ناوەکەی دەڵێت .jpg، بەڵام finfo text/x-php دەبینێت.
Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
Open the fileinfo database once.
fileinfo یەکجار بکەرەوە.
- Lineدێڕی 4
finfo_file()returns the real type of the content.finfo_file()جۆری ڕاستەقینەی ناوەڕۆکەکە دەگەڕێنێتەوە.
// Check the real type of the file's content
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$realType = finfo_file($finfo, $file_tmp);
if (!in_array($realType, ["image/jpeg", "image/png"], true)) {
$errors[] = "This file is not a real JPEG or PNG picture.";
}Every check must stop the uploadهەموو پشکنینێک دەبێت بارکردنەکە ڕابگرێت
The course's complete script puts the steps together, and ends with move_uploaded_file(temp, destination), which moves the uploaded temporary file to the target folder. It prints "Success" if $errors is empty, and the collected errors otherwise. But look closely: each check only echoes its message. Nothing is ever added to $errors, so empty($errors) is always true. Here is the slide's script, with only the missing } added, tested with a 9 MB file called virus.exe:
تەواوەکەی کۆرسەکە هەنگاوەکان پێکەوە دادەنێت و بە move_uploaded_file(temp, destination) کۆتایی دێت، کە کاتییە بارکراوەکە دەگوازێتەوە بۆ ئامانج. ئەگەر $errors بەتاڵ بێت «Success» چاپ دەکات، دەنا هەڵە کۆکراوەکان. بەڵام بە وردی سەیر بکە: هەر پشکنینێک تەنها پەیامەکەی echo دەکات. هەرگیز هیچ شتێک بۆ $errors زیاد ناکرێت، بۆیە empty($errors) هەمیشە ڕاستە. ئەمە ، تەنها }ی لەبیرکراوی بۆ زیاد کراوە و بە ٩ بە ناوی virus.exe تاقیکراوەتەوە:
}ی لەبیرکراوی بۆ زیاد کراوە (بەکاری مەهێنە)upload.phpPHPRuns on the serverلەسەر ڕاژەکاری وێب کار دەکات<?php if(isset($_POST['submit'])){
$target_dir="Uploads/";
$errors="";
$file_name = $_FILES['image']['name'];
$file_size =$_FILES['image']['size'];
$file_tmp =$_FILES['image']['tmp_name'];
$file_type=$_FILES['image']['type'];
$file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
$target=$target_dir.basename($file_name);
$expensions= array("jpeg","jpg","png");
if (file_exists($target)) {
echo "this file already exist<br>";
}
if (in_array($file_ext, $expensions) === false)
{
echo "extension not allowed, please choose a JPEG or PNG file.<br>";
}
if ($file_size > 2097152) {
echo 'File size must be excately 2 MB<br>';
}
if (empty($errors) == true) {
move_uploaded_file($file_tmp, $target_dir . $file_name);
echo "Success";
} else {
print($errors);
}
}
?>Notice: Only variables should be passed by reference in /var/www/html/upload.php on line 8 extension not allowed, please choose a JPEG or PNG file. File size must be excately 2 MB Success
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<br />
<b>Notice</b>: Only variables should be passed by reference in <b>/var/www/html/upload.php</b> on line <b>8</b><br />
extension not allowed, please choose a JPEG or PNG file.<br>File size must be excately 2 MB<br>SuccessBoth errors are printed, and then "Success": virus.exe was really saved in the Uploads folder.
هەردوو چاپ دەکرێن و پاشان «Success»: virus.exe بە ڕاستی لە Uploads خەزن کرا.
There are two correct ways to make every check block the upload.
دوو ڕێگای دروست هەیە بۆ ئەوەی هەموو پشکنینێک ڕابگرێت.
Every check must stop the uploadهەموو پشکنینێک دەبێت بارکردنەکە ڕابگرێت
Way 1: collect the errors, move only when there are noneڕێگای ١: هەڵەکان کۆ بکەرەوە، تەنها کاتێک هیچ نییە بیگوازەرەوە
Every check adds its message to $errors (the summary does this correctly with $errors .= "...", and so does the lecture's extension check). At the end, the file is moved only if $errors is empty. The visitor sees all problems at once.
هەموو پشکنینێک پەیامەکەی بۆ $errors زیاد دەکات (پوختەکە ئەمە بە دروستی بە $errors .= "..." دەکات، هەروەها پشکنینی وانەکەش). لە کۆتاییدا تەنها ئەو کاتە دەگوازرێتەوە کە $errors بەتاڵ بێت. سەردانکەر هەموو کێشەکان پێکەوە دەبینێت.
// Only when there are no errors: move the file and check the result
if (empty($errors)) {
if (move_uploaded_file($file_tmp, $target_file)) {
echo "Success! The file was uploaded.";
} else {
echo "Sorry, the file could not be saved.";
}
} else {
foreach ($errors as $error) {
echo $error . "<br>";
}
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
move_uploaded_file()takes exactly two arguments: the temporary file and the destination path. It returnstrueorfalse.move_uploaded_file()ڕێک دوو وەردەگرێت: و شوێنی مەبەست.trueیانfalseدەگەڕێنێتەوە.- Lineدێڕی 9-11
Show every collected message.
هەموو پەیامە کۆکراوەکان پیشان بدە.
Every check must stop the uploadهەموو پشکنینێک دەبێت بارکردنەکە ڕابگرێت
Way 2: one if/elseif chain (the lab's complete version)ڕێگای ٢: یەک زنجیرەی if/elseif (وەشانە تەواوەکەی تاقیگە)
Lab 6's final page uses one if/elseif chain: the first failing check prints its message, and the else at the end (which moves the file) runs only if no check failed. Here it is with the small fixes (pathinfo, basename(), clear messages, and a check of the move's result):
لاپەڕە کۆتاییەکەی تاقیگەی ٦ یەک زنجیرەی if/elseif بەکار دەهێنێت: یەکەم پشکنینی شکستخواردوو پەیامەکەی چاپ دەکات و لە کۆتاییدا (کە دەگوازێتەوە) تەنها ئەو کاتە جێبەجێ دەکرێت کە هیچ پشکنینێک شکستی نەهێنابێت. ئەمە بە چاکسازییە بچووکەکانەوەیە (pathinfo، basename()، پەیامی ڕوون و پشکنینی ئەنجامی گواستنەوەکە):
<?php
if (isset($_POST['submit'])) {
$target_dir = "Uploads/";
$file_name = basename($_FILES['image']['name']);
$file_size = $_FILES['image']['size'];
$file_tmp = $_FILES['image']['tmp_name'];
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
$target = $target_dir . $file_name;
$extensions = array("jpeg", "jpg", "png");
if (empty($file_name)) {
echo "Please select a file.";
} elseif (file_exists($target)) {
echo "Sorry, this file already exists.";
} elseif (in_array($file_ext, $extensions) === false) {
echo "Extension not allowed, please choose a JPEG or PNG file.";
} elseif ($file_size > 2097152) {
echo "The file must not be bigger than 2 MB.";
} elseif (move_uploaded_file($file_tmp, $target)) {
echo "Success";
} else {
echo "Sorry, the file could not be saved.";
}
}
?>
<!DOCTYPE html>
<html>
<body>
<form action="index.php" method="POST" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" name="submit">
</form>
</body>
</html>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 24-31
The form from the lab sheet. It posts to
index.php, so the PHP and the form must be saved together inindex.php. The lab's page stops after</form>; close</body>and</html>too.پەڕەی تاقیگەکە. بۆ
index.phpدەنێرێت، بۆیە PHPـەکە و دەبێت پێکەوە لەindex.phpدا خەزن بکرێن. لاپەڕەکەی تاقیگە دوای</form>دەوەستێت؛</body>و</html>یش دابخە.
| Uploaded file بارکراو | Output |
|---|---|
virus.exe (9 MB) | Extension not allowed, please choose a JPEG or PNG file. |
cat.png | Success |
cat.png (again) | Sorry, this file already exists. |
Way 1 tells the visitor about every problem at once; way 2 tells them about the first problem only. Both are correct, because in both the move happens only when every check has passed.
ڕێگای ١ دەربارەی هەموو کێشەکان پێکەوە بە سەردانکەر دەڵێت؛ ڕێگای ٢ تەنها دەربارەی یەکەم کێشە. هەردووکیان دروستن، چونکە لە هەردووکیاندا گواستنەوەکە تەنها ئەو کاتە ڕوودەدات کە هەموو پشکنینێک تێپەڕیبێت.
The complete, safe upload pageلاپەڕەی بارکردنی تەواو و سەلامەت
Here is the whole upload page in one file, index.php, with the form at the bottom and the PHP at the top. It keeps the course's checks (submit, existing file, size, extension) and adds the protections that a real site needs: it checks the error key and the real type, never uses the visitor's file name on the disk, and checks the result of move_uploaded_file().
ئەمە هەموو لاپەڕەی لە یەک ، index.php، لە خوارەوە و PHPـەکە لە سەرەوە. پشکنینەکانی کۆرسەکە دەهێڵێتەوە (ناردن، هەبوو، قەبارە، ) و ئەو پاراستنانەی زیاد دەکات کە ڕاستەقینە پێویستی پێیانە: error و جۆری ڕاستەقینە دەپشکنێت، هەرگیز ناوی سەردانکەر لەسەر دیسک بەکار ناهێنێت و ئەنجامی move_uploaded_file() دەپشکنێت.
<?php
// index.php - upload a photo (JPEG or PNG, at most 2 MB)
$uploadDir = __DIR__ . "/Uploads/"; // the folder must exist
$maxSize = 2097152; // 2 MB = 2 * 1024 * 1024 bytes
$extensions = ["jpeg", "jpg", "png"]; // allowed file extensions
$mimeTypes = ["image/jpeg", "image/png"]; // allowed real file types
$errors = []; // collects error messages
$message = "";
if (isset($_POST["submit"])) {
$file = $_FILES["image"] ?? null;
if ($file === null || $file["error"] === UPLOAD_ERR_NO_FILE) {
$errors[] = "Please select a file.";
} elseif ($file["error"] !== UPLOAD_ERR_OK) {
$errors[] = "The upload failed (error code " . $file["error"] . ").";
} else {
$originalName = basename($file["name"]);
$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
if (!in_array($ext, $extensions, true)) {
$errors[] = "Extension not allowed. Please choose a JPEG or PNG file.";
}
if ($file["size"] > $maxSize) {
$errors[] = "The file is too large. It must not be bigger than 2 MB.";
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$realType = finfo_file($finfo, $file["tmp_name"]);
if (!in_array($realType, $mimeTypes, true)) {
$errors[] = "This file is not a real JPEG or PNG picture.";
}
if (empty($errors)) {
// a new, random name: the visitor cannot choose it
$newName = bin2hex(random_bytes(16)) . "." . $ext;
$target = $uploadDir . $newName;
if (file_exists($target)) {
$errors[] = "Sorry, this file already exists.";
} elseif (move_uploaded_file($file["tmp_name"], $target)) {
$message = "Success! " . htmlspecialchars($originalName) . " was uploaded.";
} else {
$errors[] = "Sorry, the file could not be saved.";
}
}
}
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Upload a photo</h1>
<?php
foreach ($errors as $error) {
echo "<p style=\"color: red\">$error</p>\n";
}
if ($message !== "") {
echo "<p style=\"color: green\">$message</p>\n";
}
?>
<form action="index.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" accept=".jpg,.jpeg,.png">
<input type="submit" name="submit" value="Upload Image">
</form>
</body>
</html>Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-8
Settings in one place: the folder, the size limit, the allowed extensions and real types, and the list of errors.
لە یەک شوێندا: ، سنووری قەبارە، و جۆرە ڕاستەقینە ڕێگەپێدراوەکان و لیستی .
- Lineدێڕی 11
??givesnullwhen there is noimagefile at all (for example a form without enctype).??کاتێک هیچimageنەبێتnullدەدات (بۆ نموونە بەبێ enctype).- Lineدێڕی 13-16
No file chosen, or the upload failed: stop here.
هیچ هەڵنەبژێردراوە، یان شکستی هێنا: لێرە بوەستە.
- Lineدێڕی 18-19
Never trust the name: keep only the last part, and take the extension with
pathinfo().هەرگیز متمانە بە ناوەکە مەکە: تەنها بەشی کۆتایی بهێڵەوە و بە
pathinfo()وەربگرە.- Lineدێڕی 21-31
Three checks; each one adds a message.
سێ پشکنین؛ هەر یەکێکیان پەیامێک زیاد دەکات.
- Lineدێڕی 27-28
The real type, read from the file's content.
جۆری ڕاستەقینە، کە لە ناوەڕۆکی خوێندراوەتەوە.
- Lineدێڕی 33
Move only when there is no error.
تەنها کاتێک هیچ نییە بیگوازەرەوە.
- Lineدێڕی 35
A new random name such as
9f86d081...c3.png. The visitor cannot choose it, and two uploads never collide.ناوێکی نوێی هەڕەمەکی وەک
9f86d081...c3.png. سەردانکەر ناتوانێت هەڵیبژێرێت و دوو هەرگیز تێکهەڵناچن.- Lineدێڕی 38-44
The course's exists check stays as a safety net; then move, and check that it worked.
پشکنینی هەبوونی کۆرسەکە وەک تۆڕی سەلامەتی دەمێنێتەوە؛ پاشان بیگوازەرەوە و بپشکنە کە کاری کرد.
- Lineدێڕی 41
The original name is shown with
htmlspecialchars(), because a file name can contain HTML.ناوە ڕەسەنەکە بە
htmlspecialchars()پیشان دەدرێت، چونکە ناوی دەتوانێت HTMLـی تێدابێت.- Lineدێڕی 61
The form:
postandmultipart/form-data;acceptonly helps the visitor choose.:
postوmultipart/form-data؛acceptتەنها یارمەتیی سەردانکەر دەدات بۆ هەڵبژاردن.
The complete, safe upload pageلاپەڕەی بارکردنی تەواو و سەلامەت
Tested with six uploadsتاقیکراوەتەوە بە شەش بارکردن
We sent six requests to the complete index.php. The messages below are the part of each page that changed:
شەش بۆ index.phpـە تەواوەکە نارد. پەیامەکانی خوارەوە ئەو بەشەی هەر لاپەڕەیەکن کە گۆڕا:
Upload a photo Select image to upload: [Choose File] No file chosen [Upload Image]
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<!DOCTYPE html>
<html>
<body>
<h1>Upload a photo</h1>
<form action="index.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" accept=".jpg,.jpeg,.png">
<input type="submit" name="submit" value="Upload Image">
</form>
</body>
</html>Upload a photo Success! cat.png was uploaded.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: green">Success! cat.png was uploaded.</p>Upload a photo This file is not a real JPEG or PNG picture.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: red">This file is not a real JPEG or PNG picture.</p>Upload a photo Extension not allowed. Please choose a JPEG or PNG file. The file is too large. It must not be bigger than 2 MB. This file is not a real JPEG or PNG picture.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: red">Extension not allowed. Please choose a JPEG or PNG file.</p>
<p style="color: red">The file is too large. It must not be bigger than 2 MB.</p>
<p style="color: red">This file is not a real JPEG or PNG picture.</p>Upload a photo The file is too large. It must not be bigger than 2 MB.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: red">The file is too large. It must not be bigger than 2 MB.</p>Upload a photo Please select a file.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<h1>Upload a photo</h1>
<p style="color: red">Please select a file.</p>These tests ran with upload_max_filesize and post_max_size set to 40M. Afterwards the Uploads folder held exactly one new file, 6fc3301d....png: only the real picture was kept, under a random name.
ئەم تاقیکردنەوانە بە upload_max_filesize و post_max_size ـی 40M جێبەجێ کران. دواتر Uploads ڕێک یەک نوێی تێدابوو، 6fc3301d....png: تەنها وێنە ڕاستەقینەکە هەڵگیرا، بە ناوێکی هەڕەمەکی.
The complete, safe upload pageلاپەڕەی بارکردنی تەواو و سەلامەت
Keep uploaded files from runningڕێگە مەدە فایلەکان بارکراوەکان جێبەجێ بکرێن
The Uploads folder is inside your website, so anyone can open a file in it with its address. Even with all the checks, store uploads so that they can never run as a program. There are two ways:
Uploads لەناو ، بۆیە هەر کەسێک دەتوانێت ناوی بە ناونیشانەکەی بکاتەوە. تەنانەت لەگەڵ هەموو پشکنینەکانیش، بارکراوەکان بە شێوەیەک هەڵبگرە کە هەرگیز نەتوانن وەک جێبەجێ بکرێن. دوو ڕێگا هەیە:
- Best: keep them outside the web root. The web root is the public folder that the server shows to everyone ( in XAMPP). A folder next to it, such as
C:\xampp\private_uploads, cannot be opened from a browser at all; a small PHP page sends the pictures when needed (see the next section). - If the folder must stay inside the website, block scripts in it. On Apache (XAMPP) put this
.htaccessfile insideUploads/:
- باشترین: لە دەرەوەی ڕەگی وێب هەڵیانبگرە. ڕەگی وێب ئەو گشتییەیە کە بە هەمووانی پیشان دەدات ( لە XAMPPـدا). لە تەنیشتیەوە، وەک
C:\xampp\private_uploads، هەرگیز لە ناکرێتەوە؛ لاپەڕەیەکی بچووکی PHP کاتێک پێویست بوو وێنەکان دەنێرێت (بەشی داهاتوو ببینە). - ئەگەر دەبێت لەناو بمێنێتەوە، تێدا ڕابگرە. لەسەر Apache (XAMPP) ئەم
.htaccessـە بخە ناوUploads/ەوە:
# Uploads/.htaccess - this folder only stores pictures
# 1. Never run or send any PHP file from this folder
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
# 2. Do not show a list of the files in this folder
Options -IndexesExplain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3-5
Refuse every request for a PHP file in this folder, so an uploaded script can never run.
هەموو بۆ PHP لەم ڕەت بکەرەوە، بۆ ئەوەی بارکراو هەرگیز جێبەجێ نەبێت.
- Lineدێڕی 7
Do not show a list of the folder's files.
لیستی پیشان مەدە.
Showing files that are stored outside the web rootپیشاندانی ئەو فایلانەی لە دەرەوەی ڕەگی وێب هەڵگیراون
If the pictures are in private_uploads, next to the web root, the browser cannot open them by address. A small script reads the file and sends it, with the right Content-Type . It uses basename() so that the visitor can only ask for a file inside that folder:
ئەگەر وێنەکان لە private_uploadsدا بن، لە تەنیشت ڕەگی وێبەوە، ناتوانێت بە ناونیشان بیانکاتەوە. بچووک دەخوێنێتەوە و دەینێرێت، لەگەڵ Content-Typeی دروست. basename() بەکار دەهێنێت بۆ ئەوەی سەردانکەر تەنها بتوانێت داوای بکات کە لەناو ئەو :
<?php
// photo.php?name=... sends one stored photo to the browser
$dir = dirname(__DIR__) . "/private_uploads/"; // outside the web root
$name = basename($_GET["name"] ?? ""); // basename() blocks "../" tricks
$path = $dir . $name;
if ($name === "" || !is_file($path)) {
http_response_code(404);
exit("Photo not found.");
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
header("Content-Type: " . finfo_file($finfo, $path));
readfile($path);Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 3
dirname(__DIR__)is the folder above the web root.dirname(__DIR__)ئەو کە لە سەرووی ڕەگی وێبەوەیە.- Lineدێڕی 8-9
Unknown name: answer 404 (Not Found) and stop.
ناوی نەناسراو: بە 404 (Not Found) وەڵام بدەرەوە و بوەستە.
- Lineدێڕی 12-14
Tell the browser the real type, then send the file's bytes.
جۆرە ڕاستەقینەکە بە بڵێ، پاشان بنێرە.
| Request | Statusدۆخ | Content-Type |
|---|---|---|
photo.php?name=dac0e95b...54.png | 200 | image/png |
photo.php?name=../html/photo.php | 404 (Photo not found.) | text/html; charset=UTF-8 |
In the HTML page you then write <img src="photo.php?name=...">, using the stored name from your database.
پاشان لە لاپەڕەی HTMLـدا دەنووسیت <img src="photo.php?name=...">، بە بەکارهێنانی ئەو ناوەی لە هەڵگیراوە.
Storing the file in the database (BLOB)هەڵگرتنی فایل لە بنکەدراوەدا (BLOB)
The alternate method stores the file's bytes inside a . The course gives four steps:
ڕێگا جێگرەوەکە لەناو هەڵدەگرێت. کۆرسەکە چوار هەنگاو دەدات:
- Step 1: create a table with a LONGBLOB columnهەنگاوی ١: خشتەیەک بە ستوونێکی LONGBLOB دروست بکە
A
LONGBLOBcolumn holds up to 4 GB of binary data. Store the name and the real type next to it, so that you can send the file back later.LONGBLOBتا ٤ دووانەیی هەڵدەگرێت. ناو و جۆرە ڕاستەقینەکەش لە تەنیشتیەوە هەڵبگرە، بۆ ئەوەی دواتر بتوانیت بنێریتەوە.SQLRuns in the databaseلە ناو بنکەدراوە کار دەکات CREATE TABLE uploads ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, type VARCHAR(100) NOT NULL, data LONGBLOB NOT NULL ); - Step 2: prepare the fileهەنگاوی ٢: فایلەکە ئامادە بکە
Run the same checks as before. Then
file_get_contents()reads the entire file into a string. (filesize()returns the file size, if you need it.)هەمان پشکنینەکانی پێشوو جێبەجێ بکە. پاشان
file_get_contents()هەموو دەخوێنێتەوە بۆ ناو . (filesize()قەبارەی دەگەڕێنێتەوە، ئەگەر پێویستت پێی بێت.) - Step 3: create and run the query, as a prepared statementهەنگاوی ٣: پرسەکە دروست بکە و جێبەجێی بکە، وەک ڕستەی ئامادەکراو
Send the data as a parameter of a , never inside the SQL text.
وەک بنێرە، هەرگیز لەناو دەقی SQLـدا نا.
- Step 4: tell the userهەنگاوی ٤: بە بەکارهێنەر بڵێ
Check all the previous factors and display an appropriate message to the user.
هەموو هۆکارەکانی پێشوو بپشکنە و پەیامێکی گونجاو بە پیشان بدە.
<?php
require 'dbcon.php'; // gives $con, the MySQL connection
// ... first run the same checks as the folder method:
// error code, size, extension and real type ($realType) ...
if (empty($errors)) {
// Step 2: prepare the file
$name = basename($_FILES["image"]["name"]);
$data = file_get_contents($_FILES["image"]["tmp_name"]); // the whole file as a string
// Step 3: create and run the query - as a prepared statement
$stmt = mysqli_prepare($con, "INSERT INTO uploads (name, type, data) VALUES (?, ?, ?)");
mysqli_stmt_bind_param($stmt, "sss", $name, $realType, $data);
mysqli_stmt_execute($stmt);
// Step 4: tell the user what happened
echo "The picture was saved in the database.";
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 2
dbcon.phpcreates the connection$con(see Including files).dbcon.phpپەیوەندیی$conدروست دەکات (بڕوانە هاوردەکردنی فایل).- Lineدێڕی 10
Reads the entire file into a string.
هەموو دەخوێنێتەوە بۆ ناو .
- Lineدێڕی 13
The SQL has a
?(a placeholder, also called a parameter marker) in place of each value.لە SQLـەکەدا لە جیاتی هەر ،
?ێک وەک دانراوە.- Lineدێڕی 14
Bind the three values as strings (
"sss"); binary data is safe here because it never becomes part of the SQL text.سێ وەک ببەستەوە (
"sss")؛ دووانەیی لێرەدا سەلامەتە چونکە هەرگیز نابێتە بەشێک لە دەقی SQL.
Storing the file in the database (BLOB)هەڵگرتنی فایل لە بنکەدراوەدا (BLOB)
What was wrong in the slide's BLOB codeچی لە کۆدی BLOB ـی سلایدەکەدا هەڵە بوو
Storing the file in the database (BLOB)هەڵگرتنی فایل لە بنکەدراوەدا (BLOB)
Trying the BLOB method with SQLiteتاقیکردنەوەی ڕێگای BLOB بە SQLite
The MySQL code above needs a MySQL server, so its output is not shown. To prove that the method works, here is the same idea with , which runs without a server (you will meet PDO and SQLite later in the course):
کۆدە MySQLـییەکەی سەرەوە پێویستی بە MySQL هەیە، بۆیە پیشان نادرێت. بۆ سەلماندنی ئەوەی ڕێگاکە کار دەکات، ئەمە هەمان بیرۆکەیە بە ، کە بەبێ کار دەکات (دواتر لە کۆرسەکەدا PDO و SQLite دەبینیت):
<?php
// The BLOB method with SQLite (PDO), so you can try it without MySQL
$db = new PDO("sqlite:" . __DIR__ . "/photos.sqlite");
// Step 1: a table with a BLOB column (created only the first time)
$db->exec("CREATE TABLE IF NOT EXISTS uploads (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
type TEXT NOT NULL,
data BLOB NOT NULL
)");
if (isset($_POST["submit"]) && $_FILES["image"]["error"] === UPLOAD_ERR_OK) {
// Step 2: prepare the file
$tmp = $_FILES["image"]["tmp_name"];
$name = basename($_FILES["image"]["name"]);
$type = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tmp);
$data = file_get_contents($tmp); // the whole file as one string
// Step 4 (the checks) comes before saving
if (!in_array($type, ["image/jpeg", "image/png"], true) || strlen($data) > 2097152) {
exit("Only JPEG or PNG pictures up to 2 MB, please.");
}
// Step 3: a prepared statement - the data never becomes part of the SQL text
$stmt = $db->prepare("INSERT INTO uploads (name, type, data) VALUES (?, ?, ?)");
$stmt->bindValue(1, $name);
$stmt->bindValue(2, $type);
$stmt->bindValue(3, $data, PDO::PARAM_LOB);
$stmt->execute();
echo "Saved " . htmlspecialchars($name) . " (" . strlen($data) . " bytes) in the database.<br>\n";
}
foreach ($db->query("SELECT id, name, type, length(data) AS bytes FROM uploads") as $row) {
echo $row["id"] . ": " . htmlspecialchars($row["name"]) . ", " . $row["type"] . ", " . $row["bytes"] . " bytes<br>\n";
}Explain the codeڕوونکردنەوەی کۆدەکە
- Lineدێڕی 26-29
A prepared statement;
PDO::PARAM_LOBmarks the value as binary data.؛
PDO::PARAM_LOBوەک دووانەیی نیشانە دەکات.
Saved cat.png (123 bytes) in the database. 1: cat.png, image/png, 123 bytes
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Saved cat.png (123 bytes) in the database.<br>
1: cat.png, image/png, 123 bytes<br>Only JPEG or PNG pictures up to 2 MB, please.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Only JPEG or PNG pictures up to 2 MB, please.Saved erbil.jpg (653 bytes) in the database. 1: cat.png, image/png, 123 bytes 2: erbil.jpg, image/jpeg, 653 bytes
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
Saved erbil.jpg (653 bytes) in the database.<br>
1: cat.png, image/png, 123 bytes<br>
2: erbil.jpg, image/jpeg, 653 bytes<br>Storing the file in the database (BLOB)هەڵگرتنی فایل لە بنکەدراوەدا (BLOB)
Showing a picture from the databaseپیشاندانی وێنەیەک لە بنکەدراوەوە
To show a stored picture, select it with a prepared statement and send it with its type:
بۆ پیشاندانی وێنەیەکی هەڵگیراو، بە هەڵیبژێرە و لەگەڵ جۆرەکەی بینێرە:
<?php
// show.php?id=5 - send one picture from the database to the browser
require 'dbcon.php';
$id = (int) ($_GET["id"] ?? 0);
$stmt = mysqli_prepare($con, "SELECT type, data FROM uploads WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $id);
mysqli_stmt_execute($stmt);
$row = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt));
if (!$row) {
http_response_code(404);
exit("Picture not found.");
}
header("Content-Type: " . $row["type"]);
echo $row["data"];Common mistakesهەڵە باوەکان
- No
enctype="multipart/form-data"(ormethod="get"). PHP receives only the file name as text;$_FILESis empty. Our test without enctype:$_POSTheldimage => "cat.png", and$_FILESwas an empty array. - The input's
nameand the key in$_FILESdiffer (image,fileToUpload,fileInput,photo...). Use one name everywhere. - The target folder does not exist, or its name has the wrong case (
Uploadsvsuploads).move_uploaded_file()then fails with two warnings; see below. - Checks that only
echo. The file is saved anyway. Collect errors or use anelseifchain. move_uploaded_file()with three arguments, or with the misspelled keytpm_name.end(explode(...))gives a notice; usepathinfo($name, PATHINFO_EXTENSION).- Trusting
typeor the extension instead of checking the content withfinfo. - Keeping the visitor's file name: files overwrite each other, and strange names cause trouble. Generate a new name.
- A request bigger than
post_max_size: PHP empties$_POSTand$_FILES, soisset($_POST["submit"])is false and the page just shows the form again, with a startup warning. Our test with a 9 MB file andpost_max_size = 8M:
- هیچ
enctype="multipart/form-data"ێک نییە (یانmethod="get"). PHP تەنها ناوی وەک دەق وەردەگرێت؛$_FILESبەتاڵە. تاقیکردنەوەکەمان بەبێ enctype:$_POSTimage => "cat.png"ی تێدابوو و$_FILESبەتاڵ بوو. nameی و ناو$_FILESجیاوازن (image،fileToUpload،fileInput،photo...). یەک ناو لە هەموو شوێنێک بەکاربهێنە.- ئامانج بوونی نییە، یان ناوەکەی پیتی گەورە و بچووکی هەڵەیە (
Uploadsبەرامبەرuploads). ئەوکاتەmove_uploaded_file()بە دوو شکست دەهێنێت؛ لە خوارەوە ببینە. - پشکنین کە تەنها
echoدەکەن. هەر خەزن دەکرێت. کۆ بکەرەوە یان زنجیرەیelseifبەکاربهێنە. move_uploaded_file()بە سێ ، یان بە بە هەڵە نووسراویtpm_name.end(explode(...))ئاگاداری دەدات؛pathinfo($name, PATHINFO_EXTENSION)بەکاربهێنە.- متمانەکردن بە
typeیان لە جیاتی پشکنینی ناوەڕۆک بەfinfo. - هێشتنەوەی ناوی سەردانکەر: جێی یەکتر دەگرنەوە و ناوی سەیر کێشە دروست دەکەن. ناوێکی نوێ دروست بکە.
- گەورەتر لە
post_max_size: PHP$_POSTو$_FILESبەتاڵ دەکات، بۆیەisset($_POST["submit"])هەڵەیە و لاپەڕەکە تەنها دووبارە پیشان دەداتەوە، لەگەڵ ئاگادارییەکی دەستپێکردن. تاقیکردنەوەکەمان بە ٩ وpost_max_size = 8M:
Warning: PHP Request Startup: POST Content-Length of 9437468 bytes exceeds the limit of 8388608 bytes in Unknown on line 0 Upload a photo
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<br />
<b>Warning</b>: PHP Request Startup: POST Content-Length of 9437468 bytes exceeds the limit of 8388608 bytes in <b>Unknown</b> on line <b>0</b><br />
<h1>Upload a photo</h1><?php
if (isset($_POST["submit"])) {
$target = "Uploads/" . basename($_FILES["image"]["name"]); // the folder does not exist
if (move_uploaded_file($_FILES["image"]["tmp_name"], $target)) {
echo "Success";
} else {
echo "Sorry, the file could not be saved.";
}
}Warning: move_uploaded_file(Uploads/cat.png): Failed to open stream: No such file or directory in /var/www/html/no-folder.php on line 4 Warning: move_uploaded_file(): Unable to move "/tmp/php02nirb9fb0g18iHJogk" to "Uploads/cat.png" in /var/www/html/no-folder.php on line 4 Sorry, the file could not be saved.
HTML sent to the browserئەو HTMLـەی دەنێردرێت بۆ تۆڕگەڕ
<br />
<b>Warning</b>: move_uploaded_file(Uploads/cat.png): Failed to open stream: No such file or directory in <b>/var/www/html/no-folder.php</b> on line <b>4</b><br />
<br />
<b>Warning</b>: move_uploaded_file(): Unable to move "/tmp/php02nirb9fb0g18iHJogk" to "Uploads/cat.png" in <b>/var/www/html/no-folder.php</b> on line <b>4</b><br />
Sorry, the file could not be saved.<?php
var_dump($_POST);
var_dump($_FILES);array(2) {
["image"]=>
string(7) "cat.png"
["submit"]=>
string(12) "Upload Image"
}
array(0) {
}Lab and exercisesتاقیگە و ڕاهێنانەکان
Open a new PHP project in NetBeans and name it file_handling. (1) Create a new folder in the project called Uploads. (2) Write the HTML form for uploading files. (3) Write the PHP script that reads the file's information. (4) Add the checks: the file already exists, the file size, and the allowed formats; each check must block the upload. (5) Move the file to Uploads and tell the user that it worked. Put everything in index.php.
پرۆژەیەکی نوێی PHP لە NetBeans بکەرەوە و ناوی بنێ file_handling. (١) نوێ لە پرۆژەکەدا دروست بکە بە ناوی Uploads. (٢) HTML بۆ بنووسە. (٣) PHP بنووسە کە دەخوێنێتەوە. (٤) پشکنینەکان زیاد بکە: پێشتر هەیە، قەبارەی و شێوازە ڕێگەپێدراوەکان؛ هەر پشکنینێک دەبێت ڕابگرێت. (٥) بگوازەرەوە بۆ Uploads و بە بڵێ کە سەرکەوتوو بوو. هەموو شتێک لە index.phpدا دابنێ.
Hintئاماژە
Start from the lab's elseif chain, then add the error check, the real-type check and a random name.
لە زنجیرەی elseif ـی تاقیگەکەوە دەست پێبکە، پاشان پشکنینی هەڵە، پشکنینی جۆری ڕاستەقینە و ناوێکی هەڕەمەکی زیاد بکە.
Show answerوەڵامەکە پیشان بدە
Steps 1 to 5 together are the complete, safe upload page. Create the Uploads folder (with the .htaccess file inside it) and save the page as index.php, because the form's action is index.php. The simpler lab version (an elseif chain without the real-type check and random names) is shown in Every check must stop the upload.
هەنگاوەکانی ١ تا ٥ پێکەوە لاپەڕەی بارکردنی تەواو و سەلامەتن. Uploads دروست بکە (لەگەڵ .htaccess لەناویدا) و لاپەڕەکە وەک index.php خەزن بکە، چونکە actionی index.phpـە. وەشانە سادەترەکەی تاقیگە (زنجیرەیەکی elseif بەبێ پشکنینی جۆری ڕاستەقینە و ناوی هەڕەمەکی) لە هەموو پشکنینێک دەبێت بارکردنەکە ڕابگرێت پیشان دراوە.
<?php
// index.php - upload a photo (JPEG or PNG, at most 2 MB)
$uploadDir = __DIR__ . "/Uploads/"; // the folder must exist
$maxSize = 2097152; // 2 MB = 2 * 1024 * 1024 bytes
$extensions = ["jpeg", "jpg", "png"]; // allowed file extensions
$mimeTypes = ["image/jpeg", "image/png"]; // allowed real file types
$errors = []; // collects error messages
$message = "";
if (isset($_POST["submit"])) {
$file = $_FILES["image"] ?? null;
if ($file === null || $file["error"] === UPLOAD_ERR_NO_FILE) {
$errors[] = "Please select a file.";
} elseif ($file["error"] !== UPLOAD_ERR_OK) {
$errors[] = "The upload failed (error code " . $file["error"] . ").";
} else {
$originalName = basename($file["name"]);
$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
if (!in_array($ext, $extensions, true)) {
$errors[] = "Extension not allowed. Please choose a JPEG or PNG file.";
}
if ($file["size"] > $maxSize) {
$errors[] = "The file is too large. It must not be bigger than 2 MB.";
}
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$realType = finfo_file($finfo, $file["tmp_name"]);
if (!in_array($realType, $mimeTypes, true)) {
$errors[] = "This file is not a real JPEG or PNG picture.";
}
if (empty($errors)) {
// a new, random name: the visitor cannot choose it
$newName = bin2hex(random_bytes(16)) . "." . $ext;
$target = $uploadDir . $newName;
if (file_exists($target)) {
$errors[] = "Sorry, this file already exists.";
} elseif (move_uploaded_file($file["tmp_name"], $target)) {
$message = "Success! " . htmlspecialchars($originalName) . " was uploaded.";
} else {
$errors[] = "Sorry, the file could not be saved.";
}
}
}
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Upload a photo</h1>
<?php
foreach ($errors as $error) {
echo "<p style=\"color: red\">$error</p>\n";
}
if ($message !== "") {
echo "<p style=\"color: green\">$message</p>\n";
}
?>
<form action="index.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" accept=".jpg,.jpeg,.png">
<input type="submit" name="submit" value="Upload Image">
</form>
</body>
</html>This is step two of Lab 6 (welcome.php), exactly as printed. It does not run. Find at least six problems.
ئەمە هەنگاوی دووی تاقیگەی ٦ـە (welcome.php)، ڕێک وەک چاپ کراوە. کار ناکات. لانیکەم شەش کێشە بدۆزەرەوە.
<?php
$target_dir = "uploads/";
errors=””;
//get file size
$file_size=($_FILES["image"]["size"]);
variable for file name
$file_name=($_FILES["image"]["name"]);
$file_temp=($_FILES["image"]["tpm_name"]);
$file_type=($_FILES["image"]["type"]);
// get file extention
$file_ext=strtolower(end(explode('.',$_FILES['image']['name'])));
$target=$target_dir.basename($file_name);
//array of allowed extension
$extensions= array("jpeg","jpg","png");
//check if user clicks submit button
$ if(isset($_POST["submit"])) {
}
?>Show answerوەڵامەکە پیشان بدە
- Line 3:
errors=””;has no$, and””are curly quotes: parse error. Write$errors = [];(or""). - Line 6:
variable for file nameis a comment without//: parse error. - Line 8:
"tpm_name"should be"tmp_name"; otherwise$file_tempisnulland the move fails. - Line 11:
end(explode(...))gives a notice; usepathinfo(). "extention" is misspelled. - Line 17:
$ if(...)has a stray$: parse error. Theifblock is also empty. $_FILESis read before checking that the form was sent, so a normal visit gives "Undefined array key" warnings. Read it inside theif.- Line 2:
"uploads/"does not match the folderUploadscreated in step one (Linux is case-sensitive). - The extra brackets in
($_FILES[...])are harmless but unnecessary. A corrected version is Step 1.
- دێڕی 3:
errors=””;ـی$تێدا نییە و””خوارن: . بنووسە$errors = [];(یان""). - دێڕی 6:
variable for file nameبەبێ//: . - دێڕی 8:
"tpm_name"دەبێت"tmp_name"بێت؛ دەنا$file_tempnullـە و گواستنەوەکە شکست دەهێنێت. - دێڕی 11:
end(explode(...))ئاگاداری دەدات؛pathinfo()بەکاربهێنە. «extention» بە هەڵە نووسراوە. - دێڕی 17:
$ if(...)ـی$ێکی زیادەی هەیە: . بلۆکیifـەکەش بەتاڵە. $_FILESپێش پشکنینی ناردنی دەخوێنرێتەوە، بۆیە سەردانێکی ئاسایی «Undefined array key» دەدات. لەناوifـەکەدا بیخوێنەوە.- دێڕی 2:
"uploads/"لەگەڵUploadsکە لە هەنگاوی یەکەمدا دروست کرا ناگونجێت (Linux هەستیارە بە پیتی گەورە و بچووک). - کەوانە زیادەکانی
($_FILES[...])زیانیان نییە بەڵام پێویست نین. وەشانێکی ڕاستکراوە هەنگاوی ١ـە.
What does basename() do in PHP? What do basename('/var/www/html/index.php') and basename('/var/www/html/index.php', '.php') return? Why is it used in upload scripts?
basename() لە PHPـدا چی دەکات؟ basename('/var/www/html/index.php') و basename('/var/www/html/index.php', '.php') چی دەگەڕێننەوە؟ بۆچی لە بەکار دێت؟
Show answerوەڵامەکە پیشان بدە
It returns the last part of a path, usually the file name: index.php. With the second argument it also removes that ending: index. In uploads it removes any folder part from a name, so that a name like ../../config.php cannot point outside the upload folder.
دوایین بەشی دەگەڕێنێتەوە، کە بەگشتی ناوی : index.php. بە دووەم ئەو کۆتاییەش لادەبات: index. لە هەر بەشێکی لە ناوێک لادەبات، بۆ ئەوەی ناوێکی وەک ../../config.php نەتوانێت ئاماژە بە دەرەوەی بکات.
Change the complete script so that it accepts PDF files (extension pdf, real type application/pdf) of at most 5 MB, and nothing else.
تەواوەکە بگۆڕە بۆ ئەوەی PDF ( pdf، جۆری ڕاستەقینەی application/pdf) تا ٥ وەربگرێت و هیچ شتێکی تر نا.
Hintئاماژە
Only the settings at the top and the messages change.
تەنها سەرەوە و پەیامەکان دەگۆڕێن.
Show answerوەڵامەکە پیشان بدە
$maxSize = 5 * 1024 * 1024; // 5 MB = 5242880 bytes
$extensions = ["pdf"];
$mimeTypes = ["application/pdf"];Change the messages too ("Please choose a PDF file.", "must not be bigger than 5 MB"), the form's accept=".pdf", and check that upload_max_filesize in php.ini is at least 5M.
پەیامەکانیش بگۆڕە («Please choose a PDF file.»، «must not be bigger than 5 MB»)، accept=".pdf"ی و بپشکنە کە upload_max_filesize لە php.iniدا لانیکەم 5Mـە.
Summary and reviewپوختە و پێداچوونەوە
- An upload form needs
method="post",enctype="multipart/form-data"and<input type="file" name="...">;file_uploads = Onin php.ini. - PHP keeps the file in a temporary folder and describes it in
$_FILES; if you do not move it, it is deleted when the request ends. - Check the error code, the size, the extension (
pathinfo()) and the real type (finfo). Every check must block the upload. move_uploaded_file($tmp, $target)takes two arguments and returns true or false.- Save under a new unique name, outside the web root or in a folder where scripts cannot run.
- Two methods: a folder plus the path in the database (usual), or the bytes in a BLOB column, always with a prepared statement.
- پێویستی بە
method="post"،enctype="multipart/form-data"و<input type="file" name="...">هەیە؛file_uploads = Onلە php.iniدا. - PHP لە کاتیدا ڕادەگرێت و لە
$_FILESدا وەسفی دەکات؛ ئەگەر نەیگوازیتەوە، لە کۆتایی دەسڕدرێتەوە. - کۆدی ، قەبارە، (
pathinfo()) و جۆری ڕاستەقینە (finfo) بپشکنە. هەموو پشکنینێک دەبێت ڕابگرێت. move_uploaded_file($tmp, $target)دوو وەردەگرێت و true یان false دەگەڕێنێتەوە.- بە ناوێکی نوێی بێهاوتا خەزنی بکە، لە دەرەوەی ڕەگی وێب یان لە کە تێیدا جێبەجێ نابێت.
- دوو ڕێگا: لەگەڵ لە (باو)، یان لە BLOBـدا، هەمیشە بە .
What must you take into consideration to upload a file with <input type="file">?بۆ بارکردنی فایل بە <input type="file"> دەبێت ئاگات لە چی بێت؟
Use the POST method, add enctype="multipart/form-data" to the form (without it the file is not uploaded), and make sure file_uploads = On in php.ini.
بەکاربهێنە، enctype="multipart/form-data" بۆ زیاد بکە (بەبێ ئەو بار ناکرێت) و دڵنیابە کە file_uploads = On لە php.iniدا.
What are the two file-upload methods?دوو ڕێگاکەی بارکردنی فایل چین؟
Copy the file to a local folder and store its path in the database, or store the file itself in the database as a BLOB.
بۆ ناوخۆیی کۆپی بکە و لە هەڵبگرە، یان خۆی لە وەک BLOB هەڵبگرە.
Why does PHP save an uploaded file into a temporary directory?بۆچی PHP فایلی بارکراو لە فۆڵدەرێکی کاتیدا خەزن دەکات؟
So that the script can check the file before deciding to keep it. The temporary file is a holding area: if the script does not move it with move_uploaded_file(), PHP deletes it when the request ends. PHP itself does not scan for viruses; the checks are the developer's job.
بۆ ئەوەی بتوانێت پێش بڕیاردان لەسەر هەڵگرتنی، بپشکنێت. شوێنێکی ڕاگرتنە: ئەگەر بە move_uploaded_file() نەیگوازێتەوە، PHP لە کۆتایی دەیسڕێتەوە. PHP خۆی بۆ ڤایرۆس ناپشکنێت؛ پشکنینەکان ئەرکی گەشەپێدەرن.
What do name, size, tmp_name, type and error in $_FILES hold?name، size، tmp_name، type و error لە $_FILESدا چی هەڵدەگرن؟
The original file name, the size in bytes, the temporary file's path, the type claimed by the browser, and the upload error code (0 = OK).
ناوی ڕەسەنی ، قەبارە بە ، ، ئەو جۆرەی دەیڵێت و کۆدی (0 = باش).
Why is checking the extension not enough?بۆچی پشکنینی پاشگری فایل بەس نییە؟
Anyone can rename a file. Check the real type of the content with finfo (and save under a new name in a place where scripts cannot run).
هەر کەسێک دەتوانێت ناوی بگۆڕێت. جۆری ڕاستەقینەی ناوەڕۆکەکە بە finfo بپشکنە (و بە ناوێکی نوێ لە شوێنێکدا خەزنی بکە کە تێیدا جێبەجێ نابێت).
What is basename in PHP?basename لە PHPـدا چییە؟
A function that returns the last part of a path, usually the file name; with a second argument it also removes that file extension.
کە دوایین بەشی دەگەڕێنێتەوە، کە بەگشتی ناوی ؛ بە دووەم ئەو پاشگرەش لادەبات.
Why did the slide's complete upload script save virus.exe?بۆچی دەسنووسە تەواوەکەی سلایدەکە virus.exe ـی خەزن کرد؟
Its checks only echoed messages and never added to $errors, so empty($errors) was always true and the file was always moved.
پشکنینەکانی تەنها پەیامیان echo دەکرد و هەرگیز هیچیان بۆ $errors زیاد نەدەکرد، بۆیە empty($errors) هەمیشە ڕاست بوو و هەمیشە دەگوازرایەوە.
Videoڤیدیۆ
Watch a videoسەیری ڤیدیۆیەک بکە
A video that viewers liked a lot and praised in their comments, chosen for this lesson.ڤیدیۆیەک کە بینەران زۆریان پێ خۆش بووە و لە کۆمێنتەکانیاندا ستایشیان کردووە، بۆ ئەم وانەیە هەڵبژێردراوە.
Builds an upload form and script step by step: what $_FILES holds, php.ini settings, every upload error code, and a file-size limit.
هەنگاو بە هەنگاو و دروست دەکات: $_FILES چی تێدایە، ڕێکخستنەکانی ، هەموو کۆدەکانی و سنووری قەبارەی .
Watch 0:00–10:30: form, $_FILES, php.ini, error codes, size limit.
لە 0:00 تا 10:30 سەیر بکە: ، $_FILES، ، کۆدەکانی و سنووری قەبارە.
Lesson complete!وانەکە تەواو بوو!
Well done. Review the key terms, then go on to the next lesson.دەستخۆش. سەیرێکی زاراوە سەرەکییەکان بکەرەوە، پاشان بڕۆ بۆ وانەی داهاتوو.
Key termsزاراوە سەرەکییەکان
Databases and SQL basicsبنکەدراوەکان و بنەماکانی SQL
Related lecturesوانە پەیوەندیدارەکان
- HTML Forms Reviewپێداچوونەوەی فۆرمەکانی HTML
- Form Validationپشتڕاستکردنەوەی فۆرم
- Form Security and Sticky Formsئاسایشی فۆرم و فۆرمە لکاوەکان
- Including Files: include and requireهاوردەکردنی فایل: include و require
- Redirects: Sending the Browser Somewhere Elseئاڕاستەکردنەوە: ناردنی تۆڕگەڕ بۆ شوێنێکی تر
- Securing Data in PHP and MySQLپاراستنی دراوە لە PHP و MySQL
- XAMPP: Your Own Local Web ServerXAMPP: ڕاژەکاری وێبی ناوخۆیی خۆت
References and further readingسەرچاوەکان و خوێندنەوەی زیاتر
This lecture is a first edition. The Kurdish text and terminology are waiting for review by Kurdish IT teachers.ئەم وانەیە چاپی یەکەمە. دەقە کوردییەکە و زاراوەکانی چاوەڕێی پێداچوونەوەی مامۆستایانی کوردی بواری IT ن.