إنشاء استثناءات مخصّصة
وسّعوا الفئة Exception لإنشاء أنواع أخطاء خاصة بالمجال
إنشاء استثناءات مخصّصة درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.
لماذا نستخدم الاستثناءات المخصصة؟
تتيح لك الاستثناءات المخصصة ما يلي:
- تمييز أخطاء تطبيقك عن أخطاء PHP العامة
- حمل بيانات خاصة بالمجال (مثل معرّف الطلب ومعرّف المستخدم وغيرهما)
- التعامل مع أنواع أخطاء محددة في طبقات مختلفة
- إنشاء تسلسلات هرمية للأخطاء واضحة وموضّحة ذاتيًا
توسيع Exception
أنشئ استثناءً مخصصًا بتوسيع الفئة الأساسية Exception:
<?php
class ValidationException extends \Exception
{
private array $errors;
public function __construct(array $errors, string $message = '', int $code = 0)
{
$this->errors = $errors;
parent::__construct($message ?: implode(', ', $errors), $code);
}
public function getErrors(): array
{
return $this->errors;
}
}استخدام استثناء مخصص
اطرح استثناءك المخصص وتعامل معه:
<?php
function createUser(array $data): void {
$errors = [];
if (empty($data['email'])) $errors[] = 'Email required';
if (empty($data['name'])) $errors[] = 'Name required';
if ($errors) {
throw new ValidationException($errors);
}
// save user...
}
try {
createUser([]);
} catch (ValidationException $e) {
foreach ($e->getErrors() as $err) {
echo '- ' . $err . PHP_EOL;
}
}تصميم التسلسل الهرمي للاستثناءات
صمّم تسلسلًا هرميًا لمجالك:
<?php
// Base exception for your app
class AppException extends \RuntimeException {}
// Domain-specific exceptions
class NotFoundException extends AppException {}
class AuthException extends AppException {}
class PaymentException extends AppException {}
// Specific payment errors
class InsufficientFundsException extends PaymentException {
public function __construct(public readonly float $balance, public readonly float $required) {
parent::__construct("Insufficient funds: have $balance, need $required");
}
}التعامل حسب التسلسل الهرمي
تعامل مع فئة أساسية لمعالجة جميع الاستثناءات المشتقة منها:
<?php
try {
processPayment($order);
} catch (InsufficientFundsException $e) {
echo 'Low balance: need ' . $e->required;
} catch (PaymentException $e) {
echo 'Payment failed: ' . $e->getMessage();
} catch (AppException $e) {
echo 'App error: ' . $e->getMessage();
} catch (\Throwable $e) {
// Last resort
error_log($e);
}إضافة السياق إلى الاستثناءات
أثرِ الاستثناءات ببيانات إضافية لتسهيل تصحيح الأخطاء:
<?php
class HttpException extends \RuntimeException
{
public function __construct(
private int $statusCode,
string $message = '',
?\Throwable $previous = null
) {
parent::__construct($message, $statusCode, $previous);
}
public function getStatusCode(): int
{
return $this->statusCode;
}
}مثال على استثناء HTTP
استخدام استثناء HTTP في تطبيق ويب:
<?php
try {
$user = findUserById($id);
if (!$user) throw new HttpException(404, 'User not found');
if (!$user->canAccess($resource)) {
throw new HttpException(403, 'Access denied');
}
} catch (HttpException $e) {
http_response_code($e->getStatusCode());
echo json_encode(['error' => $e->getMessage()]);
}الاستثناءات القائمة على الواجهات
استخدم الواجهات لتجميع فئات الاستثناءات غير المرتبطة:
<?php
interface UserFacingException
{
public function getUserMessage(): string;
}
class ValidationException extends \Exception implements UserFacingException
{
public function getUserMessage(): string
{
return 'Please check your input: ' . $this->getMessage();
}
}
// In controller:
catch (UserFacingException $e) {
echo $e->getUserMessage();
}نمط المُنشئ المسمّى
استخدم أساليب المصنع الساكنة لسيناريوهات الاستثناء الشائعة:
<?php
class OrderException extends \RuntimeException
{
public static function notFound(int $id): self
{
return new self("Order #$id not found", 404);
}
public static function alreadyShipped(int $id): self
{
return new self("Order #$id already shipped", 409);
}
}
throw OrderException::notFound($orderId);تسلسل الاستثناءات
حوّل بيانات الاستثناء إلى مصفوفة لتسجيلها أو إرجاعها في استجابات API:
<?php
function exceptionToArray(\Throwable $e): array {
return [
'type' => get_class($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
'previous' => $e->getPrevious()
? exceptionToArray($e->getPrevious())
: null,
];
}أفضل الممارسات للاستثناءات المخصصة
إرشادات لتصميم الاستثناءات المخصصة:
- وسّع
RuntimeExceptionللحالات غير المتوقعة - وسّع
LogicExceptionلأخطاء المبرمج (الوسيطات غير الصالحة) - لا تنشئ فئة استثناء لكل رسالة محتملة — استخدم الرموز البرمجية بدلًا من ذلك
- أبقِ أسماء فئات الاستثناءات بصيغة PascalCase ومنتهية بـ Exception
- وثّق الاستثناءات التي يمكن لكل أسلوب طرحها
تحقق سريع
ما الفئة الأساسية في PHP التي ينبغي توسيعها لإنشاء استثناء مخصص يمثّل خطأ منطقيًا في الكود؟
مراجعة: الاستثناءات المخصصة
ملخص الاستثناءات المخصصة:
- وسّع
Exceptionأو فئة فرعية منها - أضف خصائص وأساليب خاصة بالمجال
- صمّم تسلسلات هرمية — تعامل مع الفئة الأب للتعامل مع جميع الفئات الابنة
- استخدم الواجهات لتجميع الاستثناءات غير المرتبطة
- استخدم المُنشئات الساكنة المسمّاة لتوضيح الغرض
- استدعِ
parent::__construct()دائمًا
الأسئلة الشائعة
هل درس «إنشاء استثناءات مخصّصة» مجاني؟
نعم — نص درس «إنشاء استثناءات مخصّصة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.
ماذا ستتعلم في «إنشاء استثناءات مخصّصة»؟
وسّعوا الفئة Exception لإنشاء أنواع أخطاء خاصة بالمجال تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟
لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «إنشاء استثناءات مخصّصة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟
نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- أنواع أخطاء PHP وإعدادات الإبلاغ عنها
- Try وCatch وFinally
- إنشاء استثناءات مخصّصة
- تسجيل الأخطاء وأفضل الممارسات