الدوال — الأساسيات

تُعد الدوال اللبنات الأساسية للبرمجة. قم بتجميع الكود القابل لإعادة الاستخدام في دوال، وستنتقل من مرحلة «كتابة البرامج النصية» إلى مرحلة «البناء باستخدام اللبنات» — حيث تصبح كل دالة عنصرًا قابلاً لإعادة الاستخدام.

1. تعريف الدوال واستدعائها

PHP
<?php
// Define a function
function greet() {
    echo "Hello, World!";
}

// Call the function
greet();  // Output: Hello, World!
greet();  // You can call it repeatedly
?>

لا يُراعي التمييز بين الأحرف الكبيرة والصغيرة في أسماء الدوال (ولكن من المعتاد استخدام الأحرف الصغيرة مع علامات التسطير — snake_case):

PHP
GREET();  // This also works, but don't do it

2. المعلمات والقيم المرجعة

يمكن أن تتلقى الدوال معلمات (مدخلات) وتقوم بإرجاع البيانات (مخرجات):

PHP
<?php
// A function with a parameter
function greet($name) {
    return "Hello, {$name}!";
}

$msg = greet("John");
echo $msg;  // Hello, John!
?>

(1) معلمات متعددة

PHP
<?php
function calculateTotal($price, $quantity, $tax = 1.0) {
    return $price * $quantity * $tax;
}

echo calculateTotal(10, 3);        // 30 (tax uses the default of 1.0)
echo calculateTotal(10, 3, 1.13);  // 33.9 (custom tax passed in)
?>
💡 نصيحة: يجب أن تأتي المعلمات ذات القيم الافتراضية بعد المعلمات التي لا تحتوي على قيم افتراضية. سيؤدي استخدام function f($a = 1, $b) إلى حدوث خطأ.


3. إعلانات الأنواع (PHP 7+)

يدعم PHP 7+ إعلانات الأنواع لمعلمات الدوال وقيم الإرجاع، مما يجعل الكود أكثر أمانًا:

PHP
<?php
// Parameter type declarations + return type declaration
function add(int $a, int $b): int {
    return $a + $b;
}

echo add(3, 5);      // 8
echo add("3", "5");  // 8 (PHP auto-converts)
// echo add("hello", 5); // TypeError!

// Other type declarations
function displayUser(string $name, int $age): void {
    echo "{$name}, {$age} years old";
}

function getPrice(float $price): string {
    return "$" . number_format($price, 2);
}
?>
النوع الإعلان ملاحظات
عدد صحيح int يتم تحويله تلقائيًا إلى int
عدد عائم float يتم تحويله تلقائيًا إلى عدد عائم
سلسلة string يتم تحويلها تلقائيًا إلى سلسلة
منطقية bool يتم تحويلها تلقائيًا إلى قيمة منطقية
مصفوفة array يجب أن تكون مصفوفة
لا يمكن الإرجاع void لا يمكن إرجاع أي شيء
قابل للإلغاء ?string يقبل سلسلة أو قيمة فارغة
نوع الاتحاد (PHP 8+) int|float يقبل القيم من نوع int أو float
مختلط mixed أي نوع
💡 نصيحة: عند كتابة كود جديد، احرص دائمًا على إضافة إعلانات الأنواع. فهي توضح المقصد من الكود وتساعد على اكتشاف الأخطاء في وقت مبكر — فإذا قام المستدعي بتمرير نوع خاطئ، فستحصل على TypeError بدلاً من الحصول على نتائج غريبة دون أي إشعار.

▶ مثال: دالة عملية مع إعلانات الأنواع

PHP
<?php
// Combined type declarations: union type + void + default value
function formatPrice(int|float $price, string $currency = "$"): string {
    return $currency . number_format((float)$price, 2);
}

function logAction(string $user, string $action): void {
    echo "[" . date("H:i:s") . "] {$user} performed {$action}<br>";
}

echo formatPrice(39.9);         // $39.90
echo formatPrice(100);           // $100.00
logAction("admin", "logged in"); // [14:30:45] admin performed logged in
?>
▶ جرّب الكود

4. الكتابة الصارمة (strict_types)

بشكل افتراضي، تسمح إعلانات الأنواع في PHP بـالتحويل التلقائي للأنواع (يمكن تمرير "3" إلى معلمة int). وعند تمكين الوضع الصارم، يجب أن تتطابق الأنواع تمامًا:

▶ مثال: الوضع الافتراضي مقابل الوضع الصارم

PHP
<?php
// Default mode: automatic type coercion
function double(int $n): int {
    return $n * 2;
}
echo double("5");  // 10 ("5" is auto-converted to int 5)

// Strict mode: by the book
declare(strict_types=1);

function doubleStrict(int $n): int {
    return $n * 2;
}
echo doubleStrict("5");  // TypeError! Must pass an int
echo doubleStrict(5);    // 10 ✅

function greetStrict(string $name): string {
    return "Hello, {$name}";
}
// echo greetStrict(123);  // TypeError! A number is not a string
echo greetStrict("John");  // ✅
?>
▶ جرّب الكود
💡 نصيحة: يجب أن تكون declare(strict_types=1) هي العبارة الأولى في ملف PHP (مباشرةً بعد العلامة <?php). وهي تؤثر فقط على استدعاءات الدالة داخل الملف الحالي، وليس على الملف الذي تم تعريف الدالة فيه. بالنسبة للمشاريع الجديدة، قم بتمكين الوضع الصارم بشكل افتراضي.


5. عبارة «return»

PHP
<?php
function getUser($id) {
    // Query the database... let's pretend we found a user
    if ($id <= 0) {
        return null;  // Invalid ID — bail out early
    }
    return [
        "id" => $id,
        "name" => "User{$id}"
    ];
}

$user = getUser(1);
if ($user !== null) {
    echo $user["name"];  // User1
}

// void function: returns nothing
function logError(string $message): void {
    // Write to the error log
    error_log($message);
    // Do not write return $something;
}
?>

بعد return، تنتهي الدالة على الفور. وهذا مفيد بشكل خاص في جمل الحماية — حيث يتم التعامل مع الحالات الاستثنائية أولاً والعودة مبكرًا.


6. تعليقات PHPDoc

تحتاج الوظائف الجيدة إلى توثيق. PHPDoc هو معيار التعليقات في لغة PHP:

PHP
<?php
/**
 * Calculate the total price
 *
 * @param float $price    Unit price
 * @param int   $quantity Quantity purchased
 * @param float $tax      Tax rate (default 1.0 for tax-inclusive)
 * @return float Final total price
 *
 * Examples:
 *   calculateTotal(10, 3)       → 30.0
 *   calculateTotal(10, 3, 1.13) → 33.9
 */
function calculateTotal(float $price, int $quantity, float $tax = 1.0): float {
    return $price * $quantity * $tax;
}
?>
العلامة الغرض
@param وصف المعلمة (النوع + الاسم + الشرح)
@return وصف قيمة الإرجاع
@throws الاستثناءات التي قد يتم إلقاؤها
@var نوع المتغير
@see مرجع ذو صلة
💡 نصيحة: لا يقتصر استخدام PHPDoc على البشر فقط — فملحق Intelephense في VS Code يقرأه لتوفير ميزة الإكمال التلقائي وتلميحات الأنواع. إن PHPDoc المكتوب بشكل جيد يحول بيئة تطويرك (IDE) إلى مساعد ذكي.


7. قواعد تسمية الدوال

تتبع أسماء دوال PHP المعيار المجتمعي snake_case:

PHP
// ✅ Good function names
function get_user_by_id($id) {}
function calculate_total_price($items) {}
function send_verification_email($email) {}

// ❌ Inconsistent naming
function GetUserById($id) {}    // Don't use PascalCase
function getUserById($id) {}    // Don't use camelCase (methods use this, not functions)
function getuserbyid($id) {}    // Don't use all-lowercase-no-separators
💡 نصيحة: الفعل + الاسم: get_ (جلب)، set_ (تعيين)، calculate_ (حساب)، create_ (صنع)، delete_ (إزالة)، validate_ (تحقق)، format_ (عرض).

❓ أسئلة شائعة

س متى يجب عليّ استخدام نوع الإرجاع void؟
ج عندما تقوم الدالة بتنفيذ إجراء دون إرجاع بيانات — على سبيل المثال، عرض صفحة، أو كتابة سجل، أو إرسال بريد إلكتروني، أو تعديل الحالة العامة. يُشير void إلى المستدعين قائلاً: «هذه الدالة تقوم بشيء ما — فلا تتوقعوا قيمة إرجاع.»
س ما الفرق بين إعلانات الأنواع وتحويل الأنواع؟
ج تشير إعلانات الأنواع في توقيع الدالة إلى «أنا أتوقع هذا النوع». تقوم لغة PHP تلقائيًّا بتحويل الأنواع عند وقت الاستدعاء. قم بتمكين strict_types لتعطيل التحويل التلقائي — مما يؤدي عند تمرير نوع خاطئ إلى ظهور خطأ، وهو ما يُعد أكثر أمانًا.
س هل يمكنني كتابة كود بعد return؟
ج نعم، يمكنك ذلك، لكنه لن يتم تنفيذه. فـ return ينهي الدالة على الفور. وعادةً ما يحذرك بيئة تطوير التطبيقات (IDE) الخاصة بك من وجود «كود لا يمكن الوصول إليه».

📖 ملخص

📝 تمارين

  1. اكتب دالة calculateBMI($weight, $height) تأخذ الوزن (كجم) والطول (م)، وتُرجع مؤشر كتلة الجسم (الوزن ÷ الطول²)، وتُضيف تقييمًا مثل «نقص الوزن / طبيعي / زيادة الوزن / السمنة».
  2. قم بتفعيل الوضع الصارم واكتب دالة formatCurrency(float $amount, string $symbol = "$"): string تعمل على تنسيق مبلغ نقدي. استخدم الوضع الصارم لضمان أن يكون المبلغ دائمًا من النوع العائم.
  3. اكتب دالة getPageUrl(string $base, int $page): string تُنشئ عنوان URL للتقسيم إلى صفحات. إذا كانت الصفحة هي 1، فقم بإرجاع العنوان الأساسي فقط؛ وإلا فقم بإلحاق ?page=N. اكتب تعليقات PHPDoc لهذه الدالة.
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%