آموزش برنامه نویسی PHP-جلسه بیست و هشتم

آموزش برنامه نویسی PHP-جلسه بیست و هشتم

در این قسمت از آموزش PHP و MySQL با دستور DELETE آشنا می‌شویم و یاد می‌گیریم چگونه اطلاعات موردنظر را از دیتابیس حذف کنیم. همچنین نحوه استفاده از شرط WHERE، حذف یک یا چند رکورد، اجرای دستور DELETE با PDO و MySQLi، ساخت فرم حذف اطلاعات و نکات امنیتی مهم مانند جلوگیری از SQL Injection را همراه با مثال‌های کاربردی بررسی خواهیم کرد.

Table of contents [Show] [Hide]

مقدمه

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

برای حذف رکوردها از جدول‌های MySQL از دستور DELETE استفاده می‌کنیم. این دستور یکی از دستورات اصلی SQL برای مدیریت اطلاعات دیتابیس است و به ما اجازه می‌دهد یک یا چند رکورد را بر اساس شرایط مشخص حذف کنیم.

در این قسمت از آموزش PHP و MySQL قصد داریم به‌صورت کامل با دستور DELETE آشنا شویم و نحوه اجرای آن را با PHP و روش‌های PDO و MySQLi بررسی کنیم. همچنین ساخت فرم حذف اطلاعات، استفاده از شرط WHERE، حذف چند رکورد، حذف اطلاعات مرتبط با JOIN، استفاده از تراکنش‌ها، جلوگیری از SQL Injection و نکات امنیتی مهم هنگام حذف اطلاعات را آموزش خواهیم داد.

1. دستور DELETE در MySQL چیست؟

دستور DELETE برای حذف یک یا چند رکورد از یک جدول در دیتابیس MySQL استفاده می‌شود.

فرض کنید جدولی به نام users داریم که اطلاعات کاربران در آن ذخیره شده است. اگر بخواهیم اطلاعات کاربری با شناسه مشخصی را حذف کنیم، می‌توانیم از دستور DELETE استفاده کنیم.

ساختار کلی دستور DELETE به شکل زیر است:

DELETE FROM table_name
WHERE condition;

در این ساختار:

  • DELETE: دستور حذف اطلاعات را مشخص می‌کند.
  • FROM: برای مشخص کردن جدولی استفاده می‌شود که قصد حذف اطلاعات آن را داریم.
  • table_name: نام جدول موردنظر است.
  • WHERE: شرطی را مشخص می‌کند که تعیین می‌کند کدام رکوردها حذف شوند.

نکته بسیار مهم این است که اگر دستور DELETE را بدون شرط WHERE اجرا کنیم، تمام رکوردهای جدول حذف خواهند شد. بنابراین هنگام استفاده از این دستور باید دقت زیادی داشته باشیم.

2. ساخت جدول برای مثال‌های آموزشی

برای درک بهتر دستور DELETE، ابتدا جدولی به نام users ایجاد می‌کنیم. این جدول شامل شناسه، نام، ایمیل و سن کاربران است.

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(150) NOT NULL UNIQUE,
    age INT
);

اکنون چند رکورد آزمایشی در جدول قرار می‌دهیم:

INSERT INTO users (name, email, age)
VALUES
('Ali', 'ali@example.com', 25),
('Sara', 'sara@example.com', 22),
('Reza', 'reza@example.com', 30),
('Mina', 'mina@example.com', 19),
('Amir', 'amir@example.com', 27);

برای مشاهده اطلاعات جدول می‌توانیم از دستور SELECT استفاده کنیم:

SELECT * FROM users;

اکنون جدول users دارای پنج رکورد است که در مثال‌های بعدی از آن‌ها برای آموزش دستور DELETE استفاده خواهیم کرد.

3. حذف یک رکورد با استفاده از DELETE

یکی از ساده‌ترین کاربردهای DELETE حذف یک رکورد مشخص از جدول است.

برای مثال، فرض کنید می‌خواهیم اطلاعات کاربری با شناسه 3 را حذف کنیم:

DELETE FROM users
WHERE id = 3;

با اجرای این دستور، رکوردی که مقدار ستون id آن برابر با 3 است، از جدول users حذف خواهد شد.

برای بررسی نتیجه می‌توانیم دستور زیر را اجرا کنیم:

SELECT * FROM users;

در خروجی دیگر اطلاعات کاربر دارای شناسه 3 نمایش داده نمی‌شود.

استفاده از شناسه اصلی یا Primary Key یکی از روش‌های مناسب برای حذف دقیق یک رکورد است؛ زیرا معمولاً این مقدار برای هر رکورد منحصربه‌فرد است.

4. حذف چند رکورد با استفاده از WHERE

دستور DELETE فقط برای حذف یک رکورد استفاده نمی‌شود. با استفاده از شرط‌های مختلف می‌توانیم چندین رکورد را نیز به‌صورت هم‌زمان حذف کنیم.

برای مثال، اگر بخواهیم تمام کاربرانی را که سن آن‌ها کمتر از 20 سال است حذف کنیم، می‌توانیم بنویسیم:

DELETE FROM users
WHERE age < 20;

در این مثال تمام رکوردهایی که مقدار ستون age آن‌ها کمتر از 20 باشد، حذف خواهند شد.

همچنین می‌توانیم از شرط‌های دیگری مانند بزرگ‌تر، کوچک‌تر، مساوی و نامساوی استفاده کنیم:

DELETE FROM users
WHERE age > 30;

این دستور تمام کاربرانی را که سن آن‌ها بیشتر از 30 سال است حذف می‌کند.

برای حذف کاربرانی که سن آن‌ها برابر با 25 نیست، می‌توانیم از دستور زیر استفاده کنیم:

DELETE FROM users
WHERE age != 25;

در این مثال فقط رکوردهایی حذف می‌شوند که سن آن‌ها با 25 متفاوت باشد.

5. استفاده از عملگرهای AND و OR در دستور DELETE

در بخش WHERE می‌توانیم از عملگرهای منطقی برای ترکیب چند شرط استفاده کنیم.

استفاده از AND

