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

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

آموزش PHP قسمت 27 | ویرایش و به‌روزرسانی اطلاعات در MySQL (UPDATE)

Table of contents [Show] [Hide]

مقدمه

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

برای انجام این عملیات در MySQL از دستور UPDATE استفاده می‌کنیم. این دستور به ما اجازه می‌دهد اطلاعات موجود در یک یا چند رکورد از جدول دیتابیس را تغییر دهیم.

در این قسمت از آموزش PHP قصد داریم به‌صورت کامل با دستور UPDATE در MySQL آشنا شویم و یاد بگیریم چگونه با استفاده از PHP و روش‌های PDO و MySQLi اطلاعات دیتابیس را به‌روزرسانی کنیم. همچنین نکات مهم امنیتی، استفاده از Prepared Statements، بررسی تعداد رکوردهای تغییرکرده و پیاده‌سازی یک فرم ویرایش اطلاعات را بررسی خواهیم کرد.

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

دستور UPDATE یکی از دستورات اصلی زبان SQL است که برای تغییر اطلاعات موجود در جدول‌های دیتابیس استفاده می‌شود.

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

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

UPDATE table_name
SET column1 = value1,
    column2 = value2
WHERE condition;

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

  • UPDATE: مشخص می‌کند که قصد به‌روزرسانی اطلاعات را داریم.
  • table_name: نام جدولی است که می‌خواهیم اطلاعات آن را تغییر دهیم.
  • SET: برای مشخص کردن ستون‌ها و مقادیر جدید استفاده می‌شود.
  • WHERE: شرطی را مشخص می‌کند که تعیین می‌کند کدام رکوردها باید تغییر کنند.

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

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

برای درک بهتر مثال‌ها، ابتدا یک جدول به نام 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);

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

SELECT * FROM users;

خروجی فرضی جدول به شکل زیر خواهد بود:

idnameemailage
1Aliali@example.com25
2Sarasara@example.com22
3Rezareza@example.com30

3. به‌روزرسانی یک ستون با UPDATE

یکی از ساده‌ترین کاربردهای UPDATE تغییر مقدار یک ستون در یک رکورد مشخص است.

برای مثال، فرض کنید می‌خواهیم سن کاربری با شناسه 1 را از 25 به 26 تغییر دهیم:

UPDATE users
SET age = 26
WHERE id = 1;

در این مثال فقط رکوردی تغییر می‌کند که مقدار ستون id آن برابر با 1 باشد.

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

SELECT * FROM users
WHERE id = 1;

اکنون سن کاربر موردنظر برابر با 26 خواهد بود.

4. به‌روزرسانی چند ستون به‌صورت هم‌زمان

گاهی لازم است چند مقدار از یک رکورد را به‌صورت هم‌زمان تغییر دهیم. برای این کار کافی است نام ستون‌ها و مقادیر جدید را با استفاده از SET مشخص کنیم و بین آن‌ها کاما قرار دهیم.

برای مثال، می‌خواهیم نام، ایمیل و سن کاربری با شناسه 2 را تغییر دهیم:

UPDATE users
SET
    name = 'Sara Ahmadi',
    email = 'sara.ahmadi@example.com',
    age = 23
WHERE id = 2;

با اجرای این دستور، تمام ستون‌های مشخص‌شده در رکورد موردنظر به‌روزرسانی می‌شوند.

استفاده از این روش باعث می‌شود به‌جای اجرای چند دستور UPDATE، بتوانیم چند ستون را در یک عملیات تغییر دهیم.

5. به‌روزرسانی چند رکورد با استفاده از WHERE

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

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

UPDATE users
SET age = age + 1
WHERE age < 25;

در این دستور مقدار فعلی ستون age خوانده می‌شود و یک واحد به آن اضافه خواهد شد.

همچنین می‌توانیم مقدار یک ستون را برای تمام رکوردهایی که شرایط مشخصی دارند، به یک مقدار ثابت تغییر دهیم:

UPDATE users
SET age = 20
WHERE age < 20;

در این مثال سن تمام کاربرانی که کمتر از 20 سال دارند، برابر با 20 قرار می‌گیرد.

6. استفاده از عملگرهای شرطی در UPDATE

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

استفاده از AND

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

UPDATE users
SET age = 28
WHERE name = 'Ali' AND id = 1;

در این مثال فقط رکوردی تغییر می‌کند که نام آن Ali و شناسه آن 1 باشد.

استفاده از OR

با استفاده از OR کافی است یکی از شرط‌ها برقرار باشد:

UPDATE users
SET age = 24
WHERE name = 'Ali' OR name = 'Sara';

این دستور سن تمام کاربرانی را که نام آن‌ها Ali یا Sara است، برابر با 24 قرار می‌دهد.

استفاده از IN

عملگر IN زمانی کاربرد دارد که بخواهیم چند مقدار مشخص را بررسی کنیم:

UPDATE users
SET age = 27
WHERE id IN (1, 3);

در این مثال اطلاعات کاربران دارای شناسه 1 و 3 به‌روزرسانی می‌شود.

استفاده از BETWEEN

با BETWEEN می‌توانیم رکوردهایی را انتخاب کنیم که مقدار یک ستون آن‌ها در یک محدوده قرار دارد:

UPDATE users
SET age = 25
WHERE age BETWEEN 20 AND 30;

این دستور سن کاربرانی را که سن آن‌ها بین 20 تا 30 است، برابر با 25 قرار می‌دهد. محدوده BETWEEN شامل هر دو مقدار ابتدا و انتها نیز می‌شود.

7. به‌روزرسانی مقادیر با استفاده از عبارت‌های محاسباتی

در دستور UPDATE می‌توانیم به‌جای قرار دادن یک مقدار ثابت، از عملیات ریاضی نیز استفاده کنیم.

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

UPDATE products
SET price = price * 1.10;

یا اگر بخواهیم از قیمت محصولات یک مبلغ مشخص کم کنیم:

UPDATE products
SET price = price - 5000
WHERE category_id = 2;

در مثال بالا قیمت محصولات دسته‌بندی شماره 2 به‌اندازه 5000 واحد کاهش پیدا می‌کند.

دقت کنید که اگر در چنین دستورهایی WHERE را حذف کنیم، تغییر روی تمام رکوردهای جدول اعمال خواهد شد.

8. استفاده از UPDATE همراه با ORDER BY و LIMIT

در MySQL می‌توانیم در برخی دستورهای UPDATE از ORDER BY و LIMIT نیز استفاده کنیم.

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

برای مثال:

UPDATE users
SET age = age + 1
ORDER BY id ASC
LIMIT 2;

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

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

9. اجرای دستور UPDATE در PHP با استفاده از PDO

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

یکی از روش‌های مناسب برای ارتباط PHP با MySQL استفاده از PDO است. 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

فرض کنید می‌خواهیم نام و ایمیل کاربری با شناسه مشخص را تغییر دهیم:

<?php

$id = 1;
$name = 'Ali Rezaei';
$email = 'ali.rezaei@example.com';

$sql = "UPDATE users
        SET name = :name, email = :email
        WHERE id = :id";

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

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

echo 'اطلاعات کاربر با موفقیت بررسی و به‌روزرسانی شد.';

?>

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

این روش علاوه بر خوانایی بهتر کد، از تزریق SQL جلوگیری می‌کند؛ البته به شرطی که تمام مقادیر ورودی به‌درستی به‌عنوان پارامتر ارسال شوند.

10. بررسی تعداد رکوردهای تغییرکرده با PDO

یکی از متدهای کاربردی PDO، متد rowCount است. این متد برای دستور UPDATE تعداد ردیف‌های تغییرکرده را گزارش می‌کند.

مثال:

<?php

$sql = "UPDATE users
        SET age = :age
        WHERE id = :id";

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

$stmt->execute([
    ':age' => 29,
    ':id' => 1
]);

$affectedRows = $stmt->rowCount();

if ($affectedRows > 0) {
    echo 'اطلاعات با موفقیت تغییر کرد.';
} else {
    echo 'رکوردی تغییر نکرد.';
}

?>

نکته مهم این است که مقدار rowCount لزوماً تعداد رکوردهای منطبق با شرط WHERE نیست؛ در MySQL معمولاً تعداد ردیف‌هایی را نشان می‌دهد که واقعاً تغییر کرده‌اند. اگر مقدار جدید با مقدار قبلی یکسان باشد، ممکن است خروجی صفر باشد، حتی اگر رکورد موردنظر وجود داشته باشد.

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

11. اجرای UPDATE در PHP با استفاده از MySQLi

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

در MySQLi نیز بهتر است برای دریافت مقادیر ورودی از Prepared Statements استفاده کنیم.

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

<?php

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

if ($conn->connect_error) {
    die('خطا در اتصال به دیتابیس');
}

$conn->set_charset('utf8mb4');

?>

به‌روزرسانی اطلاعات با MySQLi

برای تغییر اطلاعات کاربر می‌توانیم به شکل زیر عمل کنیم:

<?php

$id = 1;
$name = 'Reza Mohammadi';
$email = 'reza.m@example.com';

$sql = "UPDATE users
        SET name = ?, email = ?
        WHERE id = ?";

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

$stmt->bind_param(
    'ssi',
    $name,
    $email,
    $id
);

if ($stmt->execute()) {

    if ($stmt->affected_rows > 0) {
        echo 'اطلاعات با موفقیت به‌روزرسانی شد.';
    } else {
        echo 'رکوردی تغییر نکرد.';
    }

} else {
    echo 'خطا در به‌روزرسانی اطلاعات.';
}

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

?>

در این مثال:

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

12. ساخت فرم ویرایش اطلاعات با PHP و MySQL

یکی از کاربردهای مهم UPDATE ساخت فرم ویرایش اطلاعات است. در بسیاری از وب‌سایت‌ها کاربران می‌توانند اطلاعات حساب کاربری خود را از طریق یک فرم تغییر دهند.

برای پیاده‌سازی چنین قابلیتی معمولاً دو مرحله داریم:

  1. دریافت اطلاعات فعلی کاربر از دیتابیس و نمایش آن‌ها در فرم.
  2. دریافت اطلاعات جدید از فرم و ذخیره تغییرات در دیتابیس با UPDATE.

مرحله اول: دریافت اطلاعات کاربر

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

<?php

$id = 1;

$sql = "SELECT id, name, email
        FROM users
        WHERE id = :id";

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

$user = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$user) {
    die('کاربر موردنظر پیدا نشد.');
}

?>

مرحله دوم: نمایش فرم ویرایش

پس از دریافت اطلاعات، آن‌ها را داخل فیلدهای فرم قرار می‌دهیم:

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

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

    <label>نام کاربر:</label>
    <input
        type=text
        name=name
        value="<?= htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8') ?>"
        required
    >

    <label>ایمیل:</label>
    <input
        type=email
        name=email
        value="<?= htmlspecialchars($user['email'], ENT_QUOTES, 'UTF-8') ?>"
        required
    >

    <button type=submit>ذخیره تغییرات</button>

</form>

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

توجه داشته باشید که مقدار id ارسال‌شده از فرم قابل اعتماد نیست و باید در سمت سرور اعتبارسنجی و مجوز ویرایش آن بررسی شود.

مرحله سوم: دریافت اطلاعات فرم و اجرای UPDATE

اکنون فایل update-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);

$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');

if (!$id || $id < 1) {
    exit('شناسه کاربر معتبر نیست.');
}

if ($name === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
    exit('اطلاعات واردشده معتبر نیست.');
}

$sql = "UPDATE users
        SET name = :name, email = :email
        WHERE id = :id";

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

try {

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

    if ($stmt->rowCount() > 0) {
        echo 'اطلاعات با موفقیت به‌روزرسانی شد.';
    } else {
        echo 'اطلاعات تغییر نکرده است یا مقدارهای جدید با مقادیر قبلی یکسان هستند.';
    }

} catch (PDOException $e) {

    if ($e->getCode() === '23000') {
        echo 'این ایمیل قبلاً توسط کاربر دیگری ثبت شده است.';
    } else {
        echo 'خطایی هنگام به‌روزرسانی اطلاعات رخ داد.';
    }

}

?>

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

از آنجا که ستون email در جدول ما دارای محدودیت UNIQUE است، اگر ایمیل تکراری ارسال شود، دیتابیس خطای مربوط به نقض محدودیت را برمی‌گرداند.

نکته امنیتی مهم: این مثال برای آموزش است. در یک سامانه واقعی، شناسه کاربر باید از نشست کاربر واردشده یا مجوز مدیریتی معتبر تعیین شود، نه اینکه صرفاً به شناسه ارسالی از فرم اعتماد کنیم. همچنین باید از توکن CSRF برای محافظت از فرم در برابر درخواست‌های جعلی استفاده شود.

13. استفاده از UPDATE برای تغییر رمز عبور کاربران

یکی دیگر از کاربردهای مهم UPDATE تغییر رمز عبور کاربران است. برای ذخیره رمز عبور هرگز نباید متن ساده آن را مستقیماً در دیتابیس قرار دهیم.

در PHP باید ابتدا رمز عبور را با password_hash هش کنیم و سپس مقدار هش‌شده را در دیتابیس ذخیره کنیم.

مثال:

<?php

$userId = 1;
$newPassword = 'NewSecurePassword123';

$passwordHash = password_hash(
    $newPassword,
    PASSWORD_DEFAULT
);

$sql = "UPDATE users
        SET password = :password
        WHERE id = :id";

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

$stmt->execute([
    ':password' => $passwordHash,
    ':id' => $userId
]);

echo 'رمز عبور با موفقیت تغییر کرد.';

?>

در این مثال فرض کرده‌ایم جدول users دارای ستونی به نام password است. بهتر است نوع این ستون VARCHAR(255) باشد تا فضای کافی برای هش‌های تولیدشده توسط الگوریتم‌های پیش‌فرض PHP وجود داشته باشد.

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

14. به‌روزرسانی اطلاعات همراه با شرط‌های امنیتی

در برنامه‌های واقعی بهتر است UPDATE را با شرط‌هایی اجرا کنیم که علاوه بر شناسه رکورد، مالکیت یا وضعیت مجاز آن را نیز بررسی کنند.

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

<?php

session_start();

$currentUserId = $_SESSION['user_id'] ?? null;

if (!$currentUserId) {
    exit('ابتدا وارد حساب کاربری خود شوید.');
}

$name = trim($_POST['name'] ?? '');

if ($name === '') {
    exit('نام کاربر الزامی است.');
}

$sql = "UPDATE users
        SET name = :name
        WHERE id = :id";

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

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

echo 'درخواست ویرایش انجام شد.';

?>

در این روش شناسه کاربر از نشست دریافت می‌شود و کاربر نمی‌تواند صرفاً با تغییر یک فیلد مخفی در فرم، شناسه کاربر دیگری را برای ویرایش ارسال کند.

البته در پروژه‌های واقعی باید علاوه بر احراز هویت، اعتبار نشست، مجوز دسترسی و توکن CSRF نیز بررسی شوند.

15. استفاده از UPDATE همراه با JOIN

در MySQL می‌توانیم از UPDATE همراه با JOIN برای به‌روزرسانی اطلاعات یک جدول بر اساس اطلاعات جدول دیگر استفاده کنیم.

فرض کنید دو جدول به نام‌های products و categories داریم. هر محصول با استفاده از category_id به یک دسته‌بندی متصل شده است.

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

UPDATE products AS p
JOIN categories AS c
    ON p.category_id = c.id
SET p.price = p.price * 1.10
WHERE c.name = 'Digital Products';

در این مثال ابتدا ارتباط بین دو جدول با JOIN برقرار می‌شود. سپس قیمت محصولات مرتبط با دسته‌بندی موردنظر تغییر می‌کند.

استفاده از UPDATE JOIN در پروژه‌های فروشگاهی، سیستم‌های مدیریت محتوا و نرم‌افزارهای سازمانی کاربرد زیادی دارد.

16. استفاده از UPDATE همراه با CASE

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

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

UPDATE users
SET level = CASE
    WHEN score >= 90 THEN 'Gold'
    WHEN score >= 70 THEN 'Silver'
    WHEN score >= 50 THEN 'Bronze'
    ELSE 'Normal'
END;

در این مثال مقدار ستون level بر اساس مقدار score تعیین می‌شود.

اگر بخواهیم فقط گروه مشخصی از کاربران را به‌روزرسانی کنیم، می‌توانیم یک شرط WHERE نیز به کوئری اضافه کنیم.

17. تفاوت UPDATE و REPLACE در MySQL

دو دستور UPDATE و REPLACE ممکن است در نگاه اول مشابه به نظر برسند، اما عملکرد آن‌ها یکسان نیست.

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

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

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

18. تفاوت UPDATE با INSERT

هر دو دستور UPDATE و INSERT برای کار با اطلاعات دیتابیس استفاده می‌شوند، اما کاربرد متفاوتی دارند.

  • INSERT: برای اضافه کردن رکورد جدید به جدول استفاده می‌شود.
  • UPDATE: برای تغییر اطلاعات رکوردهای موجود استفاده می‌شود.

برای مثال، اگر بخواهیم یک کاربر جدید ایجاد کنیم از INSERT استفاده می‌کنیم:

INSERT INTO users (name, email, age)
VALUES ('Mina', 'mina@example.com', 24);

اما اگر بخواهیم اطلاعات کاربر موجود را تغییر دهیم، از UPDATE استفاده می‌کنیم:

UPDATE users
SET name = 'Mina Ahmadi'
WHERE id = 4;

19. استفاده از تراکنش‌ها برای عملیات حساس UPDATE

در برخی پروژه‌ها ممکن است یک عملیات به‌روزرسانی شامل چند دستور SQL باشد. برای مثال، هنگام انتقال موجودی بین دو حساب بانکی باید موجودی حساب اول کاهش پیدا کند و موجودی حساب دوم افزایش یابد.

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

مثال ساده انتقال موجودی با PDO:

<?php

try {

    $pdo->beginTransaction();

    $stmt = $pdo->prepare(
        "UPDATE accounts
         SET balance = balance - :amount
         WHERE id = :source
         AND balance >= :amount"
    );

    $stmt->execute([
        ':amount' => 100,
        ':source' => 1
    ]);

    if ($stmt->rowCount() !== 1) {
        throw new Exception('موجودی کافی نیست یا حساب مبدأ معتبر نیست.');
    }

    $stmt = $pdo->prepare(
        "UPDATE accounts
         SET balance = balance + :amount
         WHERE id = :destination"
    );

    $stmt->execute([
        ':amount' => 100,
        ':destination' => 2
    ]);

    if ($stmt->rowCount() !== 1) {
        throw new Exception('حساب مقصد معتبر نیست.');
    }

    $pdo->commit();

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

} catch (Throwable $e) {

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

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

}

?>

در این مثال:

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

این مثال آموزشی است و برای یک سیستم مالی واقعی باید از کنترل هم‌زمانی، قفل‌گذاری مناسب رکوردها، کنترل مجوزها و قواعد دقیق مالی نیز استفاده شود. همچنین جدول‌ها باید از موتور ذخیره‌سازی تراکنش‌پذیر مانند InnoDB استفاده کنند.

20. جلوگیری از SQL Injection در دستور UPDATE

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

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

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

<?php

$id = $_POST['id'];

$sql = "UPDATE users
        SET name = 'Ali'
        WHERE id = $id";

$pdo->query($sql);

?>

در این مثال مقدار id مستقیماً داخل کوئری قرار گرفته است. اگر ورودی کاربر به‌درستی کنترل نشود، ممکن است ساختار کوئری تغییر کند.

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

<?php

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

if (!$id || $id < 1) {
    exit('شناسه نامعتبر است.');
}

$sql = "UPDATE users
        SET name = :name
        WHERE id = :id";

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

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

?>

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

نکته مهم: Prepared Statements برای مقادیر مناسب هستند، اما نمی‌توان نام جدول، نام ستون یا عبارت‌های SQL را به‌عنوان پارامتر معمولی به آن‌ها متصل کرد. اگر لازم است نام ستون یا ترتیب مرتب‌سازی از ورودی کاربر انتخاب شود، باید آن را با یک فهرست مجاز از مقادیر ثابت در برنامه کنترل کنیم.

21. نکات مهم و اشتباهات رایج هنگام استفاده از UPDATE

هنگام استفاده از دستور UPDATE باید به چند نکته مهم توجه داشته باشیم:

فراموش کردن WHERE

یکی از خطرناک‌ترین اشتباهات، حذف شرط WHERE است. برای مثال:

UPDATE users
SET age = 30;

این دستور سن تمام کاربران را برابر با 30 قرار می‌دهد. بنابراین قبل از اجرای UPDATE همیشه باید شرایط تغییر رکوردها را بررسی کنیم.

استفاده از شرط نادرست

حتی اگر WHERE وجود داشته باشد، انتخاب شرط اشتباه می‌تواند باعث تغییر رکوردهای زیادی شود. بهتر است پیش از اجرای دستور، همان شرط را با SELECT آزمایش کنیم:

SELECT *
FROM users
WHERE age < 25;

پس از اطمینان از رکوردهای انتخاب‌شده می‌توانیم دستور UPDATE را اجرا کنیم.

نادیده گرفتن محدودیت‌های دیتابیس

اگر مقدار جدید با محدودیت‌هایی مانند NOT NULL، UNIQUE یا FOREIGN KEY سازگار نباشد، MySQL ممکن است اجرای دستور را با خطا متوقف کند.

اعتماد به ورودی کاربر

مقادیر دریافتی از فرم‌ها، URL و درخواست‌های HTTP باید در سمت سرور اعتبارسنجی شوند. استفاده از Prepared Statements نیز برای جلوگیری از SQL Injection ضروری است.

بررسی نکردن مجوز ویرایش

هر کاربر نباید بتواند اطلاعات کاربران دیگر را تغییر دهد. قبل از اجرای UPDATE باید مشخص شود کاربر واردشده اجازه ویرایش رکورد موردنظر را دارد یا خیر.

نادیده گرفتن عملیات هم‌زمان

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

22. مثال کاربردی: به‌روزرسانی قیمت محصولات فروشگاه

فرض کنید یک فروشگاه اینترنتی داریم و مدیر سایت می‌خواهد قیمت محصولی با شناسه مشخص را تغییر دهد.

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

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

    <label>شناسه محصول:</label>
    <input type=number name=id min="1" required>

    <label>قیمت جدید:</label>
    <input type=number name=price min="0" step="0.01" required>

    <button type=submit>به‌روزرسانی قیمت</button>

</form>

اکنون در فایل update-product.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);
$price = $_POST['price'] ?? '';

if (!$id || $id < 1) {
    exit('شناسه محصول معتبر نیست.');
}

if (!is_numeric($price) || (float) $price < 0) {
    exit('قیمت واردشده معتبر نیست.');
}

$sql = "UPDATE products
        SET price = :price
        WHERE id = :id";

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

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

if ($stmt->rowCount() > 0) {
    echo 'قیمت محصول با موفقیت تغییر کرد.';
} else {
    echo 'محصول تغییر نکرده است یا قیمت جدید با قیمت قبلی یکسان است.';
}

?>

در یک پروژه واقعی، علاوه بر اعتبارسنجی قیمت، باید دسترسی مدیر فروشگاه بررسی شود و از توکن CSRF برای محافظت از فرم استفاده کنیم. همچنین بهتر است برای قیمت‌های مالی از نوع داده مناسب مانند DECIMAL در MySQL استفاده شود تا دقت محاسبات حفظ شود.

