За последние 24 часа нас посетили 16520 программистов и 1714 роботов. Сейчас ищут 945 программистов ...

Проблемы с PDO

Тема в разделе "PHP для новичков", создана пользователем ogogon, 21 июл 2024.

Метки:
  1. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Коллеги, подскажите pls, что я делаю не так...

    Я осваиваю работу с базой данных. Хочу научиться правильно читать ее содержимое и удобно работать с ним.
    У меня есть тестовая база. В ней содержится пользователи и пароли, но вполне могли бы породы кошек и их расцветки или авторы и их книжки.
    Код (Text):
    1. CREATE TABLE users (
    2.   id INT PRIMARY KEY AUTO_INCREMENT,
    3.   username VARCHAR(255),
    4.   password VARCHAR(255),
    5.   comment VARCHAR(255)
    6. );
    7. INSERT INTO users (username,password,comment) VALUES ('admin','','Default Admin');
    8. INSERT INTO users (username,password,comment) VALUES ('admin1','Jgw4LNVekL8jEjq5dU','Admin №1');
    9. INSERT INTO users (username,password,comment) VALUES ('admin2','UKCMLTS073cq26iIOc','Admin №2');
    10. INSERT INTO users (username,password,comment) VALUES ('admin3','oU1Qky27TzmFOGFj4c2I','Admin №3');
    11. INSERT INTO users (username,password,comment) VALUES ('admin4','JSfkWJWjT6rdI5cgHo','Admin №4');
    12. INSERT INTO users (username,password,comment) VALUES ('admin5','HLTmJCnzxm2DW6LT9','Admin №5');
    Я соединяюсь с базой и читаю её.
    PHP:
    1. $dsn = 'mysql:dbname='.$config['db_name'].';host='.$config['db_host'];
    2. $pdo = new PDO($dsn, $config['db_user'], $config['db_pass']);
    3. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    4.  
    5. $sth = $pdo->prepare("SELECT * FROM `users`;");
    6. $sth->execute();
    7. $data = $sth->fetchAll(PDO::FETCH_UNIQUE);
    8.  
    9. $result = print_r($data, true);
    10. echo $result;
    Получаю выдачу:
    Array ( [1] => Array ( [username] => admin [1] => admin [password] => [2] => [comment] => Default Admin [3] => Default Admin ) [2] => Array ( [username] => admin1 [1] => admin1 [password] => Jgw4LNVekL8jEjq5dU [2] => Jgw4LNVekL8jEjq5dU [comment] => Admin №1 [3] => Admin №1 ) [3] => Array ( [username] => admin2 [1] => admin2 [password] => UKCMLTS073cq26iIOc [2] => UKCMLTS073cq26iIOc [comment] => Admin №2 [3] => Admin №2 ) [4] => Array ( [username] => admin3 [1] => admin3 [password] => oU1Qky27TzmFOGFj4c2I [2] => oU1Qky27TzmFOGFj4c2I [comment] => Admin №3 [3] => Admin №3 ) [5] => Array ( [username] => admin4 [1] => admin4 [password] => JSfkWJWjT6rdI5cgHo [2] => JSfkWJWjT6rdI5cgHo [comment] => Admin №4 [3] => Admin №4 ) [6] => Array ( [username] => admin5 [1] => admin5 [password] => HLTmJCnzxm2DW6LT9 [2] => HLTmJCnzxm2DW6LT9 [comment] => Admin №5 [3] => Admin №5 ) )

    Далее, я хочу воспользоваться маленькими, но приятными удобствами, и меняю код.

    PHP:
    1. $my_cols = 'username,password,comment';
    2.  
    3. $sth = $pdo->prepare("SELECT :cols FROM `users`;");
    4. $sth->bindParam(':cols', $my_cols);
    5. $sth->execute();
    6. $data = $sth->fetchAll(PDO::FETCH_UNIQUE);
    В ответ получаю вот что:
    Array ( [username,password,comment] => Array ( ) )

    По идее, он даже подстановку раскрыл, но ничего не получил.

    Как мне адресовывать структуры в $data для поштучного просмотра и почему во втором случае массив пуст?

    Признателен за рекомендации,
    Ogogon.
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.793
    Симпатии:
    1.330
    Адрес:
    Лень
    Ты препарируешь единственное число значения, и я впервые вижу чтобы так названия столбцов пытались кастомизировать. Зачем тебе подготовленные запросы когда значения не совсем те потребляешь?

    твой единственный столбец по требованию называется "username,password,comment"
    --- Добавлено ---
    Юзай query на данный момент
     
  3. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    428
    Симпатии:
    80
    Адрес:
    Бавария, Германия
    Добрый день!

    Имена таблиц и столбцов нельзя заменять параметрами в PDO.
    Попробуйте сделать так
    PHP:
    1. $my_cols = 'username,password,comment';
    2. $sth = $pdo->prepare("SELECT $my_cols FROM `users`;");
    3. $sth->execute();
    4. $data = $sth->fetchAll(PDO::FETCH_UNIQUE);
    Удачи!
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.793
    Симпатии:
    1.330
    Адрес:
    Лень
     
  5. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Благодарю. Я сделал вот так:
    PHP:
    1. $data = $pdo->query("SELECT $my_cols FROM `users`;")->fetchAll(PDO::FETCH_UNIQUE);
    А как мне обращаться к элементам массива $data?
    Например, как вывести вторую колонку третьей полученной строки? $data[3][2] дает ошибку.
    Или как посчитать количество колонок в четвертой строке?
     
  6. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    914
    Симпатии:
    143
    var_dump($data);
    и да, SELECT без лимитов такое себе.
     
  7. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Сказано, наверное, сильно, но уж больно непонятно.
     
  8. Vladimir Kheifets

    Vladimir Kheifets Новичок

    С нами с:
    23 сен 2023
    Сообщения:
    428
    Симпатии:
    80
    Адрес:
    Бавария, Германия
    Добрый день!

    Попробую объснить не больно.

    1. Чтобы узнать как обращаться к элементам массива $data нужно добавить var_dump($data) и Вы увидете структуру данных.
    Возможно, что ошибка на $data[3][2] происходит из-за того, что массив $data нет и запрос возвращает false.

    2. Про "без лимитов такое себе".
    Такие заппросы на больших таблицах могут работать медленно.
    Поэтому в них добавляют параметр LIMIT позвлящий выбирать данные порциями.
    Например, если в Ваш запрос добавить LIMIT 30 OFFSET 1, то будут выбираться максимум 30 строк начиная 1
    PHP:
    1. SELECT $my_cols FROM `users` LIMIT 30  OFFSET 1
    см. https://wiki.byte-welt.net/wiki/Limit_(SQL)
    Удачи!
     
    #8 Vladimir Kheifets, 23 июл 2024
    Последнее редактирование: 23 июл 2024
  9. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Благодарю. Я вставил подсказанную строчку.
    PHP:
    1. echo var_dump($data);
    В ответ получил то-ли шпионскую радиограмму, то-ли лирический сонет на марсианском:
    array(6) { ["admin"]=> array(4) { ["password"]=> string(0) "" [1]=> string(0) "" ["comment"]=> string(13) "Default Admin" [2]=> string(13) "Default Admin" } ["admin1"]=> array(4) { ["password"]=> string(18) "Jgw4LNVekL8jEjq5dU" [1]=> string(18) "Jgw4LNVekL8jEjq5dU" ["comment"]=> string(10) "Admin №1" [2]=> string(10) "Admin №1" } ["admin2"]=> array(4) { ["password"]=> string(18) "UKCMLTS073cq26iIOc" [1]=> string(18) "UKCMLTS073cq26iIOc" ["comment"]=> string(10) "Admin №2" [2]=> string(10) "Admin №2" } ["admin3"]=> array(4) { ["password"]=> string(20) "oU1Qky27TzmFOGFj4c2I" [1]=> string(20) "oU1Qky27TzmFOGFj4c2I" ["comment"]=> string(10) "Admin №3" [2]=> string(10) "Admin №3" } ["admin4"]=> array(4) { ["password"]=> string(18) "JSfkWJWjT6rdI5cgHo" [1]=> string(18) "JSfkWJWjT6rdI5cgHo" ["comment"]=> string(10) "Admin №4" [2]=> string(10) "Admin №4" } ["admin5"]=> array(4) { ["password"]=> string(17) "HLTmJCnzxm2DW6LT9" [1]=> string(17) "HLTmJCnzxm2DW6LT9" ["comment"]=> string(10) "Admin №5" [2]=> string(10) "Admin №5" } }
    Текстуально он немного отличается от выдачи echo print_r($data, true);, но в целом очень близок.

    Что я могу понять из этого глубокомысленного текста в контексте моих вопросов?
     
  10. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.793
    Симпатии:
    1.330
    Адрес:
    Лень
    PHP:
    1. foreach ( $data as $user => $row )
    2. {
    3.     echo "{$user} - " . implode ( ', ', $row ) . PHP_EOL;
    4. }
    --- Добавлено ---
    потому что PDO::FETCH_UNIQUE , чет сайт не могу найти с перечислениями какой-то pdo doc
     
  11. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Благодарю. Вставил этот код.
    После запуска получаю:
    admin - , , Default Admin, Default Admin admin1 - Jgw4LNVekL8jEjq5dU, Jgw4LNVekL8jEjq5dU, Admin №1, Admin №1 admin2 - UKCMLTS073cq26iIOc, UKCMLTS073cq26iIOc, Admin №2, Admin №2 admin3 - oU1Qky27TzmFOGFj4c2I, oU1Qky27TzmFOGFj4c2I, Admin №3, Admin №3 admin4 - JSfkWJWjT6rdI5cgHo, JSfkWJWjT6rdI5cgHo, Admin №4, Admin №4 admin5 - HLTmJCnzxm2DW6LT9, HLTmJCnzxm2DW6LT9, Admin №5, Admin №5

    И вот, что странно:
    1. $user взят в фигурные скобки, но на экран они не выводятся. Так и должно быть?
    2. Если я правильно понимаю, каждая запись должна выводиться в отдельной строке (PHP_EOL). Это не происходит.
    3. Значения полей записей почему-то выводятся по два раза. В этой пещере такое сильное эхо?
    --- Добавлено ---
    Так, может быть, мне есть резон применить какую-то более удобную дисциплину?
     
  12. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    914
    Симпатии:
    143
    PHP: PDOStatement::fetchAll - Manual не смог осилить или опять в поисковиках забанили?
     
  13. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Мда... Несомненно, хамить умеют многие, а вот ответить на вопрос по сути - отнюдь не все.
    Полагаю, что Вы, mon amie, не можете - поэтому и перешли на такой тон.
    (Если бы я сам нашел ответ, поясняющий как правильно обращаться к нужным записям этого массива, я не стал бы надоедать сообществу своим вопросом.)
     
  14. ogogon

    ogogon Активный пользователь

    С нами с:
    9 дек 2015
    Сообщения:
    11
    Симпатии:
    0
    Похоже, у меня получилось обращаться к элементам этого массива.
    Благодарю всех, кто помог толковым советом!