با سلام، در این قسمت از سری آموزشی کار با رابط شیء گرای PDO قصد داریم انواع راه های دریافت داده در PDO را بررسی کنیم.
برخی اوقات می توانید به جای اجرای چند باره ی یک کوئری، از prepared statement ها برای اجرای چند باره ی آن ها استفاده کنید.
بدین صورت سرعت اجرای کار را تا حدی بهبود می بخشید و همچنین کوئری ما یک بار بیشتر تجزیه (parse) نمی شود.
این قابلیت در صورتی که به ما اجازه می داد از آن ها در یک نمونه ی (instance) دیگر از PHP استفاده کنیم، بسیار کاربردی بود اما متاسفانه چنین نیست و شما تنها می توانید یک کوئری واحد را در یک instance واحد تکرار کنید.
البته چنین حالتی بسیار کم پیش می آید و معمولا تنها در هنگام INSERT ها و UPDATE های چند باره دیده می شود. به کد زیر توجه کنید:
$data = [ 1 => 1000, 5 => 300, 9 => 200, ]; $stmt = $pdo->prepare('UPDATE users SET bonus = bonus + ? WHERE id = ?'); foreach ($data as $id => $bonus) { $stmt->execute([$bonus, $id]); }
من وظیفه ی خود می دانستم که این مورد را توضیح دهم اما در زمان ما نیاز چندانی به چنین قابلیتی نیست چرا که موقعیت های استفاده از آن بسیار کم است و از طرفی تجزیه ی (parse) کوئری در عصر ما بسیار سریع است. همچنین باید توجه داشته باشید که تنها زمانی می توانید از این ویژگی استفاده کنید که emulation mode خاموش باشد.
هیچ موضوع خاص و نکته ی پیچیده ای راجع به این دستورات وجود ندارد. ممکن است در سایت های اینترنتی دیده باشید، به نوعی به این دستورات آب و تاب می دهند که انگار آن ها را در mysqli ندیده ایم!
از آن جایی که این دوره برای افراد مبتدی نیست، بنده سعی می کنم مواردی را که ارزش یادآوری داشته و مربوط به PDO بوده و با mysqli تفاوت دارد، توضیح بدهم.
دقیقا همانطور که در مثال بالا دیدید تنها کاری که باید بکنید این است که یک کوئری را prepare (آماده کردن با placeholder ها) کرده و سپس execute (اجرا) کنید.
برای کوئری های DELETE
و SELECT
این پروسه تقریبا یکی است. تنها تفاوتی که در مورد این دستور ها باید به یاد داشته باشید این است:
از آن جایی که کوئری های DML1 (یعنی INSERT، UPDATE، DELETE) هیچ داده ای را بر نمی گردانند، شما می توانید از method chaining (دستورات زنجیره ای) استفاده کرده و ()execute را همراه ()prepare صدا بزنید.
1- قبل از ارائه ی مثال توضیحی راجع به DML:
CREATE
و ALTER
و RENAME
و DROP
و ...SELECT
و INSERT
و UPDATE
و DELETE
و...بر اساس چیزی که گفته شد به مثال زیر توجه کنید:
$sql = "UPDATE users SET name = ? WHERE id = ?"; $pdo->prepare($sql)->execute([$name, $id]);
اما اگر بخواهید تعداد ردیف های تغییر یافته را نیز ببینید باید از همان روال همیشگی استفاده کنید:
$stmt = $pdo->prepare("DELETE FROM goods WHERE category = ?"); $stmt->execute([$cat]); $deleted = $stmt->rowCount();
ساده ترین و مستقیم ترین روش دریافت ردیف های مختلف داده از یک statement استفاده از حلقه ی ()foreach
است. در PHP می توانید با حلقه ی ()foreach روی PDOStatement
گردش (iterate) کنید. حتما با iterate (به معنی تکرار یا گردش) آشنا هستید؛
به گردش یک حلقه روی یک شیء، آرایه و .. و پردازش آن، iterate می گوییم، در واقع همان کاری که حلقه ها همیشه می کنند!
به مثال زیر توجه کنید:
$stmt = $pdo->query('SELECT name FROM users'); foreach ($stmt as $row) { echo $row['name'] . "\n"; }
در ذهن خود به یاد داشته باشید که این روش، مشکلی برای حافظه ی (memory) برنامه ی ما ایجاد نمی کند، چرا که به جای بارگذاری (load) تمام ردیف ها به صورت یکجا، آن ها را تک تک و دانه دانه تحویل می دهد.
ما قبلا و در mysqli با این تابع آشنا شده ایم اما بهتر است از نزدیک نگاهی دیگر به آن بیندازیم. نحوه ی کار این تابع به این شکل است:
وقتی یک کوئری را اجرا می کنید، (در صورت امکان) آن کوئری به شما یک data set (به معنی یک دسته داده، که همان مجموعه ی نتایج کوئری شماست) بر میگرداند. تصویر زیر را به عنوان یک data set تصور کنید:
pointer همان فلشی است که در ابتدا روی تنیجه ی اول قرار می گیرد، عملیات مناسب را روی آن انجام می دهد و سپس می رود روی نتیجه ی دوم. سپس عملیات مناسب (چیزی که ما تعیین کرده ایم تا روی نتایج انجام شود) را انجام داده و می رود روی نتیجه ی سوم الی آخر ...
این روش کار آن را تا حدی شبیه به تابع ()mysql_fetch_array
می کند، اما تفاوتی نیز با آن دارد. به جای داشتن توابع متعدد (مثل ()mysql_fetch_assoc
و ()mysql_fetch_row
) فقط یک تابع داریم که رفتارش با پارامتر های مختلف تغییر می کند. حالت های fetch در PHP زیاد هستند و بعدا در مورد آن ها صحبت خواهیم کرد اما جهت آشنایی اولیه، به صورت خلاصه از آن ها نام می برم:
PDO::FETCH_NUM
: یک آرایه ی عددی (ایندکس عددی) را بر میگرداند.PDO::FETCH_ASSOC
: یک آرایه ی متناظر را بر میگردند.PDO::FETCH_BOTH
: هر دو مورد بالا را بر میگرداند.PDO::FETCH_OBJ
: یک شیء را بر میگرداند.PDO::FETCH_LAZY
: بدون اینکه حافظه ی برنامه مختل و اشغال شود، برای شما استفاده از هر سه مورد (آرایه ی عددی، آرایه ی متناظر و شیء) را ممکن می کند.از مطالب بالا می توان گفت این متد چه زمانی به کار می رود:
$row = $stmt->fetch(PDO::FETCH_ASSOC);
این کد به شما یک ردیف از statement (در اینجا، متغیر stmt$) را به صورت یک آرایه ی متناظر می دهد.
$stmt = $pdo->query('SELECT name FROM users'); while ($row = $stmt->fetch()) { echo $row['name'] . "\n"; }
متد دیگری که به درد بخورد است PDO::FETCH_CLASS
نام دارد که می تواند یک شیء از یک کلاس خاص را به ما بدهد:
$news = $pdo->query('SELECT * FROM news')->fetchAll(PDO::FETCH_CLASS, 'News');
این کد یک آرایه به شما می دهد که پر از اشیاء از کلاس News می باشد و خصوصیاتِ (property) کلاس ها را از روی مقادیر برگشت داده شده تعیین می کند.
در این روش به یاد داشته باشید که:
به یاد داشته باشید که حالت پیش فرض این متد PDO::FETCH_BOTH
است اما می توانید طبق مثال بالا مثلا با استفاده از PDO::ATTR_DEFAULT_FETCH_MODE
آن را تغییر دهید
در این قسمت با انواع روش های دریافت داده ها در PDO مانند حلقه ی foreach
و دستور fetch
آشنا شدیم؛ سعی کرده ام تا جایی که ممکن است بحث را باز و ریز کنم تا جای شبهه و ابهامی باقی نمانده باشد اما با این حال به یاد داشته باشید که این دوره مخصوص افرادی است که آشنایی قبلی با مباحث پایگاه داده و برنامه نویسی شیء گرا دارند.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.