اذهب إلى المحتوى

معالجة بيانات طلبيات HTTP والتعامل مع أخطاء رفع الملفات في PHP


سارة محمد2

قراءة بيانات خام مُرسَلة عبر طلب POST

تُنظَّم عادةً البيانات المُرسلة عبر طلب POST في أزواج مفتاح/قيمة مع نوع MIME ‏application/x-www-formurlencoded، ومع ذلك تتطلب العديد من التطبيقات مثل خدمات الويب (web services) بيانات خام بتنسيق XML أو JSON غالبًا لتُرسَل، يمكن قراءة هذه البيانات بإحدى طريقتين.

  • الأولى هي عبر مجرى يوفر الوصول إلى هيكل الطلب الخام php://input. لدينا الشيفرة التالية في الإصدار PHP < 5.6:
$rawdata = file_get_contents("php://input");

// ‫بفرض أننا نحصل على JSON
$decoded = json_decode($rawdata);
  • الثانية عبر المتغير ‎$HTTP_RAW_POST_DATA الذي هو متغير عام يتضمن بيانات خام مُرسَلة عبر طلب POST وهو مُتاح فقط إذا كان الموجِّه always_populate_raw_post_data في ملف php.ini مفعّلًا.
$rawdata = $HTTP_RAW_POST_DATA;

// ‫إذا كنا نريد الحصول على XML
$decoded = simplexml_load_string($rawdata);

أُهمل هذا المتغير منذ الإصدار PHP 5.6 وأُزيل في الإصدار PHP 7.0.

لاحظ أنّ هذه التوابع غير متاحة عندما يُضبَط نوع المحتوى إلى القيمة multipart/form-data التي تُستَخدم لرفع الملفات.

قراءة بيانات مُرسَلة عبر طلب POST

تُخزَّن البيانات المُرسَلة عبر طلب POST في المتغير ذو النطاق العام العالي ‎$_POST على شكل مصفوفة ترابطية.

لاحظ أنّ الوصول إلى عنصر مصفوفة غير موجود يولّد ملاحظة لذا يجب التأكد دومًا من وجود العنصر باستخدام الدوال isset()‎ أو empty()‎ أو عامل تجميع null، مثال:

$from = isset($_POST["name"]) ? $_POST["name"] : "NO NAME";
$message = isset($_POST["message"]) ? $_POST["message"] : "NO MESSAGE";
echo "Message from $from: $message";

// ‫الإصدار PHP ≥ 7.0
$from = $_POST["name"] ?? "NO NAME";
$message = $_POST["message"] ?? "NO MESSAGE";

echo "Message from $from: $message";

قراءة بيانات مُرسَلة عبر طلب GET

تُخزَّن البيانات المُرسَلة عبر طلب GET في المتغير ذو النطاق العام العالي ‎$_GET على شكل مصفوفة ترابطية.

لاحظ أنّ الوصول إلى عنصر مصفوفة غير موجود يولّد ملاحظة لذا يجب التأكد دومًا من وجود العنصر باستخدام الدوال isset()‎ أو empty()‎ أو عامل تجميع null، مثال:

مثال (بفرض لدينا الرابط ‎/topics.php?author=alice&topic=php‎):

$author = isset($_GET["author"]) ? $_GET["author"] : "NO AUTHOR";
$topic = isset($_GET["topic"]) ? $_GET["topic"] : "NO TOPIC";
echo "Showing posts from $author about $topic";

// ‫الإصدار PHP ≥ 7.0
$author = $_GET["author"] ?? "NO AUTHOR";
$topic = $_GET["topic"] ?? "NO TOPIC";

echo "Showing posts from $author about $topic";

معالجة أخطاء رفع ملف

قد يتضمن العنصر ‎$_FILES["FILE_NAME"]['error']‎ (حيث "FILE_NAME" قيمة الخاصيّة name للعنصر input الموجود في النموذج الخاص بك) إحدى القيم التالية:

1- UPLOAD_ERR_OK: لا يوجد خطأ، رُفِع الملف بنجاح.

2- UPLOAD_ERR_INI_SIZE: تجاوز الملف المرفوع قيمة upload_max_filesize في الملف php.ini.

