За последние 24 часа нас посетили 8832 программиста и 669 роботов. Сейчас ищут 164 программиста ...

Подключение к БД через $_SESSION['объект']

Тема в разделе "PHP для новичков", создана пользователем g1e8, 7 фев 2020.

  1. g1e8

    g1e8 Новичок

    С нами с:
    17 окт 2019
    Сообщения:
    17
    Симпатии:
    2
    Хочу загнать в сессию объект, а в объект функцию подключения а БД, чтобы каждый раз include_once не писать... примерно так ( session_start(); - сюда же)
    PHP:
    1. class User {
    2. function acces_bd(){
    3. try {
    4.     $pdo = new PDO("$driver:host=$host; dbname=$db_name; charset=$charset", $db_user, $db_pass, $options);
    5.     session_start();
    6. }
    7. catch (PDOException $e) {
    8.       print "Error!: " . $e->getMessage();
    9.       die("Ошибка подключения к базе");
    10.     }    }      }     }
    подключаться через PDO так
    PHP:
    1. $_SESSION['user']=new User;
    2. $login=trim($_POST['login']);
    3. $pwd=trim($_POST['pwd']);
    4. $_SESSION['user']->acces_bd();
    5. $sql= "SELECT login, password FROM zakazchik WHERE login = :login";
    6.     $params=[':login' => $login];
    7.     $stmt=$pdo->prepare($sql);
    8.     $stmt->execute($params);
    9.     $user=$stmt->fetch(PDO::FETCH_ACCOS);
    Ошибка. Понятно, что все дело в "$stmt=$pdo->prepare($sql);" - $pdo - объект внутри объекта.
    А как поправельному сделать
     
  2. sushko

    sushko Новичок

    С нами с:
    17 июл 2019
    Сообщения:
    59
    Симпатии:
    7
    Во первом фрагменте нет сохранения PDO в сессию, а во втором фрагменте не раскрыто, откуда вдруг взялась переменная $pdo, но в общем - так сделать нельзя. В сессию можно сохранить только сериализуемые сущности; подключение к БД сериализуемой сущностью не является.

    Т.е. если коротко, то никак, только открывать подключение к БД каждый раз наново.
     
  3. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    7.234
    Симпатии:
    1.401
    Гуглите единую точку входа, автозагрузку, PSR
     
  4. g1e8

    g1e8 Новичок

    С нами с:
    17 окт 2019
    Сообщения:
    17
    Симпатии:
    2
    Подключение к БД у меня есть - проверил,
    PHP:
    1. $_SESSION['user']->acces_bd();
    работает, но на эту строчку ругается
    PHP:
    1. $stmt=$pdo->prepare($sql);
    Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\OSPanel\domains\test\include\auto.php:10 Stack trace: #0 {main} thrown in C:\OSPanel\domains\test\include\auto.php on line 10
     
    #4 g1e8, 7 фев 2020
    Последнее редактирование: 7 фев 2020
  5. miketomlin

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

    С нами с:
    9 авг 2016
    Сообщения:
    2.299
    Симпатии:
    366
    Сессии не для этого предназначены. Вообще ХЗ, что вы пытаетесь сделать. Постоянное соединение? :D

    $pdo?
    --- Добавлено ---
    Вы бы сначала с областью видимости переменной разобрались, а уже потом покушались на архитектурные решения ;)
     
    AlexandrS нравится это.
  6. g1e8

    g1e8 Новичок

    С нами с:
    17 окт 2019
    Сообщения:
    17
    Симпатии:
    2
    я вообще сделал так
    да все работает, надо только global $pdo
    я хотел в объект $_SESSION['user'] и подключение к БД и session_start.....
    но так не получится, что бы запустить $_SESSION нужен session_start, я чтобы запустить session_start нужен объект $_SESSION['user']
     
    #6 g1e8, 7 фев 2020
    Последнее редактирование: 7 фев 2020
  7. _ne_scaju_

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

    С нами с:
    25 ноя 2016
    Сообщения:
    1.976
    Симпатии:
    111
    global зло, от них избавляться лучше.
    Можно попробовать в конструктор передать подключения __construct() - передаешь подключения, а вообще еще лучше посмотреть что такое единая точка входа и как ее сделать, как посоветовали выше.
    чтобы запустить $_SESSION не нужен session_start(), тут наоборот, чтобы работала $_SESSION нужно запустить session_start().
    --- Добавлено ---
    запрос можно сделать компактней:
    PHP:
    1.     $stmt=$pdo->prepare("SELECT `login`, `password` FROM `zakazchik` WHERE `login` = ?");
    2.     $stmt->execute([$login]);
    3.     $user=$stmt->fetch();
     
  8. g1e8

    g1e8 Новичок

    С нами с:
    17 окт 2019
    Сообщения:
    17
    Симпатии:
    2
    дык я так и делаю, только поготовленный, только не показал
    PHP:
    1.     $stmt=$pdo->prepare("SELECT `login`, `password` FROM `zakazchik` WHERE login=":login);
    не показал - это очевидно... надо 1. или ссиию вынимать из функции 2. или функцию... короче - утром стулья - вечером деньги........ никак не плучиться запустить $__SESSION(функция), если в нутри функции start_sesson... или "start_sesson" ВЫНИМАТЬ НАРУЖУ... ПРИНЦИПИАЛЬНО... можно это обойти.... но зачем?
     
    #8 g1e8, 7 фев 2020
    Последнее редактирование: 7 фев 2020
  9. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.681
    Симпатии:
    277
    @g1e8, вот тебе говорят не надо одевать трусы на голову, а ты не слушаешь.
     
  10. Зингер

    Зингер Новичок

    С нами с:
    20 июл 2017
    Сообщения:
    103
    Симпатии:
    4
    Надо
    Не знаю, поможет или нет.
     
  11. AlexandrS

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

    С нами с:
    30 сен 2017
    Сообщения:
    655
    Симпатии:
    101
    Адрес:
    Краснодар
    В методе acces_bd() должен быть
    PHP:
    1. return new PDO ....
    а не
    PHP:
    1. $pdo = new PDO ...
    тогда логически, всё будет выглядеть
    PHP:
    1.  $_SESSION['user']->acces_bd()->prepare($sql);
    Но это нечто :rolleyes:, вы хотите чтоб фотография ожила o_O
    PS: просто в сессии экземпляр класса не будет жить.
    Т.е. если ваша цель создать единожды подключение к БД закинуть его в сессию и потом просто обращаться к ней, так оно работать не будет.
    В PDO есть постоянное соединение (https://www.php.net/manual/ru/pdo.connections.php), но там есть свои НО
     
    #11 AlexandrS, 9 фев 2020
    Последнее редактирование: 9 фев 2020
  12. artoodetoo

    artoodetoo Суперстар
    Команда форума Модератор

    С нами с:
    11 июн 2010
    Сообщения:
    10.075
    Симпатии:
    958
    Адрес:
    там-сям
    откажись от этой идеи :)

    не надо избегать include/require. хорошей практикой считается использование лоадеров классов. они подгружают файлы, но при этом в твоём коде нет include, он происходит "за кадром".
    --- Добавлено ---
    В твоём случае стоит вынести работу с базой в отдельный класс-помошник. Обращайся к нему на "статический" манер или используй какой-нибудь приём по сохранению соединения PDO в статическом свойстве, это поможет тебе вызывать new PDO только один раз за сеанс работы. Т.е. за один HTTP запрос. Понимаешь о чём я?
    --- Добавлено ---
    И ещё, не надо думать о сессии как о кэше. Это не кэш.
    Сессия нужна для сохранения состояния в очень ограниченном контексте и объёме. Не надо в неё впихивать всё подряд, это приведёт только к неразберихе и потере контроля.
     
  13. g1e8

    g1e8 Новичок

    С нами с:
    17 окт 2019
    Сообщения:
    17
    Симпатии:
    2
    Все прекрасно работает, суть в том, что класс надо определить до открытия сессии... те
    PHP:
    1. $_SESSION['user'] = new User;
    2. class User
    3. { ......}
    можно и объект PDO таким же манером загнать... только не к чему
    а в $_SESSION['user'] у меня 10 переменных вертится - она очень маленькая... опять же конструктор - штука удобная