ویژگی تصویر

تابع sqlstate() در PHP

  /  PHP   /  تابع sqlstate() در PHP
بنر تبلیغاتی الف
آموزش PHP

در برنامه‌نویسی پایگاه‌داده، SQLSTATE یک استاندارد پنج‌حرفی است که وضعیت یا نوع خطای رخ‌داده را به صورت استاندارد مشخص می‌کند. در PHP توابع و متدهای مختلفی وجود دارد که این مقدار را بازمی‌گردانند یا می‌توان از آن برای تصمیم‌گیری منطقی استفاده کرد. در این مقاله به صورت کاربردی و با مثال‌های واقعی نشان می‌دهیم چگونه در PHP مقدار SQLSTATE را بخوانید، تفسیر کنید و برای ساختن سامانه‌ای مقاوم به خطا از آن استفاده کنید.

SQLSTATE چیست و چرا مهم است؟

SQLSTATE یک کد پنج‌رقمی (مثلاً “00000” برای موفقیت یا “23000” برای خطاهای یکپارچگی) است که به شکلی استاندارد خطاها را در سطح SQL توصیف می‌کند. مزیت استفاده از SQLSTATE این است که مستقل از سیستم مدیریت پایگاه‌داده است و می‌توان رفتارهای کلی (مثل بازگشت تراکنش در هنگام نقض کلید یکتا) را بر پایه کلاس خطاها خودکار کرد.

دسته‌بندی کلی کدهای SQLSTATE

  • کلاس 00 — موفقیت (مثلاً “00000”)
  • کلاس 01 — هشدار
  • کلاس 02 — یافت نشدن رکورد
  • کلاس 23 — خطاهای یکپارچگی (constraint violation)
  • کلاس 42 — خطاهای نگارش یا نحوی

دریافت SQLSTATE در PDO

PDO یکی از مرسوم‌ترین لایه‌های دسترسی به پایگاه‌داده در PHP است. برای خواندن SQLSTATE در PDO می‌توانید از متدهای errorCode() و errorInfo() و همچنین از استثناهای PDOException استفاده کنید.

// نمونه با PDO، حالت Exception برای خطاها
try {
    $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $pdo->exec("INSERT INTO users (id, name) VALUES (1, 'Ali')");
} catch (PDOException $e) {
    // کد SQLSTATE معمولاً در getCode یا در errorInfo قرار دارد
    $sqlstate = $e->getCode();
    $info = $e->errorInfo ?? null;

    echo "SQLSTATE: $sqlstaten";
    if ($info) {
        echo "Driver code: " . $info[1] . "n";
        echo "Driver message: " . $info[2] . "n";
    }
}

توضیح: در این مثال، PDO در حالت پرتاب استثنا تنظیم شده است. هنگام بروز خطا، PDOException پرتاب می‌شود که معمولاً مقدار SQLSTATE را می‌توان از getCode() خواند و جزئیات بیشتر از errorInfo گرفت. errorInfo آرایه‌ای است با ساختار [SQLSTATE, driver_code, driver_message].

مثال با بررسی errorCode از Statement

$stmt = $pdo->prepare("INSERT INTO users (id, name) VALUES (?, ?)");
$stmt->execute([1, 'Ali']);
$state = $stmt->errorCode(); // '00000' در صورت موفقیت
$info = $stmt->errorInfo();

توضیح: متدهای statement هم همانند شیء PDO مقدار SQLSTATE و اطلاعات تکمیلی را بازمی‌گردانند. بررسی errorCode بعد از اجرای دستور برای سیستم‌هایی که از حالت استثنا استفاده نمی‌کنند مفید است.

دریافت SQLSTATE در MySQLi

در MySQLi می‌توان از ویژگی sqlstate شیء MySQLi یا تابع مربوطه در حالت پروسیژرال استفاده کرد. توجه کنید که MySQLi اطلاعات دیگری مانند errno (کد عددی) و error (متن پیام) نیز ارائه می‌دهد.

// نمونه OOP با MySQLi
$mysqli = new mysqli('localhost', 'user', 'pass', 'test');

if ($mysqli->connect_error) {
    echo "Connect error: " . $mysqli->connect_error;
    exit;
}