عملگر AND زمانی استفاده می‌شود که بخواهیم تمام شرط‌های مشخص‌شده برقرار باشند.

برای مثال، فرض کنید می‌خواهیم کاربری را حذف کنیم که نام او Ali و سن او 25 سال باشد:

DELETE FROM users
WHERE name = 'Ali'
AND age = 25;

در این مثال فقط رکوردهایی حذف می‌شوند که هر دو شرط را داشته باشند.

استفاده از OR

عملگر OR زمانی کاربرد دارد که برقرار بودن حداقل یکی از شرط‌ها کافی باشد.

برای مثال:

DELETE FROM users
WHERE name = 'Ali'
OR name = 'Sara';

این دستور تمام کاربرانی را که نام آن‌ها Ali یا Sara است، حذف می‌کند.

هنگام ترکیب AND و OR بهتر است از پرانتز استفاده کنیم تا محدوده شرط‌ها کاملاً مشخص باشد.

DELETE FROM users
WHERE (age < 20 OR age > 60)
AND name != 'Ali';

در این مثال کاربرانی حذف می‌شوند که سن آن‌ها کمتر از 20 یا بیشتر از 60 باشد و نام آن‌ها نیز Ali نباشد.

6. استفاده از IN برای حذف چند مقدار مشخص

اگر بخواهیم رکوردهایی را حذف کنیم که مقدار یک ستون آن‌ها در میان چند مقدار مشخص قرار دارد، می‌توانیم از عملگر IN استفاده کنیم.

برای مثال:

DELETE FROM users
WHERE id IN (1, 2, 5);

این دستور رکوردهایی را حذف می‌کند که شناسه آن‌ها برابر با 1، 2 یا 5 باشد.

استفاده از IN باعث می‌شود به‌جای نوشتن چند شرط OR، بتوانیم کد ساده‌تر و خواناتری داشته باشیم.

7. استفاده از BETWEEN برای حذف اطلاعات در یک محدوده

با استفاده از BETWEEN می‌توانیم رکوردهایی را حذف کنیم که مقدار یک ستون آن‌ها در یک محدوده مشخص قرار دارد.

برای مثال، اگر بخواهیم کاربران دارای سن بین 20 تا 30 سال را حذف کنیم، می‌توانیم بنویسیم:

DELETE FROM users
WHERE age BETWEEN 20 AND 30;

عملگر BETWEEN هر دو مقدار ابتدا و انتهای محدوده را نیز شامل می‌شود.

8. استفاده از LIKE برای حذف اطلاعات بر اساس الگو

گاهی لازم است رکوردهایی را حذف کنیم که مقدار یک ستون آن‌ها با یک الگوی مشخص مطابقت دارد. برای این کار می‌توانیم از عملگر LIKE استفاده کنیم.

برای مثال، اگر بخواهیم کاربرانی را حذف کنیم که ایمیل آن‌ها با دامنه example.com پایان پیدا می‌کند، می‌توانیم از دستور زیر استفاده کنیم:

DELETE FROM users
WHERE email LIKE '%@example.com';

در این دستور علامت درصد (%) نشان‌دهنده هر تعداد کاراکتر است.

مثال دیگر:

DELETE FROM users
WHERE name LIKE 'A%';

این دستور تمام کاربرانی را حذف می‌کند که نام آن‌ها با حرف A شروع شده باشد.

به دلیل گسترده بودن دامنه رکوردهای قابل حذف با LIKE، بهتر است قبل از اجرای چنین دستورهایی، شرط موردنظر را با SELECT بررسی کنیم.

9. حذف اطلاعات با مقدار NULL

در MySQL ممکن است بعضی ستون‌ها مقدار NULL داشته باشند. برای حذف رکوردهایی که یک ستون مشخص آن‌ها مقدار NULL دارد، باید از IS NULL استفاده کنیم.

برای مثال:

DELETE FROM users
WHERE age IS NULL;

این دستور تمام کاربرانی را حذف می‌کند که مقدار ستون age آن‌ها NULL است.

برای حذف رکوردهایی که مقدار ستون مشخص‌شده آن‌ها NULL نیست، از IS NOT NULL استفاده می‌کنیم:

DELETE FROM users
WHERE age IS NOT NULL;

نکته مهم این است که برای بررسی NULL نباید از عملگر مساوی استفاده کنیم. عبارت age = NULL روش صحیح بررسی مقدار NULL نیست.

10. حذف اطلاعات با استفاده از ORDER BY و LIMIT

در MySQL می‌توانیم در برخی دستورهای DELETE از ORDER BY و LIMIT استفاده کنیم تا تعداد رکوردهای حذف‌شده را محدود کنیم.

برای مثال، اگر بخواهیم فقط قدیمی‌ترین رکورد را بر اساس شناسه حذف کنیم، می‌توانیم بنویسیم:

DELETE FROM users
ORDER BY id ASC
LIMIT 1;

در این مثال ابتدا رکوردها بر اساس شناسه به‌صورت صعودی مرتب می‌شوند و سپس فقط یک رکورد حذف می‌شود.

همچنین می‌توانیم آخرین رکورد ثبت‌شده را حذف کنیم:

DELETE FROM users
ORDER BY id DESC
LIMIT 1;

این دستور جدیدترین رکورد را بر اساس شناسه حذف می‌کند.

استفاده از LIMIT در حذف اطلاعات زمانی کاربرد دارد که بخواهیم تعداد مشخصی از رکوردها را حذف کنیم؛ اما بهتر است در عملیات حساس، علاوه بر LIMIT از شرط‌های دقیق نیز استفاده کنیم.

11. اجرای دستور DELETE در PHP با استفاده از PDO

اکنون که با ساختار دستور DELETE در MySQL آشنا شدیم، نوبت به اجرای آن در PHP می‌رسد.

یکی از روش‌های مناسب برای ارتباط PHP با MySQL استفاده از PDO است. این روش از Prepared Statements پشتیبانی می‌کند و امکان اجرای کوئری‌های پارامتری را فراهم می‌سازد.

اتصال به دیتابیس با PDO

ابتدا باید اتصال به دیتابیس را ایجاد کنیم:

<?php

$host = 'localhost';
$dbname = 'my_database';
$username = 'root';
$password = '';

try {

    $pdo = new PDO(
        "mysql:host=$host;dbname=$dbname;charset=utf8mb4",
        $username,
        $password
    );

    $pdo->setAttribute(
        PDO::ATTR_ERRMODE,
        PDO::ERRMODE_EXCEPTION
    );

} catch (PDOException $e) {

    die('خطا در اتصال به دیتابیس');

}

?>

در این مثال ابتدا اطلاعات اتصال مشخص شده‌اند. سپس با استفاده از PDO یک اتصال به دیتابیس ایجاد می‌کنیم و حالت گزارش خطا را روی Exception قرار می‌دهیم.

حذف یک کاربر با استفاده از PDO

فرض کنید می‌خواهیم اطلاعات کاربری با شناسه 3 را حذف کنیم:

<?php

$id = 3;

$sql = "DELETE FROM users WHERE id = :id";

$stmt = $pdo->prepare($sql);

$stmt->execute([
    ':id' => $id
]);

echo 'عملیات حذف با موفقیت انجام شد.';

?>

در این مثال ابتدا کوئری را با استفاده از prepare آماده می‌کنیم. سپس شناسه کاربر را به‌عنوان پارامتر به execute ارسال می‌کنیم.

این روش نسبت به قرار دادن مستقیم مقدار متغیر در متن SQL امن‌تر است و از SQL Injection جلوگیری می‌کند.

12. بررسی تعداد رکوردهای حذف‌شده با PDO

یکی از متدهای کاربردی PDO، متد rowCount است. با استفاده از این متد می‌توانیم تعداد ردیف‌هایی را که توسط دستور DELETE حذف شده‌اند، بررسی کنیم.

مثال:

<?php

$id = 3;

$sql = "DELETE FROM users WHERE id = :id";

$stmt = $pdo->prepare($sql);

$stmt->execute([
    ':id' => $id
]);

$deletedRows = $stmt->rowCount();

if ($deletedRows > 0) {

    echo 'رکورد با موفقیت حذف شد.';

} else {

    echo 'رکوردی برای حذف پیدا نشد.';

}

?>

در این مثال اگر حداقل یک رکورد حذف شده باشد، پیام موفقیت نمایش داده می‌شود. در غیر این صورت مشخص می‌شود که هیچ رکوردی با شرط تعیین‌شده حذف نشده است.

در دستور DELETE مقدار rowCount معمولاً تعداد رکوردهای حذف‌شده را نشان می‌دهد. این مقدار برای بررسی نتیجه عملیات حذف بسیار کاربردی است.

13. اجرای دستور DELETE در PHP با استفاده از MySQLi

روش دیگر ارتباط PHP با MySQL استفاده از MySQLi است. این افزونه به‌صورت اختصاصی برای کار با دیتابیس MySQL طراحی شده است و از Prepared Statements پشتیبانی می‌کند.

اتصال به دیتابیس با MySQLi

<?php

$conn = new mysqli(
    'localhost',
    'root',
    '',
    'my_database'
);

if ($conn->connect_error) {

    die('خطا در اتصال به دیتابیس');

}

$conn->set_charset('utf8mb4');

?>

حذف اطلاعات با MySQLi

برای حذف کاربری با شناسه مشخص می‌توانیم به شکل زیر عمل کنیم:

<?php

$id = 3;

$sql = "DELETE FROM users WHERE id = ?";

$stmt = $conn->prepare($sql);

$stmt->bind_param('i', $id);

if ($stmt->execute()) {

    if ($stmt->affected_rows > 0) {

        echo 'کاربر با موفقیت حذف شد.';

    } else {

        echo 'کاربری با شناسه موردنظر پیدا نشد.';

    }

} else {

    echo 'خطا در حذف اطلاعات.';

}

$stmt->close();
$conn->close();

?>

در این مثال:

  • از علامت سؤال برای مشخص کردن پارامتر کوئری استفاده کرده‌ایم.
  • متد bind_param مقدار شناسه را به کوئری متصل می‌کند.
  • حرف i نشان‌دهنده نوع عدد صحیح است.
  • متد execute دستور DELETE را اجرا می‌کند.
  • ویژگی affected_rows تعداد رکوردهای حذف‌شده را مشخص می‌کند.

14. ساخت فرم حذف اطلاعات با PHP و MySQL

در بسیاری از وب‌سایت‌ها مدیران می‌توانند اطلاعات کاربران، محصولات یا مقالات را از طریق پنل مدیریت حذف کنند.

برای پیاده‌سازی این قابلیت معمولاً یک دکمه حذف در کنار هر رکورد قرار می‌دهیم. با کلیک روی این دکمه، شناسه رکورد به فایل PHP ارسال می‌شود و پس از بررسی مجوزها، دستور DELETE اجرا خواهد شد.

برای حذف اطلاعات بهتر است از متد POST استفاده کنیم؛ زیرا حذف رکورد یک عملیات تغییردهنده در دیتابیس است و نباید با باز کردن ساده یک لینک GET اجرا شود.

مرحله اول: نمایش اطلاعات کاربران

ابتدا اطلاعات کاربران را از دیتابیس دریافت می‌کنیم:

<?php

$stmt = $pdo->query(
    "SELECT id, name, email FROM users ORDER BY id DESC"
);

$users = $stmt->fetchAll(PDO::FETCH_ASSOC);

?>

<table>

    <thead>
        <tr>
            <th>شناسه</th>
            <th>نام</th>
            <th>ایمیل</th>
            <th>عملیات</th>
        </tr>
    </thead>

    <tbody>

        <?php foreach ($users as $user): ?>

            <tr>

                <td>
                    <?= htmlspecialchars((string) $user['id'], ENT_QUOTES, 'UTF-8') ?>
                </td>

                <td>
                    <?= htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') ?>
                </td>

                <td>
                    <?= htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8') ?>
                </td>

                <td>

                    <form action="delete-user.php" method="post">

                        <input
                            type=hidden
                            name=id
                            value="<?= htmlspecialchars((string) $user['id'], ENT_QUOTES, 'UTF-8') ?>"
                        >

                        <button type=submit>حذف</button>

                    </form>

                </td>

            </tr>

        <?php endforeach; ?>

    </tbody>