3- UPLOAD_ERR_PARTIAL: تجاوز الملف المرفوع القيمة MAX_FILE_SIZE المحددة في نموذج HTML.

4- UPLOAD_ERR_NO_FILE: لم يُحمَّل أي ملف.

5- UPLOAD_ERR_NO_TMP_DIR: فقدان مجلد مؤقت (من الإصدار PHP 5.0.3).

6- UPLOAD_ERR_CANT_WRITE: فشل كتابة الملف على القرص (من الإصدار PHP 5.1.0).

7- UPLOAD_ERR_EXTENSION: إضافة PHP أوقفت رفع الملف (من الإصدار PHP 5.2.0).

الطريقة الأساسية لفحص الأخطاء:

<?php

// ‫"FILE_NAME" قيمة الخاصيّة `name` للعنصر `input` الموجود في النموذج الخاص بك‫
$fileError = $_FILES["FILE_NAME"]["error"];
switch($fileError) {
    case UPLOAD_ERR_INI_SIZE:
    // ‫تجاوز الحجم الأعظمي المحدد في php.ini
    break;

    case UPLOAD_ERR_PARTIAL:
    // ‫تجاوز الحجم الأعظمي المحدد في نموذج html
    break;

    case UPLOAD_ERR_NO_FILE:
    // لم يُحمَّل أي ملف
    break;

    case UPLOAD_ERR_NO_TMP_DIR:
    // لا يوجد مجلد مؤقت للكتابة فيه
    break;

    case UPLOAD_ERR_CANT_WRITE:
    // خطأ في الكتابة إلى القرص
    break;

    default:
    // لا يوجد أخطاء!
    break;
}

تمرير مصفوفات عبر طلب POST

يُرسَل عادةً عنصر نموذج HTML إلى PHP كقيمة مفردة، مثال:

<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
    <input type="hidden" name="foo" value="bar"/>
    <button type="submit">Submit</button>
</form>

الخرج:

Array
(
    [foo] => bar
)

لكن قد تحتاج أحيانًا إلى تمرير مصفوفة قيم، يمكنك القيام بذلك بإضافة مايشبه اللاحقة في PHP إلى الخاصيّة name لعناصر HTML:

<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
    <input type="hidden" name="foo[]" value="bar"/>
    <input type="hidden" name="foo[]" value="baz"/>
    <button type="submit">Submit</button>
</form>

الخرج:

Array
(
    [foo] => Array
    (
        [0] => bar
        [1] => baz
    )
)

يمكنك أيضًا تحديد فهارس المصفوفة إما أرقام أو سلاسل نصية:

<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
    <input type="hidden" name="foo[42]" value="bar"/>
    <input type="hidden" name="foo[foo]" value="baz"/>
    <button type="submit">Submit</button>
</form>

الخرج:

Array
(
    [foo] => Array
    (
        [42] => bar
        [foo] => baz
    )
)

يمكن استخدام هذه التقنية لتجنب حلقات ما بعد المعالجة عبر مصفوفة ‎$_POST مما يجعل شيفرتك أنظف وأدق.

رفع ملفات باستخدام HTTP PUT

توفر PHP الدعم للطريقة HTTP PUT المستخدمة من قِبَل بعض العملاء لتخزين الملفات على الخادم، تعدّ طلبات PUT أبسط من رفع ملف باستخدام طلبات POST وتبدو بالشكل:

PUT /path/filename.html HTTP/1.1

يمكنك كتابة شيفرة PHP التالية:

<?php

// ‫تأتي بيانات PUT من مجرى الدخل القياسي
$putdata = fopen("php://input", "r");

// فتح ملف للكتابة
$fp = fopen("putfile.ext", "w");

// قراءة 1 كيلوبايت في كل مرة وكتابتها في الملف
while ($data = fread($putdata, 1024))
fwrite($fp, $data);

/* إغلاق المجاري */
fclose($fp);
fclose($putdata);
?>

ترجمة -وبتصرف- للفصل [Reading Request Data] من كتاب PHP Notes for Professionals book

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...