JSON والبريد الإلكتروني

لغة JSON هي اللغة العالمية للويب — فالتواصل بين الواجهة الأمامية والواجهة الخلفية يعتمد عليها، كما تُستخدم في نقل بيانات واجهات برمجة التطبيقات (API)، بل وحتى ملفات التكوين تُكتب بها. ويُعد البريد الإلكتروني ميزة لا غنى عنها لأي تطبيق ويب — سواء للتحقق من التسجيل، أو إعادة تعيين كلمات المرور، أو الإشعارات. ويغطي هذا الدرس كلا الموضوعين.

1. أساسيات JSON

PHP
<?php
// PHP array/object → JSON string
$data = [
    'name' => 'John',
    'age'  => 25,
    'skills' => ['PHP', 'MySQL', 'JavaScript'],
    'isActive' => true,
    'score' => null,
];

$json = json_encode($data);
echo $json;
// {"name":"John","age":25,"skills":["PHP","MySQL","JavaScript"],"isActive":true,"score":null}
?>

(1) خيارات json_encode الشائعة

PHP
<?php
$data = ['name' => 'John', 'age' => 25, 'score' => null];

// Pretty print (human-readable)
echo json_encode($data, JSON_PRETTY_PRINT);
/*
{
    "name": "John",
    "age": 25,
    "score": null
}
*/

// Don't escape Unicode (preserves non-ASCII characters)
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// {"name":"John","age":25,"score":null}

// Combine options
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);

// Handle null (PHP 8.3+)
echo json_encode($data, JSON_UNESCAPED_UNICODE, JSON_INVALID_UTF8_IGNORE);
?>
الخيار التأثير
JSON_PRETTY_PRINT التنسيق المتراجع
JSON_UNESCAPED_UNICODE لا تقم بتحويل الأحرف غير ASCII إلى \uXXXX
JSON_UNESCAPED_SLASHES لا تهرب من / إلى \/
JSON_NUMERIC_CHECK تحويل السلاسل الرقمية إلى أرقام
JSON_FORCE_OBJECT الإخراج {} للمصفوفات الفارغة

2. json_decode — تحليل JSON

PHP
<?php
$json = '{"name":"John","age":25,"skills":["PHP","MySQL"]}';

// Default: returns an object
$obj = json_decode($json);
echo $obj->name;  // John
echo $obj->skills[0];  // PHP

// Second parameter true → returns an associative array
$arr = json_decode($json, true);
echo $arr['name'];  // John

// Error handling
$badJson = '{name: John}';  // Missing double quotes
$result = json_decode($badJson);
if (json_last_error() !== JSON_ERROR_NONE) {
    echo "JSON parse error: " . json_last_error_msg();
    // JSON parse error: Syntax error
}

// PHP 7.3+ cleaner syntax
$result = json_decode($badJson);
echo json_last_error_msg();
?>

▶ مثال: قراءة وكتابة ملفات JSON

PHP
<?php
// === Writing a JSON File ===
$config = [
    'app_name' => 'MyBlog',
    'version'  => '1.2.0',
    'database' => [
        'host' => 'localhost',
        'name' => 'myblog',
    ],
    'features' => ['blog', 'comments', 'search'],
];

$json = json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
file_put_contents('config.json', $json, LOCK_EX);
echo "Config file written ✅";

// === Reading a JSON File ===
$json = file_get_contents('config.json');
$config = json_decode($json, true);

echo "App name: {$config['app_name']}<br>";
echo "Database host: {$config['database']['host']}<br>";
echo "Features: " . implode(', ', $config['features']) . "<br>";
?>
▶ جرّب الكود

▶ مثال: محاكاة واجهة برمجة التطبيقات REST

PHP
<?php
// api.php — simple JSON API
header('Content-Type: application/json; charset=utf-8');

$method = $_SERVER['REQUEST_METHOD'];
$path = $_GET['path'] ?? '';

$users = [
    ['id' => 1, 'name' => 'John', 'email' => 'j@j.com'],
    ['id' => 2, 'name' => 'Jane', 'email' => 'ja@ja.com'],
];