</table>

در این کد ابتدا اطلاعات کاربران دریافت می‌شود و سپس در یک جدول HTML نمایش داده می‌شوند. برای هر کاربر نیز یک فرم حذف ایجاد کرده‌ایم که شناسه همان کاربر را با متد POST ارسال می‌کند.

مرحله دوم: حذف کاربر در فایل delete-user.php

اکنون باید فایلی به نام delete-user.php ایجاد کنیم تا اطلاعات ارسالی را دریافت و رکورد موردنظر را حذف کند.

<?php

require_once 'database.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {

    http_response_code(405);
    exit('روش ارسال درخواست مجاز نیست.');

}

$id = filter_input(
    INPUT_POST,
    'id',
    FILTER_VALIDATE_INT
);

if (!$id || $id < 1) {

    exit('شناسه کاربر معتبر نیست.');

}

$sql = "DELETE FROM users WHERE id = :id";

$stmt = $pdo->prepare($sql);

try {

    $stmt->execute([
        ':id' => $id
    ]);

    if ($stmt->rowCount() > 0) {

        echo 'کاربر با موفقیت حذف شد.';

    } else {

        echo 'کاربر موردنظر پیدا نشد.';

    }

} catch (PDOException $e) {

    echo 'خطایی هنگام حذف اطلاعات رخ داد.';

}

?>

در این فایل ابتدا بررسی می‌کنیم درخواست از نوع POST باشد. سپس شناسه کاربر را دریافت و اعتبارسنجی می‌کنیم. در ادامه با استفاده از Prepared Statement رکورد موردنظر را حذف می‌کنیم.

در یک سیستم واقعی، قبل از اجرای دستور DELETE باید بررسی شود که کاربر واردشده اجازه حذف اطلاعات را دارد یا خیر. همچنین باید از توکن CSRF برای جلوگیری از ارسال درخواست‌های جعلی استفاده کنیم.

15. استفاده از تأییدیه قبل از حذف اطلاعات

حذف اطلاعات ممکن است باعث از دست رفتن داده‌های مهم شود. به همین دلیل بهتر است پیش از اجرای عملیات حذف، از کاربر تأییدیه دریافت کنیم.

برای این کار می‌توانیم از ویژگی onsubmit در فرم HTML استفاده کنیم:

<form
    action="delete-user.php"
    method="post"
    onsubmit="return confirm('آیا از حذف این کاربر مطمئن هستید؟');"
>

    <input type=hidden name=id value="1">

    <button type=submit>حذف کاربر</button>

</form>

در این مثال هنگام ارسال فرم، یک پیام تأیید نمایش داده می‌شود. اگر کاربر گزینه تأیید را انتخاب کند، فرم ارسال خواهد شد؛ در غیر این صورت عملیات متوقف می‌شود.

توجه داشته باشید که این تأییدیه فقط برای تجربه کاربری است و جایگزین کنترل‌های امنیتی سمت سرور نمی‌شود.

16. جلوگیری از SQL Injection در دستور DELETE

یکی از مهم‌ترین نکات امنیتی هنگام کار با دیتابیس، جلوگیری از حملات SQL Injection است.

این آسیب‌پذیری زمانی رخ می‌دهد که ورودی کاربر بدون محافظت مناسب مستقیماً وارد متن کوئری SQL شود.

نمونه کد ناامن:

<?php

$id = $_GET['id'];

$sql = "DELETE FROM users WHERE id = $id";

$pdo->query($sql);

?>

در این مثال مقدار دریافتی از کاربر مستقیماً داخل کوئری قرار گرفته است. این روش می‌تواند ساختار SQL را در معرض دست‌کاری قرار دهد.

روش صحیح استفاده از Prepared Statements است:

<?php

$id = filter_input(INPUT_POST, 'id', FILTER_VALIDATE_INT);

if (!$id || $id < 1) {

    exit('شناسه نامعتبر است.');

}

$sql = "DELETE FROM users WHERE id = :id";

$stmt = $pdo->prepare($sql);

$stmt->execute([
    ':id' => $id
]);

?>

در این روش مقدار ورودی به‌عنوان پارامتر ارسال می‌شود و بخشی از ساختار SQL محسوب نمی‌شود.

نکته مهم این است که Prepared Statements برای مقادیر داده‌ای استفاده می‌شوند. اگر نام جدول یا ستون از ورودی کاربر دریافت می‌شود، باید آن را با فهرستی از مقادیر مجاز در سمت سرور کنترل کنیم.

17. تفاوت DELETE و TRUNCATE در MySQL

دستورهای DELETE و TRUNCATE هر دو برای حذف اطلاعات جدول استفاده می‌شوند، اما عملکرد آن‌ها متفاوت است.

دستور DELETE

DELETE برای حذف یک یا چند رکورد از جدول استفاده می‌شود و امکان تعیین شرط WHERE را دارد.

DELETE FROM users
WHERE id = 5;

در این مثال فقط رکورد دارای شناسه 5 حذف می‌شود.

دستور TRUNCATE

TRUNCATE برای خالی کردن تمام رکوردهای یک جدول استفاده می‌شود.

TRUNCATE TABLE users;

این دستور تمام اطلاعات جدول را حذف می‌کند و امکان استفاده از WHERE را ندارد.

ویژگیDELETETRUNCATE
حذف رکوردهای انتخابیبلهخیر
پشتیبانی از WHEREبلهخیر
حذف تمام رکوردهابلهبله
نوع عملیاتحذف رکوردهاخالی کردن جدول
تأثیر بر مقدار AUTO_INCREMENTمعمولاً مقدار فعلی حفظ می‌شوددر MySQL مقدار شمارنده بازنشانی می‌شود
امکان Rollback در InnoDBدر تراکنش قابل بازگشت استخیر، عملیات DDL با COMMIT ضمنی همراه است

برای حذف رکوردهای مشخص در برنامه‌های PHP معمولاً از DELETE استفاده می‌کنیم. دستور TRUNCATE بیشتر برای خالی کردن کامل جدول در شرایط کنترل‌شده کاربرد دارد.