$result = $mysqli->query("INSERT INTO users (id, name) VALUES (1, 'Ali')");
if (! $result) {
    // مقدار SQLSTATE
    echo "SQLSTATE: " . $mysqli->sqlstate . "n";
    echo "Errno: " . $mysqli->errno . "n";
    echo "Error: " . $mysqli->error . "n";
}

توضیح: در مثال بالا پس از اجرای کوئری اگر خطا رخ دهد مقدار sqlstate در شیء mysqli خوانده می‌شود. ترکیب sqlstate با errno و error به شما تصویر کامل‌تری از رخداد می‌دهد.

ODBC و دیگر درایورها

در محیط‌هایی که از ODBC یا درایورهای دیگر استفاده می‌شود، توابعی مانند odbc_error() و odbc_errormsg() وضعیت و پیام را برمی‌گردانند. معمولاً بهتر است همواره SQLSTATE را جداگانه خوانده و براساس کلاس آن عمل کنید تا کد قابل‌حمل بنویسید.

چگونه از SQLSTATE در مدیریت خطا استفاده کنیم؟

  • تشخیص خطاهای یکپارچگی: SQLSTATE کلاس 23 (مثلاً “23000”) برای تشخیص نقض کلید یکتا یا محدودیت‌های یکپارچگی مفید است.
  • اعمال rollback خودکار: در تراکنش‌ها اگر SQLSTATE نشان‌دهنده خطای بحرانی باشد، تراکنش را برگردانید.
  • منطق بازگشت یا تکرار: برای خطاهای موقتی (مثلاً کلاس 40 یا 08) می‌توان اجرای مجدد را امتحان کرد.
  • ثبت و مانیتورینگ: ثبت SQLSTATE در لاگ به شما امکان تحلیل خطاها و ساخت قواعد واکنشی می‌دهد.

نمونه عملی: مدیریت Duplicate Entry در PDO

try {
    $pdo->beginTransaction();
    $pdo->exec("INSERT INTO users (email) VALUES ('test@example.com')");
    $pdo->commit();
} catch (PDOException $e) {
    $sqlstate = $e->getCode();
    if ($sqlstate === '23000') {
        // معمولاً نقض محدودیت یکپارچگی (مثل unique)
        $pdo->rollBack();
        echo "Duplicate entry detected. Rolling back.n";
    } else {
        $pdo->rollBack();
        throw $e; // برای خطاهای دیگر دوباره پرتاب می‌کنیم
    }
}

توضیح: با بررسی SQLSTATE برابر ‘23000’ می‌توان تشخیص داد که خطای ایجاد شده به یکپارچگی مرتبط است (مثلاً مقادیر تکراری برای کلید یکتا) و به صورت مناسب تراکنش را برگرداند یا پیام کاربر را تغییر داد.

بهترین شیوه‌ها و نکات تکمیلی

  • همیشه SQLSTATE را همراه با پیام و کد در لاگ ذخیره کنید تا در تحلیل بعدی مفید باشد.
  • از کلاس‌های کلی SQLSTATE برای تصمیم‌گیری سطح بالا استفاده کنید (مثلاً کلاس ’23’ برای قوانین یکپارچگی).
  • در سیستم‌های تولیدی، اطلاعات حساس (مثل اسکیوال کامل یا پارامترها) را در لاگ عمومی ننویسید؛ فقط کد و پیام ضروری را ثبت کنید.
  • برای افزایش پایداری، ترکیب SQLSTATE و مدیریت تراکنش را به صورت یک الگوی مرکزی پیاده‌سازی کنید.

جمع‌بندی

SQLSTATE ابزار قدرتمندی برای کلاس‌بندی و مدیریت خطاهای پایگاه‌داده است. در PHP از طریق PDO (errorCode، errorInfo، PDOException)، MySQLi (sqlstate) و درایورهای دیگر می‌توانید این مقدار را بخوانید و براساس آن منطق خطایابی و بازیابی را پیاده‌سازی کنید. استفاده هوشمندانه از SQLSTATE باعث می‌شود برنامه‌های شما مقاوم‌تر، قابل‌حمل‌تر و قابل‌نگهداری‌تر باشند.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: