با سلام، در این قسمت به بررسی بیشتر راه های دریافت داده ها در PDO خواهیم پرداخت و برخی مسائل حاشیه ای را هم ذکر می کنیم.
اگر PDO روی حالت mysqlnd1 بوده و emulation mode نیز خاموش باشد، داده های برگشتی می توانند از نوع int
(عدد صحیح) و float
(عدد اعشاری) باشند.
به طور مثال اگر یک جدول بسازیم:
create table typetest (string varchar(255), `int` int, `float` float, `null` int); insert into typetest values('foo',1,1.1,NULL);
و سپس آن را با PDO بر پایه ی mysqlnd (و emulation mode خاموش) کوئری بزنیم، خروجی به شکل زیر خواهد بود:
array(4) { ["string"] => string(3) "foo" ["int"] => int(1) ["float"] => float(1.1) ["null"] => NULL }
در غیر این صورت همان رفتار قدیمی در تابع ()mysql_fetch_array را خواهیم دید؛ تمام مقادیر به صورت رشته ای برمیگردند به غیر از null که به صورت null برمیگردد.
1- mysqlnd چیست؟ برای برقراری ارتباط با پایگاه داده دو driver داریم: libmysqlclient و mysqlnd که تفاوت هایشان به شرح زیر است:
برای اطلاعات بیشتر به http://php.net/manual/en/mysqlinfo.library.choosing.php مراجعه نمایید.
اگر از این حالت خوشتان نمی آید و دوست دارید به همان روش قدیمی کار کنید، می توانید به شکل زیر آن را غیر فعال کنید:
$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
این تابع هنگامی که برای انتخاب یک فیلد از پایگاه داده بسیار موثر است!
// id دریافت نام بر اساس $stmt = $pdo->prepare("SELECT name FROM table WHERE id=?"); $stmt->execute([$id]); $name = $stmt->fetchColumn(); // دریافت تعداد ردیف ها در جدول $count = $pdo->query("SELECT count(*) FROM table")->fetchColumn();
یکی از بهترین و کاربردی ترین توابع در PDO است که بسیاری از کار هایی که باید دستی انجام می شد را به صورت خودکار برای ما انجام می دهد!
در واقع ()PDOStatement::fetchAll یک آرایه برمی گرداند که شامل تمامی ردیف هایی (row) است که توسط کوئری ما برگشت داده شده اند. بر این اساس می توانیم بگوییم:
شما حتی باورتان نمی شود که این تابع به چند حالت می تواند داده ها را برگرداند! تمام این حالات با دستور *_PDO::FETCH
کنترل می شود.
در حالت پیش فرض، این تابع یک آرایه عددی ساده را بر میگرداند که حاوی تمام ردیف های برگردانده شده است اما شما می توانید با ثابت های مختلف مربوط به این تابع (مانند PDO::FETCH_NUM
یا PDO::FETCH_ASSOC
یا PDO::FETCH_OBJ
یا ...)، قالب داده های برگشتی را تعیین کنید:
$data = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_ASSOC); var_export($data); /* array ( 0 => array('John'), 1 => array('Mike'), 2 => array('Mary'), 3 => array('Kathy'), )*/
برخی اوقات دریافت آرایه ی تک بعدی به صورت مستقیم از کوئری خیلی به درد بخور است، مخصوصا اگر بتوانیم یک ستون از ردیف های مختلف را دریافت کنیم. راه حل اش این است:
$data = $pdo->query('SELECT name FROM users')->fetchAll(PDO::FETCH_COLUMN); /* array ( 0 => 'John', 1 => 'Mike', 2 => 'Mary', 3 => 'Kathy', )*/
این قالب نیز از قالب های بسیار مفید برای توسعه دهندگان است؛ زمانی از این قالب استفاده می کنیم که قصد دریافت یک ستون را داشته باشیم اما ایندکس آن را به صورت عادی و عددی نخواهیم، بلکه بخواهیم ایندکس ها بر اساس یک فیلد دیگر باشند. مثال را ببینید:
$data = $pdo->query('SELECT id, name FROM users')->fetchAll(PDO::FETCH_KEY_PAIR); /* array ( 104 => 'John', 110 => 'Mike', 120 => 'Mary', 121 => 'Kathy', )*/
توجه: برای این قالب حتما باید دو ستون (و تنها دو ستون) انتخاب کنید که مورد اولشان unique (منحصر به فرد - به طور که در جدول مشترک نبوده و تکرار نشود) باشد.
اگر بخواهیم یک ردیف را با یک ایندکس از نوع فیلدی دیگر دریافت کنیم از این قالب استفاده می کنیم. تفاوت این قالب با قالب بالا این است که در این قالب به جای یک ستون، تمام یک ردیف را می خواهیم:
$data = $pdo->query('SELECT * FROM users')->fetchAll(PDO::FETCH_UNIQUE); /* array ( 104 => array ( 'name' => 'John', 'car' => 'Toyota', ), 110 => array ( 'name' => 'Mike', 'car' => 'Ford', ), 120 => array ( 'name' => 'Mary', 'car' => 'Mazda', ), 121 => array ( 'name' => 'Kathy', 'car' => 'Mazda', ), )*/
نکته: اولین ستون انتخاب شده در این قالب باید unique (منحصر به فرد) باشد. در این مثال، فرض ما این بوده است که ستون اول، id افراد است و بنابراین منحصر به فرد تلقی می شود اما شما باید حواستان به جدول هایتان باشد.
دستور PDO::FETCH_GROUP
ردیف ها را به صورت یک آرایه ی تو در تو در می آورد که ایندکس ها، مقادیر منحصر به فرد از ستون های اول هستند و مقادیر (value) آرایه هایی شبیه به آرایه هایی بوده که دستور ()fetchAll
بر میگرداند.
به طور مثال، کد زیر دختر ها را از پسر ها جدا می کند و درون آرایه های متفاوت قرار می دهد:
$data = $pdo->query('SELECT sex, name, car FROM users')->fetchAll(PDO::FETCH_GROUP); array ( 'male' => array ( 0 => array ( 'name' => 'John', 'car' => 'Toyota', ), 1 => array ( 'name' => 'Mike', 'car' => 'Ford', ), ), 'female' => array ( 0 => array ( 'name' => 'Mary', 'car' => 'Mazda', ), 1 => array ( 'name' => 'Kathy', 'car' => 'Mazda', ), ), )
این قالب، راه حل ایده آلی برای مواردی مانند "مرتب سازی بر اساس تاریخ" و "مرتب سازی بر اساس دسته بندی" و ... است.
برای طرفداران برنامه نویسی functional نیز حالت PDO::FETCH_FUNC
موجود است.
حالت های دیگری نیز در دست ساخت است.
در این قسمت، که ادامه ی قسمت قبلی از این مبحث بود، با حالت های دیگر دریافت داده ها در PDO آشنا شدیم. ممکن است در آینده مثال های بیشتر از این مبحث را خدمت شما ارائه دهم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.