23. مقایسه روش‌های PDO و MySQLi برای UPDATE

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

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

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

24. تمرین عملی

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

  1. جدولی به نام students ایجاد کنید که شامل ستون‌های id، name، email و grade باشد.
  2. حداقل پنج دانشجو در جدول ثبت کنید.
  3. نمره دانشجویی با شناسه 2 را تغییر دهید.
  4. نام و ایمیل دانشجویی با شناسه 3 را به‌صورت هم‌زمان به‌روزرسانی کنید.
  5. نمره تمام دانشجویانی را که کمتر از 10 گرفته‌اند، برابر با 10 قرار دهید.
  6. با استفاده از PDO یک فرم ویرایش اطلاعات دانشجو طراحی کنید.
  7. در فرم ویرایش، اعتبارسنجی اطلاعات و Prepared Statements را پیاده‌سازی کنید.
  8. تعداد رکوردهای تغییرکرده را با rowCount بررسی کنید.

هدف این تمرین‌ها این است که بتوانید علاوه بر نوشتن کوئری‌های UPDATE، آن‌ها را به‌صورت امن در پروژه‌های PHP اجرا کنید.

25. سوالات متداول درباره دستور UPDATE در MySQL

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

از UPDATE برای تغییر اطلاعات موجود در یک یا چند رکورد جدول استفاده می‌شود. با این دستور می‌توانیم یک یا چند ستون را به‌روزرسانی کنیم.

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

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

3. چگونه چند ستون را با یک UPDATE تغییر دهیم؟

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

4. آیا می‌توان با یک UPDATE چند رکورد را تغییر داد؟

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

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

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

6. متد rowCount در PDO چه کاری انجام می‌دهد؟

این متد برای دستور UPDATE تعداد ردیف‌هایی را که واقعاً تغییر کرده‌اند گزارش می‌کند. مقدار صفر لزوماً به معنی نبودن رکورد نیست؛ ممکن است مقدار جدید با مقدار قبلی یکسان باشد.

7. آیا UPDATE می‌تواند اطلاعات چند جدول را تغییر دهد؟

در MySQL می‌توان از UPDATE همراه با JOIN برای تغییر اطلاعات یک جدول بر اساس ارتباط آن با جدول‌های دیگر استفاده کرد.

8. چگونه از SQL Injection در UPDATE جلوگیری کنیم؟

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

9. آیا UPDATE رکورد جدید ایجاد می‌کند؟

خیر. UPDATE فقط رکوردهای موجود را تغییر می‌دهد. برای افزودن رکورد جدید باید از INSERT استفاده کنیم.

10. چگونه از تغییر ناخواسته اطلاعات جلوگیری کنیم؟

قبل از اجرای UPDATE شرط WHERE را بررسی کنید، در عملیات حساس از تراکنش استفاده کنید و در برنامه‌های واقعی مجوز ویرایش کاربران را کنترل کنید.

جمع‌بندی

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

در ادامه نحوه اجرای UPDATE در PHP با استفاده از PDO و MySQLi را بررسی کردیم و با متدهایی مانند execute، rowCount و affected_rows آشنا شدیم. همچنین ساخت فرم ویرایش اطلاعات، تغییر رمز عبور به روش امن، استفاده از JOIN و CASE، اجرای تراکنش‌ها و جلوگیری از SQL Injection را آموزش دادیم.

دستور UPDATE یکی از مهم‌ترین بخش‌های کار با دیتابیس در پروژه‌های PHP است. تقریباً تمام وب‌سایت‌ها و برنامه‌های تحت وب به قابلیت ویرایش اطلاعات نیاز دارند؛ بنابراین تسلط بر این دستور و رعایت نکات امنیتی آن برای طراحی یک برنامه حرفه‌ای ضروری است.

در قسمت بعدی آموزش PHP می‌توانیم به سراغ دستور DELETE در MySQL برویم و نحوه حذف رکوردها از دیتابیس را با استفاده از PHP و روش‌های PDO و MySQLi یاد بگیریم.

پیشنهاد ویژه ما:آموزش رایگان 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