18. تفاوت DELETE و DROP در MySQL

دستورهای DELETE و DROP نیز کاربردهای متفاوتی دارند.

DELETE برای حذف اطلاعات داخل جدول استفاده می‌شود و ساختار جدول را حفظ می‌کند.

DELETE FROM users
WHERE id = 2;

اما DROP TABLE برای حذف کامل جدول از دیتابیس استفاده می‌شود. با اجرای این دستور، هم ساختار جدول و هم اطلاعات آن حذف خواهند شد.

DROP TABLE users;

بنابراین اگر فقط قصد حذف اطلاعات کاربران را داریم، نباید از DROP استفاده کنیم.

19. استفاده از DELETE همراه با JOIN

در MySQL می‌توانیم از DELETE همراه با JOIN استفاده کنیم تا رکوردهای یک یا چند جدول را بر اساس ارتباط آن‌ها با جدول‌های دیگر حذف کنیم.

فرض کنید دو جدول posts و users داریم. در جدول posts اطلاعات مقاله‌ها ذخیره شده و هر مقاله به یک کاربر متصل است.

اگر بخواهیم تمام مقاله‌های کاربری با شناسه 5 را حذف کنیم، می‌توانیم از دستور زیر استفاده کنیم:

DELETE p
FROM posts AS p
JOIN users AS u
    ON p.user_id = u.id
WHERE u.id = 5;

در این مثال با استفاده از JOIN ارتباط بین دو جدول برقرار می‌شود و سپس فقط رکوردهای جدول posts که متعلق به کاربر موردنظر هستند حذف خواهند شد.

همچنین MySQL امکان حذف هم‌زمان رکوردها از چند جدول در دستورهای چندجدولی DELETE را فراهم می‌کند. برای مثال:

DELETE p, c
FROM posts AS p
JOIN comments AS c
    ON c.post_id = p.id
WHERE p.id = 10;

این دستور رکوردهای مرتبط از جدول‌های posts و comments را که با شرط مشخص‌شده مطابقت دارند حذف می‌کند.

در استفاده از DELETE همراه با JOIN باید دقت کنیم که نام جدول یا نام مستعار مشخص‌شده پس از DELETE تعیین می‌کند کدام جدول‌ها هدف حذف هستند.

20. حذف اطلاعات مرتبط با استفاده از Foreign Key

در طراحی دیتابیس ممکن است یک جدول به جدول دیگری وابسته باشد. برای مثال، جدول orders می‌تواند شامل سفارش‌های کاربران باشد و ستون user_id آن به شناسه کاربران در جدول users اشاره کند.

در چنین شرایطی حذف یک کاربر ممکن است با خطای محدودیت کلید خارجی روبه‌رو شود؛ زیرا هنوز سفارش‌هایی وجود دارند که به آن کاربر وابسته هستند.

برای مدیریت این ارتباط می‌توانیم از ویژگی ON DELETE در Foreign Key استفاده کنیم.

استفاده از ON DELETE CASCADE

اگر بخواهیم با حذف یک کاربر، تمام سفارش‌های مرتبط با او نیز به‌صورت خودکار حذف شوند، می‌توانیم کلید خارجی را با ON DELETE CASCADE تعریف کنیم:

CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    total_price DECIMAL(10, 2) NOT NULL,

    CONSTRAINT fk_orders_users
    FOREIGN KEY (user_id)
    REFERENCES users(id)
    ON DELETE CASCADE
) ENGINE=InnoDB;

اکنون اگر کاربری را حذف کنیم:

DELETE FROM users
WHERE id = 5;

تمام سفارش‌هایی که user_id آن‌ها برابر با شناسه کاربر حذف‌شده باشد نیز به‌صورت خودکار حذف می‌شوند.

استفاده از ON DELETE SET NULL

گاهی نمی‌خواهیم اطلاعات جدول وابسته حذف شوند. در چنین شرایطی می‌توانیم از ON DELETE SET NULL استفاده کنیم.

CREATE TABLE posts (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NULL,
    title VARCHAR(200) NOT NULL,

    CONSTRAINT fk_posts_users
    FOREIGN KEY (user_id)
    REFERENCES users(id)
    ON DELETE SET NULL
) ENGINE=InnoDB;

در این مثال اگر یک کاربر حذف شود، مقاله‌های مرتبط با او باقی می‌مانند، اما مقدار user_id آن‌ها NULL خواهد شد.

برای استفاده از ON DELETE SET NULL، ستون کلید خارجی باید اجازه پذیرش NULL را داشته باشد.

انتخاب بین CASCADE، SET NULL و رفتار پیش‌فرض محدودکننده باید بر اساس منطق کسب‌وکار و اهمیت حفظ اطلاعات انجام شود. برای مثال، حذف خودکار سفارش‌های واقعی کاربران در بسیاری از فروشگاه‌ها تصمیم مناسبی نیست.

21. استفاده از تراکنش‌ها برای حذف اطلاعات حساس

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

برای مدیریت چنین عملیات‌هایی می‌توانیم از Transaction استفاده کنیم.

مثال زیر نحوه حذف یک محصول و اطلاعات وابسته آن را با استفاده از PDO نشان می‌دهد:

<?php

$productId = 10;

try {

    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        "DELETE FROM product_images
         WHERE product_id = :id"
    );

    $stmt->execute([
        ':id' => $productId
    ]);

    $stmt = $pdo->prepare(
        "DELETE FROM products
         WHERE id = :id"
    );

    $stmt->execute([
        ':id' => $productId
    ]);

    if ($stmt->rowCount() !== 1) {
        throw new Exception('محصول موردنظر پیدا نشد.');
    }

    $pdo->commit();

    echo 'محصول با موفقیت حذف شد.';

} catch (Throwable $e) {

    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    echo 'عملیات حذف انجام نشد.';

}

?>

در این مثال:

  • با beginTransaction تراکنش را آغاز می‌کنیم.
  • ابتدا تصاویر مرتبط با محصول حذف می‌شوند.
  • سپس خود محصول حذف می‌شود.
  • اگر تمام عملیات موفق باشند، commit تغییرات را نهایی می‌کند.
  • اگر خطایی رخ دهد، rollBack تغییرات انجام‌شده در تراکنش را برمی‌گرداند.

برای استفاده از تراکنش‌ها باید جدول‌های موردنظر از موتور ذخیره‌سازی تراکنش‌پذیری مانند InnoDB استفاده کنند.

22. حذف نرم یا Soft Delete چیست؟

در بسیاری از سیستم‌های حرفه‌ای، اطلاعات را مستقیماً از دیتابیس حذف نمی‌کنیم. به‌جای آن، وضعیت رکورد را تغییر می‌دهیم تا مشخص شود اطلاعات دیگر فعال نیستند.

به این روش Soft Delete یا حذف نرم گفته می‌شود.

برای مثال، فرض کنید جدول users دارای ستونی به نام deleted_at باشد:

ALTER TABLE users
ADD deleted_at DATETIME NULL DEFAULT NULL;

اکنون به‌جای حذف مستقیم کاربر می‌توانیم مقدار deleted_at را با زمان فعلی تغییر دهیم:

UPDATE users
SET deleted_at = NOW()
WHERE id = 5;

در این روش اطلاعات کاربر همچنان در دیتابیس باقی می‌ماند، اما با استفاده از ستون deleted_at می‌توانیم تشخیص دهیم که رکورد حذف نرم شده است.

برای نمایش کاربران فعال، کافی است شرط زیر را به کوئری SELECT اضافه کنیم:

SELECT *
FROM users
WHERE deleted_at IS NULL;

برای نمایش کاربران حذف‌شده نیز می‌توانیم بنویسیم:

SELECT *
FROM users
WHERE deleted_at IS NOT NULL;

بازیابی اطلاعات حذف نرم‌شده

یکی از مزیت‌های Soft Delete این است که می‌توانیم اطلاعات حذف‌شده را دوباره بازیابی کنیم.

UPDATE users
SET deleted_at = NULL
WHERE id = 5;

با اجرای این دستور وضعیت کاربر به حالت فعال برمی‌گردد.

حذف نرم در سیستم‌های مدیریت محتوا، فروشگاه‌های اینترنتی، پنل‌های مدیریت و نرم‌افزارهای سازمانی کاربرد زیادی دارد؛ زیرا امکان بازیابی اطلاعات و حفظ سوابق را فراهم می‌کند.

23. تفاوت حذف نرم و حذف دائمی اطلاعات

ویژگیحذف نرم (Soft Delete)حذف دائمی (Hard Delete)
حذف واقعی رکورد از دیتابیسخیربله
امکان بازیابی آسانبلهخیر
حفظ سوابقبلهخیر، مگر اینکه نسخه پشتیبان یا سابقه جداگانه وجود داشته باشد
روش پیاده‌سازیمعمولاً UPDATEDELETE
کاربرد رایجکاربران، مقالات و محصولات قابل بازیابیاطلاعاتی که باید واقعاً حذف شوند

انتخاب روش مناسب به نیاز پروژه بستگی دارد. اگر احتمال بازیابی اطلاعات وجود دارد، Soft Delete گزینه مناسبی است. اما اگر حذف دائمی از نظر فنی و قانونی ضروری باشد، باید از روش مناسب حذف دائمی استفاده کنیم.

24. نکات امنیتی مهم هنگام حذف اطلاعات

حذف اطلاعات یکی از عملیات حساس در برنامه‌های تحت وب است. برای جلوگیری از مشکلات امنیتی و حذف ناخواسته داده‌ها باید چند نکته مهم را رعایت کنیم.

1. همیشه از شرط WHERE مناسب استفاده کنید

قبل از اجرای DELETE مطمئن شوید شرط WHERE دقیقاً رکوردهای موردنظر را انتخاب می‌کند. حذف اشتباه شرط WHERE می‌تواند باعث پاک شدن تمام اطلاعات جدول شود.

2. از Prepared Statements استفاده کنید

برای دریافت مقادیر از کاربر و ارسال آن‌ها به دیتابیس، از Prepared Statements در PDO یا MySQLi استفاده کنید.

3. مجوز حذف اطلاعات را بررسی کنید

هر کاربر نباید اجازه حذف تمام اطلاعات سیستم را داشته باشد. قبل از اجرای DELETE باید نقش و سطح دسترسی کاربر بررسی شود.

4. از متد POST برای عملیات حذف استفاده کنید

حذف اطلاعات نباید صرفاً با باز کردن یک لینک GET انجام شود. بهتر است درخواست حذف از طریق فرم POST ارسال شود.

5. از CSRF Token استفاده کنید

برای جلوگیری از حملات جعل درخواست بین‌سایتی (CSRF)، فرم‌های حذف باید دارای توکن امنیتی باشند و این توکن در سمت سرور بررسی شود.

6. پیش از حذف، تأییدیه دریافت کنید

در رابط کاربری بهتر است پیش از حذف اطلاعات مهم، از کاربر تأییدیه دریافت کنیم. این کار احتمال حذف تصادفی را کاهش می‌دهد.

7. از اطلاعات مهم نسخه پشتیبان تهیه کنید

در سیستم‌های واقعی بهتر است از دیتابیس به‌صورت منظم نسخه پشتیبان تهیه شود تا در صورت بروز خطا یا حذف ناخواسته، امکان بازیابی اطلاعات وجود داشته باشد.

8. خطاهای دیتابیس را به کاربر نمایش ندهید

جزئیات خطاهای PDO و MySQLi ممکن است شامل اطلاعات داخلی دیتابیس باشد. بهتر است جزئیات خطا در لاگ سرور ثبت شود و پیام عمومی و مناسبی به کاربر نمایش داده شود.

9. محدودیت‌های کلید خارجی را در نظر بگیرید

قبل از حذف رکوردهایی که با جدول‌های دیگر ارتباط دارند، باید رفتار Foreign Key و قوانین ON DELETE بررسی شوند.

10. عملیات حذف حساس را ثبت کنید

در سیستم‌های مدیریتی بهتر است مشخص باشد چه کسی، در چه زمانی و کدام اطلاعات را حذف کرده است. برای این کار می‌توانیم یک جدول گزارش فعالیت یا Audit Log طراحی کنیم.

25. مثال کاربردی: حذف محصول از فروشگاه اینترنتی

فرض کنید یک فروشگاه اینترنتی داریم و مدیر سایت باید بتواند محصولات را از طریق پنل مدیریت حذف کند.

ابتدا یک فرم ساده برای دریافت شناسه محصول ایجاد می‌کنیم:

<form action="delete-product.php" method="post">

    <label>شناسه محصول:</label>

    <input
        type=number
        name=id
        min="1"
        required
    >

    <button type=submit>حذف محصول</button>

</form>

اکنون فایل delete-product.php را ایجاد می‌کنیم:

<?php

require_once 'database.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {

    http_response_code(405);
    exit('درخواست نامعتبر است.');

}

$productId = filter_input(
    INPUT_POST,
    'id',
    FILTER_VALIDATE_INT
);

if (!$productId || $productId < 1) {

    exit('شناسه محصول معتبر نیست.');

}

$sql = "DELETE FROM products
        WHERE id = :id";

$stmt = $pdo->prepare($sql);

try {

    $stmt->execute([
        ':id' => $productId
    ]);

    if ($stmt->rowCount() > 0) {

        echo 'محصول با موفقیت حذف شد.';

    } else {

        echo 'محصول موردنظر پیدا نشد.';

    }

} catch (PDOException $e) {

    echo 'امکان حذف محصول وجود ندارد.';

}

?>

در این مثال ابتدا درخواست بررسی می‌شود، سپس شناسه محصول اعتبارسنجی شده و در نهایت با استفاده از Prepared Statement دستور DELETE اجرا می‌شود.

در یک فروشگاه واقعی باید پیش از اجرای این عملیات بررسی کنیم که کاربر مدیر یا دارای مجوز حذف محصول باشد. همچنین اگر محصول به سفارش‌های ثبت‌شده متصل است، بهتر است به‌جای حذف دائمی، وضعیت آن را غیرفعال کنیم یا از Soft Delete استفاده کنیم تا سوابق سفارش‌ها حفظ شوند.

26. اشتباهات رایج هنگام استفاده از دستور DELETE

هنگام کار با دستور DELETE ممکن است اشتباهاتی رخ دهد که باعث حذف اطلاعات اشتباه یا ایجاد مشکلات امنیتی شوند.

فراموش کردن WHERE

این اشتباه باعث حذف تمام رکوردهای جدول می‌شود:

DELETE FROM users;

استفاده از GET برای حذف اطلاعات

حذف اطلاعات با لینک‌هایی مانند delete.php?id=5 روش مناسبی نیست؛ زیرا درخواست GET نباید برای تغییر وضعیت دیتابیس استفاده شود. بهتر است از فرم POST به همراه CSRF Token استفاده کنیم.

اعتماد به شناسه ارسالی از فرم

مقدار شناسه ارسالی از مرورگر قابل تغییر است. بنابراین باید آن را در سمت سرور اعتبارسنجی کنیم و مجوز حذف رکورد را نیز بررسی کنیم.

استفاده نکردن از Prepared Statements

قرار دادن مستقیم ورودی کاربر در کوئری SQL می‌تواند باعث آسیب‌پذیری SQL Injection شود.

نادیده گرفتن ارتباط بین جدول‌ها

حذف یک رکورد ممکن است به دلیل وجود رکوردهای وابسته با خطای Foreign Key مواجه شود. بنابراین باید ارتباط جدول‌ها را پیش از حذف بررسی کنیم.

حذف دائمی اطلاعاتی که باید نگهداری شوند

در سیستم‌هایی مانند فروشگاه اینترنتی، حذف دائمی سفارش‌ها یا سوابق مالی ممکن است مشکلات جدی ایجاد کند. بهتر است برای چنین اطلاعاتی از غیرفعال‌سازی یا حذف نرم استفاده کنیم.

27. مقایسه روش‌های PDO و MySQLi برای DELETE

هر دو روش PDO و MySQLi برای اجرای دستور DELETE در PHP مناسب هستند و از Prepared Statements پشتیبانی می‌کنند.

ویژگیPDOMySQLi
پشتیبانی از MySQLبلهبله
Prepared Statementsبلهبله
پشتیبانی از دیتابیس‌های مختلفبلهخیر، مخصوص MySQL
مدیریت خطا با Exceptionبله، با تنظیم ERRMODE_EXCEPTIONبله، با تنظیم مناسب گزارش خطا
روش اتصال پارامترهاپارامترهای نام‌گذاری‌شده یا موقعیتیپارامترهای موقعیتی
تعداد رکوردهای حذف‌شدهrowCount()affected_rows

اگر قصد دارید برنامه‌ای طراحی کنید که در آینده امکان استفاده از دیتابیس‌های مختلف را داشته باشد، PDO انتخاب مناسبی است. اگر پروژه شما فقط با MySQL کار می‌کند، MySQLi نیز گزینه خوبی خواهد بود.

28. تمرین عملی

برای تسلط بیشتر بر دستور DELETE، تمرین‌های زیر را انجام دهید:

  1. جدولی به نام students ایجاد کنید که شامل ستون‌های id، name، email و grade باشد.
  2. حداقل پنج دانشجو در جدول ثبت کنید.
  3. دانشجویی با شناسه مشخص را از جدول حذف کنید.
  4. تمام دانشجویانی را که نمره آن‌ها کمتر از 10 است حذف کنید.
  5. با استفاده از IN چند دانشجوی مشخص را حذف کنید.
  6. با استفاده از LIKE دانشجویانی را که ایمیل آن‌ها با دامنه مشخصی پایان پیدا می‌کند حذف کنید.
  7. یک فرم حذف اطلاعات با متد POST طراحی کنید.
  8. در فایل PHP از PDO و Prepared Statements برای حذف اطلاعات استفاده کنید.
  9. تعداد رکوردهای حذف‌شده را با rowCount بررسی کنید.
  10. یک قابلیت Soft Delete برای دانشجویان پیاده‌سازی کنید.

هدف این تمرین‌ها این است که بتوانید علاوه بر نوشتن کوئری‌های DELETE، عملیات حذف اطلاعات را به‌صورت امن در پروژه‌های PHP پیاده‌سازی کنید.

29. سوالات متداول درباره دستور DELETE در MySQL

1. دستور DELETE در MySQL چه کاربردی دارد؟

از دستور DELETE برای حذف یک یا چند رکورد از جدول دیتابیس استفاده می‌شود. با کمک WHERE می‌توانیم رکوردهای موردنظر را مشخص کنیم.

2. اگر از WHERE در دستور DELETE استفاده نکنیم چه اتفاقی می‌افتد؟

تمام رکوردهای جدول حذف می‌شوند، اما ساختار جدول باقی می‌ماند.

3. چگونه یک رکورد مشخص را از دیتابیس حذف کنیم؟

کافی است از DELETE همراه با شرطی مانند شناسه اصلی رکورد استفاده کنیم.

DELETE FROM users
WHERE id = 10;

4. چگونه چند رکورد را به‌صورت هم‌زمان حذف کنیم؟

می‌توانیم از شرط‌های مختلف مانند IN، BETWEEN، AND و OR در بخش WHERE استفاده کنیم.

5. چگونه دستور DELETE را در PHP اجرا کنیم؟

می‌توانیم از PDO یا MySQLi استفاده کنیم. روش پیشنهادی استفاده از Prepared Statements برای ارسال امن مقادیر به کوئری است.

6. تفاوت DELETE و TRUNCATE چیست؟

DELETE امکان حذف رکوردهای انتخابی را فراهم می‌کند، اما TRUNCATE تمام رکوردهای جدول را حذف می‌کند و امکان استفاده از WHERE ندارد.

7. تفاوت DELETE و DROP چیست؟

DELETE اطلاعات داخل جدول را حذف می‌کند، اما DROP TABLE کل جدول و ساختار آن را از دیتابیس حذف می‌کند.

8. متد rowCount در PDO چه کاربردی دارد؟

این متد تعداد رکوردهایی را که توسط دستور DELETE حذف شده‌اند گزارش می‌کند.

9. آیا امکان بازیابی اطلاعات حذف‌شده وجود دارد؟

اگر عملیات DELETE در یک تراکنش فعال انجام شده باشد، پیش از COMMIT می‌توان با ROLLBACK تغییرات را برگرداند. در غیر این صورت، معمولاً برای بازیابی اطلاعات به نسخه پشتیبان یا سازوکارهای ثبت و بازیابی اطلاعات نیاز داریم.

10. Soft Delete چیست؟

Soft Delete روشی است که در آن به‌جای حذف واقعی رکورد، وضعیت آن را به حذف‌شده تغییر می‌دهیم. در نتیجه امکان بازیابی اطلاعات وجود خواهد داشت.

11. آیا می‌توان با DELETE اطلاعات چند جدول را حذف کرد؟

بله. در MySQL می‌توان از DELETE همراه با JOIN برای حذف اطلاعات از یک یا چند جدول مرتبط استفاده کرد.

12. چگونه از SQL Injection هنگام حذف اطلاعات جلوگیری کنیم؟

باید از Prepared Statements در PDO یا MySQLi استفاده کنیم و تمام ورودی‌های کاربر را در سمت سرور اعتبارسنجی کنیم.

جمع‌بندی

در این قسمت از آموزش PHP و MySQL با دستور DELETE آشنا شدیم و یاد گرفتیم چگونه اطلاعات موجود در جدول‌های دیتابیس را حذف کنیم. ابتدا ساختار اصلی DELETE و نحوه استفاده از WHERE را بررسی کردیم و سپس حذف یک رکورد، چند رکورد و استفاده از عملگرهای مختلف مانند AND، OR، IN، BETWEEN و LIKE را همراه با مثال آموزش دادیم.

در ادامه نحوه اجرای DELETE در PHP با استفاده از PDO و MySQLi را یاد گرفتیم و با متدهایی مانند execute، rowCount و affected_rows آشنا شدیم. همچنین ساخت فرم حذف اطلاعات، استفاده از JOIN، مدیریت ارتباط بین جدول‌ها با Foreign Key، استفاده از تراکنش‌ها و پیاده‌سازی Soft Delete را بررسی کردیم.

یکی از مهم‌ترین نکاتی که باید هنگام استفاده از DELETE به خاطر داشته باشیم، دقت در انتخاب شرط WHERE است. حذف اشتباه اطلاعات می‌تواند خسارت زیادی به یک پروژه وارد کند؛ بنابراین استفاده از Prepared Statements، بررسی مجوز کاربران، محافظت در برابر CSRF و تهیه نسخه پشتیبان از دیتابیس اهمیت زیادی دارد.

اکنون با سه عملیات اصلی مدیریت اطلاعات در دیتابیس یعنی INSERT، UPDATE و DELETE آشنا شده‌ایم و می‌توانیم اطلاعات را در پروژه‌های PHP ثبت، ویرایش و حذف کنیم.

در قسمت بعدی آموزش PHP می‌توانیم با موضوعات پیشرفته‌تر کار با MySQL آشنا شویم و نحوه مدیریت اطلاعات مرتبط بین جدول‌ها را با استفاده از دستورات و مفاهیم تکمیلی SQL بررسی کنیم.

پیشنهاد ویژه ما:آموزش رایگان PHP

اشتراک گذاری :
ملیکا اسمعیلی
نویسنده

ملیکا اسمعیلی

من یک توسعه‌دهنده وردپرس و متخصص سئو هستم که به کسب‌وکارها کمک می‌کنم وب‌سایت‌های خود را به پلتفرم‌هایی بهینه برای موتورهای جستجو و با نرخ تبدیل بالا تبدیل کنند. با تجربه عملی در Python، HTML و CSS، مهارت‌های فنی توسعه وب را با درک عمیق از سئوی داخلی (On-Page SEO) و سئوی محتوا ترکیب می‌کنم؛

TEST_VALUE_123
https://t.me/artarasaneh
tel:09193426251
https://wa.me/+989193426251
https://instagram.com/artarasaneh_com