if ($method === 'GET' && $path === 'users') {
    echo json_encode(['status' => 'ok', 'data' => $users], JSON_UNESCAPED_UNICODE);
} elseif ($method === 'GET' && preg_match('/users\/(\d+)/', $path, $m)) {
    $id = (int)$m[1];
    $user = $users[$id - 1] ?? null;
    if ($user) {
        echo json_encode(['status' => 'ok', 'data' => $user], JSON_UNESCAPED_UNICODE);
    } else {
        http_response_code(404);
        echo json_encode(['status' => 'error', 'message' => 'User not found']);
    }
} elseif ($method === 'POST' && $path === 'users') {
    $input = json_decode(file_get_contents('php://input'), true);
    // In a real app this would write to the database
    echo json_encode(['status' => 'ok', 'message' => 'User created']);
} else {
    http_response_code(404);
    echo json_encode(['status' => 'error', 'message' => 'Unknown endpoint']);
}
?>
▶ جرّب الكود

3. إرسال البريد الإلكتروني

(1) أساسيات دالة mail()

PHP
<?php
$to = "user@example.com";
$subject = "=?UTF-8?B?" . base64_encode("Password Reset Notification") . "?="; // Encoded subject
$message = "Hello, please click the link below to reset your password:\n\n";
$message .= "https://myblog.com/reset?token=abc123";
$headers = "From: noreply@myblog.com\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";

if (mail($to, $subject, $message, $headers)) {
    echo "Email sent ✅";
} else {
    echo "Email failed ❌";
}
?>
💡 نصيحة: يتطلب mail() أن يكون برنامج sendmail/Postfix مُهيأً على الخادم. لا يتضمن XAMPP هذا البرنامج بشكل افتراضي — وللاختبار وظائف البريد الإلكتروني، يُفضل استخدام SMTP (القسم التالي).

▶ مثال: رسالة بريد إلكتروني للتحقق بتنسيق HTML

PHP
<?php
function sendVerificationEmail(string $to, string $token): bool {
    $subject = "=?UTF-8?B?" . base64_encode("Please verify your email") . "?=";
    
    // HTML email
    $message = "<html><body>";
    $message .= "<h2>Welcome to MyBlog!</h2>";
    $message .= "<p>Please click the link below to verify your email:</p>";
    $message .= "<a href='https://myblog.com/verify?token={$token}'>Verify Email</a>";
    $message .= "<p>If the link doesn't work, copy and paste this address:</p>";
    $message .= "<p>https://myblog.com/verify?token={$token}</p>";
    $message .= "</body></html>";
    
    $headers = "From: noreply@myblog.com\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html; charset=UTF-8\r\n";
    
    return mail($to, $subject, $message, $headers);
}

$token = bin2hex(random_bytes(32));
sendVerificationEmail('user@example.com', $token);
?>
▶ جرّب الكود

4. PHPMailer (موصى به)

mail() بسيط ولكنه محدود. أما PHPMailer فهو المعيار السائد فعليًّا لإرسال البريد الإلكتروني باستخدام لغة PHP:

BASH
# Install
composer require phpmailer/phpmailer
PHP
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php';

function sendEmailSMTP(string $to, string $subject, string $body): bool {
    $mail = new PHPMailer(true);
    
    try {
        // Server settings
        $mail->isSMTP();
        $mail->Host       = 'smtp.gmail.com';    // SMTP server
        $mail->SMTPAuth   = true;
        $mail->Username   = 'your@gmail.com';     // Sender email
        $mail->Password   = 'app-password';       // App-specific password
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port       = 587;
        $mail->CharSet    = 'UTF-8';
        
        // Recipients
        $mail->setFrom('your@gmail.com', 'MyBlog');
        $mail->addAddress($to);
        
        // Content
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body    = $body;
        $mail->AltBody = strip_tags($body);  // Plain-text fallback
        
        $mail->send();
        return true;
    } catch (Exception $e) {
        echo "Email failed: {$mail->ErrorInfo}";
        return false;
    }
}

sendEmailSMTP(
    'user@example.com',
    'Password Reset',
    '<h3>MyBlog Password Reset</h3><p>Click <a href="#">here</a> to reset your password.</p>'
);
?>
💡 نصيحة: عند إجراء الاختبار باستخدام Gmail: قم بتفعيل المصادقة الثنائية → قم بإنشاء كلمة مرور خاصة بالتطبيق → استخدم تلك الكلمة (وليس كلمة مرور تسجيل الدخول إلى Gmail). سيرفض Gmail أي محاولات اتصال إذا استخدمت كلمة مرورك الفعلية مباشرةً.


5. أفضل الممارسات في مجال البريد الإلكتروني

PHP
<?php
class MailService {
    public function sendWelcome(string $email, string $username): bool {
        $subject = "Welcome to MyBlog";
        $body = file_get_contents(__DIR__ . '/templates/welcome.html');
        $body = str_replace('{{username}}', htmlspecialchars($username), $body);
        
        return sendEmailSMTP($email, $subject, $body);
    }
    
    public function sendPasswordReset(string $email, string $token): bool {
        $link = "https://myblog.com/reset?token={$token}";
        $subject = "Password Reset";
        $body = "
            <h3>Password Reset Request</h3>
            <p>Click the link below to reset your password (valid for 1 hour):</p>
            <a href='{$link}'>{$link}</a>
            <p>If you didn't request a password reset, please ignore this email.</p>
        ";
        return sendEmailSMTP($email, $subject, $body);
    }
    
    public function sendNotification(string $email, string $title, string $message): bool {
        $subject = "📢 {$title}";
        $body = "<h3>{$title}</h3><p>{$message}</p>";
        return sendEmailSMTP($email, $subject, $body);
    }
}
?>

❓ أسئلة شائعة

س لماذا يحظى JSON بشعبية أكبر من XML؟
ج لأنه خفيف الحجم (يحتوي على عدد أقل من العلامات)، ويدعمه JavaScript بشكل أصلي (JSON.parse)، كما أنه سهل القراءة للغاية. في PHP، json_encode/json_decode يتعامل معه في سطر واحد، بينما يتطلب XML عدة خطوات.
س هل يجب عليّ استخدام mail() أم مكتبة SMTP؟
ج يُعد mail() خيارًا مناسبًا للتطوير المحلي (إذا تم تهيئته). استخدم مكتبة SMTP (PHPMailer) في بيئة الإنتاج — فهي تتميز بمعالجة أفضل للأخطاء، وتدعم المرفقات والمستلمين المتعددين، ولا تتأثر بإعدادات البريد على الخادم.
س هل يمكنني استخدام ملف JSON كقاعدة بيانات؟
ج نعم، بالنسبة لمجموعات البيانات الصغيرة وحالات الاستخدام الفردي (مثل ملفات التكوين). أما بالنسبة لعمليات القراءة/الكتابة المتزامنة لعدة مستخدمين والاستعلامات المعقدة، فيجب عليك استخدام MySQL. المشاكل المتعلقة باستخدام JSON كقاعدة بيانات هي: عدم إمكانية الكتابة المتزامنة، وعدم وجود فهارس مما يؤدي إلى بطء الاستعلامات، وتدهور الأداء مع نمو حجم البيانات.

📖 ملخص

📝 تمارين

  1. قم بإنشاء ملف تكوين settings.json واستخدم لغة PHP لقراءة وعرض جميع عناصر التكوين.
  2. اكتب واجهة برمجة تطبيقات (API) بسيطة بتنسيق JSON: /users تعرض جميع المستخدمين، و/users/1 تعرض المستخدم الذي يحمل المعرّف ID=1. قم بمحاكاة ذلك باستخدام معلمات GET.
  3. أضف ميزة التحقق عبر البريد الإلكتروني إلى نظام التسجيل الخاص بك: قم بإنشاء رمز تحقق عند التسجيل (قم بتخزينه في ملف أو قاعدة بيانات)، وأرسل رسالة بريد إلكتروني للتحقق (اختبرها محليًّا باستخدام mail() أو SMTP).
Web-Tutorial.com

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

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

100%