الدوال في PHP
الجاهزة منها وما تكتبه بنفسك، لتنظيم منطق الخادم. ⏱ نحو 30 دقيقة.
- تستخدم أشهر الدوال الجاهزة للنصوص والأعداد والمصفوفات.
- تعرّف دوالًا بمعاملات وقيم افتراضية وأنواع، وتعيد النتائج بـ
return. - تشرح نطاق المتغيرات داخل الدالة وخارجها.
- تبني قطع
HTMLبدوال صغيرة قابلة لإعادة الاستخدام.
١لماذا الدوال؟
الدالة Function كتلة كود لها اسم، تكتبها مرة وتستدعيها مرات. في الواجهة الخلفية تتكرر أعمال كثيرة: حساب الضريبة، وتنسيق السعر، والتحقق من البريد. لو كررنا الكود في كل صفحة، فأي تعديل سيحتاج تغيير كل النسخ.
وفي PHP نوعان: دوال جاهزة Built-in (أكثر من ألف دالة!)، ودوال تعرّفها أنت User-defined. ابدأ دائمًا بالبحث: «هل في PHP دالة جاهزة لهذا؟» والمرجع الرسمي php.net يشرح كل دالة بأمثلة.
٢دوال جاهزة للنصوص
<?php$name = " سعود الحربي ";$clean = trim($name); // يحذف المسافات من الطرفينecho "[" . $clean . "]\n";echo mb_strlen($clean) . " حرفًا\n"; // عدد الحروف (العربية صحيحة)echo strlen($clean) . " بايتًا\n"; // عدد البايتاتecho str_replace("الحربي", "العتيبي", $clean) . "\n";echo strtoupper("php") . "\n";echo str_contains($clean, "سعود") ? "موجود\n" : "غير موجود\n"; $csv = "قهوة,شاي,عصير";$items = explode(",", $csv); // نص ← مصفوفةecho count($items) . " عناصر\n";echo implode(" | ", $items); // مصفوفة ← نص
| الدالة | عملها |
|---|---|
trim($s) | تحذف المسافات والأسطر من بداية النص ونهايته. استخدمها مع كل حقل يصل من نموذج. |
mb_strlen($s) | عدد الحروف. لا تستخدم strlen مع العربية لأنها تعدّ البايتات. |
str_replace($a, $b, $s) | تستبدل كل $a بـ $b. |
str_contains($s, $x) | هل النص يحتوي $x؟ (PHP 8) |
explode($sep, $s) و implode($sep, $a) | تقسيم النص إلى مصفوفة، وتجميع المصفوفة في نص. |
٣دوال جاهزة للأعداد والمصفوفات والتاريخ
<?php$prices = [35, 120, 45, 18];echo "المجموع: " . array_sum($prices) . "\n";echo "الأعلى: " . max($prices) . "\n";echo "المتوسط: " . round(array_sum($prices) / count($prices), 2) . "\n";echo "منسّق: " . number_format(1234567.891, 2) . "\n";echo in_array(45, $prices) ? "45 موجود\n" : "45 غير موجود\n"; sort($prices); // ترتيب تصاعدي (يغيّر المصفوفة نفسها)echo implode(", ", $prices) . "\n"; echo date("Y-m-d", 0) . "\n"; // تاريخ من طابع زمني
الدالة date("Y-m-d") بلا معامل ثانٍ تعطي تاريخ اليوم حسب ساعة الخادم. والرموز: Y للسنة، و m للشهر، و d لليوم، و H:i للساعة والدقيقة.
٤عرّف دالتك
تبدأ بالكلمة function، ثم الاسم، ثم المعاملات بين قوسين. والكلمة return تعيد النتيجة لمن استدعى الدالة:
<?phpfunction vat(float $price, float $rate = 0.15): float{ return round($price * $rate, 2);} function priceTag(float $price): string{ $total = $price + vat($price); return number_format($total, 2) . " ريال";} echo "<p>الضريبة على 100: " . vat(100) . "</p>";echo "<p>بضريبة 5%: " . vat(100, 0.05) . "</p>";echo "<p>سعر القهوة شاملًا: " . priceTag(35) . "</p>";
| الجزء | المثال | معناه |
|---|---|---|
| نوع المعامل | float $price | يقبل عددًا فقط. إن أرسلت نصًّا غير رقمي يظهر خطأ واضح. |
| قيمة افتراضية | $rate = 0.15 | إن لم يُرسل المعامل تُستخدم 0.15. |
| نوع القيمة المعادة | : float | الدالة تعد بأن تعيد عددًا عشريًّا. |
| استدعاء دالة من دالة | vat($price) | priceTag تعيد استخدام vat بدل تكرار الحساب. |
٥نطاق المتغيرات: الدالة عالم مغلق
المتغيرات المعرّفة خارج الدالة لا تُرى داخلها، والعكس صحيح. وهذا مختلف عن JavaScript وبايثون:
<?php$rate = 0.15; function vat($price){ return $price * $rate;}echo vat(100);
<?php$rate = 0.15; function vat($price, $rate){ return $price * $rate;}echo vat(100, $rate);
الحل الصحيح: مرّر ما تحتاجه الدالة معاملًا. توجد الكلمة global لكنها تجعل الكود صعب التتبع، فتجنّبها.
والدالة تستقبل نسخة من القيمة؛ تعديل المعامل داخلها لا يغيّر المتغير الأصلي. هذا يحمي بياناتك من التغيير بالخطأ.
٦الدوال التي تبني HTML
في الواجهات الخلفية نكتب دوالًا صغيرة تعيد قطع HTML جاهزة، ثم نركّب الصفحة منها. لاحظ استخدام htmlspecialchars داخل الدالة نفسها، فلا ننساها أبدًا:
<?phpfunction e(string $s): string{ return htmlspecialchars($s);} function badge(string $text, string $color = 'gray'): string{ return "<span style='background:$color;color:#fff;padding:2px 8px;border-radius:9px'>" . e($text) . "</span>";} function productCard(array $p): string{ $status = $p['stock'] > 0 ? badge('متوفر', 'green') : badge('نفد', 'crimson'); return "<div style='border:1px solid #ccc;padding:8px;margin:6px'><b>" . e($p['name']) . "</b> $status<br>" . $p['price'] . " ريال</div>";} echo productCard(['name' => 'قهوة عربية', 'price' => 35, 'stock' => 5]);echo productCard(['name' => 'عسل سدر', 'price' => 120, 'stock' => 0]);
توقّع وتحقّق
أي دالة تحذف المسافات من طرفي النص؟
trim($s)explode(",", "أ,ب,ج") تعيد:
ما قيمة vat(200) إن عُرّفت function vat($p, $r = 0.15) { return $p * $r; } ؟
متغير عُرّف خارج الدالة، هل يُرى داخلها مباشرة؟
الخلاصة
- ابحث أولًا عن دالة جاهزة:
trimوmb_strlenوexplodeوimplodeوarray_sumوnumber_format. functionاسم(نوع $معامل = افتراضي): نوع {return…; }- الدالة نطاق مغلق: لا ترى متغيرات الخارج؛ مرّر ما تحتاجه معاملًا.
- أعد النتيجة بـ
returnبدل طباعتها، لتستخدمها حيث شئت. - دوال صغيرة تبني
HTMLوتستخدمhtmlspecialcharsتجعل الصفحات أنظف وأأمن.
تحدٍّ برمجي: فاتورة المتجر
متوسطاكتب دالتين، ثم استخدمهما لطباعة فاتورة طلب. الدوال تجعل الحساب في مكان واحد.
- الدالة
lineTotal(float $price, int $qty): floatتعيد السعر × الكمية. - الدالة
withVat(float $amount, float $rate = 0.15): floatتعيد المبلغ مع الضريبة، مقرّبًا لخانتين بـ round. - للطلب الجاهز في الكود اطبع سطرًا لكل صنف:
<li>قهوة عربية × 2 = 70</li> - ثم اطبع:
<p>المجموع: 196</p>و<p>مع الضريبة: 225.4</p>
👀 اعرض الاستجابة المطلوبة
GET /invoice.php
- الكود يعمل بلا أخطاء أو تحذيرات
- سطر لكل صنف بالشكل المطلوب
- المجموع: 196
- مع الضريبة: 225.4
- عرّفت الدالة lineTotal بنوعي المعاملين
- عرّفت withVat بقيمة افتراضية 0.15 واستدعيتها
💡 تلميح 1
$sum = 0; واجمع فيه ناتج lineTotal لكل صنف داخل foreach.💡 تلميح 2
round($amount * (1 + $rate), 2)حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
<?php$order = [ ['name' => 'قهوة عربية', 'price' => 35, 'qty' => 2], ['name' => 'تمر سكري', 'price' => 45, 'qty' => 2], ['name' => 'شاي أخضر', 'price' => 18, 'qty' => 2],]; function lineTotal(float $price, int $qty): float{ return $price * $qty;} function withVat(float $amount, float $rate = 0.15): float{ return round($amount * (1 + $rate), 2);} $sum = 0;echo "<ul>";foreach ($order as $item) { $line = lineTotal($item['price'], $item['qty']); $sum += $line; echo "<li>{$item['name']} × {$item['qty']} = $line</li>";}echo "</ul>";echo "<p>المجموع: $sum</p>";echo "<p>مع الضريبة: " . withVat($sum) . "</p>";