За последние 24 часа нас посетили 76695 программистов и 1667 роботов. Сейчас ищет 921 программист ...

Как писать функции для запросов, и потом правильно подключать их?

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

  1. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    Всем привет, может кто объяснит как писать функции для запроса, и потом с этими функциями работать и подключать их где надо?

    Вот например есть вот такой запрос он выводит на главной странице сколько друзей просятся в друзья, но на главной странице я не хочу этот запрос делать:
    PHP:
    1. $friends_num = $pdo->prepare('
    2. SELECT `user_friends_demands`
    3. FROM `users`
    4. WHERE `user_id` = :user_id');
    5. $friends_num->execute(['user_id' => $user_id]);//Из сессии подставляем id пользователя
    6. $res_friends = $friends_num->fetch();
    Как же написать функции вообще для запросов.
     
  2. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    Вот написал вот такую функцию для этого запроса:
    PHP:
    1. function friend_col() {
    2. include($_SERVER['DOCUMENT_ROOT'].'/system/data/mysql.php'); /*Подключения к бд*/
    3. $user_id = $_SESSION['user_id'];
    4. $friends_num = $pdo->prepare('
    5. SELECT `user_friends_demands`
    6. FROM `users`
    7. WHERE `user_id` = :user_id');
    8. $friends_num->execute(['user_id' => $user_id]);//Из сессии подставляем user_id, для индетификации пользователя
    9. $res_friends = $friends_num->fetch();
    10. return $res_friends['user_friends_demands'];
    11. }
    Правильно ли?
     
  3. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    А зачем каждый раз, для каждого запроса, заново подключаться к БД?
     
  4. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    а как значит?
    если я начинаю писать функцию, и в них еще не разбираюсь вообще, когда то раз может 2 раза пробовал написать их.
    На счет базы, что вверху всех функций подключить? если да пробовал ругается, так как не подключена бд, если я указываю в самом верху файла функций(

    вот две функции которые пока что есть, написаны типа мною, и они слабоваты:
    PHP:
    1. include($_SERVER['DOCUMENT_ROOT'].'/system/data/mysql.php'); /*Подключения к бд*/
    2. function friend_col() {
    3. // include($_SERVER['DOCUMENT_ROOT'].'/system/data/mysql.php'); /*Подключения к бд*/
    4. // $user_id = $_SESSION['user_id'];
    5. $friends_num = $pdo->prepare('
    6. SELECT `user_friends_demands`
    7. FROM `users`
    8. WHERE `user_id` = :user_id');
    9. $friends_num->execute(['user_id' => $user_id]);//Из сессии подставляем user_id, для индетификации пользователя
    10. $res_friends = $friends_num->fetch();
    11. return $res_friends['user_friends_demands'];
    12. }
    13.  
    14. function user_pm_col() {
    15. // include($_SERVER['DOCUMENT_ROOT'].'/system/data/mysql.php'); /*Подключения к бд*/
    16. // $user_id = $_SESSION['user_id'];
    17. $friends_num = $pdo->prepare('
    18. SELECT `user_pm_num`
    19. FROM `users`
    20. WHERE `user_id` = :user_id');
    21. $friends_num->execute(['user_id' => $user_id]);//Из сессии подставляем user_id, для индетификации пользователя
    22. $res_friends = $friends_num->fetch();
    23. return $res_friends['user_pm_num'];
    24. }
    В верху этих функций я подключил бд, и у меня ругается:
    ( ! ) Fatal error: Call to a member function prepare() on a non-object in
    Но когда я во внутрь функцию подключаю БД то не ругается!!!
    Как мне быть?
     
    #4 _ne_scaju_, 6 июн 2017
    Последнее редактирование: 6 июн 2017
  5. san4ez

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

    С нами с:
    13 авг 2016
    Сообщения:
    331
    Симпатии:
    47
    чет я не пойму, почему $user_id = $_SESSION['user_id']; закомментировано?
     
  6. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @san4ez
    Ай да там раскоментировать нужно)
    А как мне быть с подключением к бд, чтобы он в каждом файле не подключался, как один раз его подключить и проинклудить?
    А то у меня получается так:
    Файл1: инклуд БД
    Файл2: инклуд БД
    Файл3: инклуд БД
    И так во всех файлах подключаю где использую запросы к БД, и в таком случае получается загрузка страниц идет с хорошей задержкой. Думаю если бы один раз подключиться к БД проблем бы не было бы с задержкой.
    Спасибо за объяснения.
     
  7. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Прочитать нормально руководство по PHP
    1) Использовать глобальные переменные. В процедурном коде до 10 глобальных переменных на проект считается нормой. Когда до ОО-кода дойдёшь, там их не любят (хотя я лично одну-две допускаю), но есть разные решения, их заменяющие
    2) Передавать объект PDO в функцию параметром.
     
  8. san4ez

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

    С нами с:
    13 авг 2016
    Сообщения:
    331
    Симпатии:
    47
    мое мнение (новичка): так и нужно, и обязательно в конце загрузки страницы закрывать соединение с бд. Могу ошибаться.
    --- Добавлено ---
    то есть в конце всех операций с бд в коде, а не загрузки страницы)
     
  9. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    О, ещё одно хорошее решение - сделать функцию, возвращающую подключение к БД, а внутри - статическую локальную переменную (загугли)
    PHP:
    1. function getDb()
    2. {
    3.    static $db = null;
    4.    if ($db === null) {
    5.        $db = new PDO(/* ... */);
    6.    }
    7.    return $db;
    8. }
    И дёргать откуда угодно. Статическая локальная переменная и проверка в 4 строке гарантируют, что подключение к БД будет выполнено только один раз, сколько раз не была бы вызвана эта функция
     
  10. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.810
    Симпатии:
    1.332
    Адрес:
    Лень
    PHP:
    1. Class SQL
    2. {
    3.     const HOST = '';
    4.     const DB_NAME = '';
    5.     const USER = '';
    6.     const PASSWORD = '';
    7.     const CHARSET = 'utf8';
    8.     const HOST_LOCAL = TRUE;
    9.  
    10.     protected static $INSTANCE = NULL;
    11.  
    12.     public static function instance()
    13.     {
    14.         if ( self::$INSTANCE === NULL )
    15.         {
    16.             self::$INSTANCE = new PDO( sprintf ( 'mysql:host=%s;dbname=%s;charset=%s',
    17.                                                     ( self::HOST_LOCAL ? 'localhost' : self::HOST ),
    18.                                                     ( self::HOST_LOCAL ? 'ray_local' : self::DB_NAME ),
    19.                                                     self::CHARSET
    20.                                                 ), ( self::HOST_LOCAL ? 'root' : self::USER ), ( self::HOST_LOCAL ? '' : self::PASSWORD ),
    21.             [
    22.                 PDO::ATTR_ERRMODE                => PDO::ERRMODE_EXCEPTION,
    23.                 PDO::ATTR_DEFAULT_FETCH_MODE    => PDO::FETCH_ASSOC,
    24.                 PDO::ATTR_EMULATE_PREPARES        => FALSE,
    25.             ] );
    26.         }
    27.      
    28.         return self::$INSTANCE;
    29.     }
    30.     public static function __callStatic( $method, $args )
    31.     {
    32.         return call_user_func_array ( [ self::instance(), $method ], $args );
    33.     }
    34.     public static function P( $sql, $args = [] )
    35.     {
    36.         $stmt = self::instance() -> prepare( $sql );
    37.         $stmt -> execute( $args );
    38.      
    39.         return $stmt;
    40.     }
    41. }
    42.  
    43. //// другой.php
    44. SQL::P( "SELECT FOLDER, LOL FROM table_test" ) -> fetchAll( PDO::FETCH_KEY_PAIR );
     
  11. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    Натолкни меня на статейку эту, спасибо...

    Да и еще вопрос, у меня есть 2 файла один отвечает за defined(локал, юзер, пароль, бд) а второй файл за подключения к бд.
    Мне нужно в файле подключение единственный вход делать?
     
  12. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Тебя навсегда забанили в гугле?
    http://pogugli.com/?159108
    --- Добавлено ---
    Причём здесь единственный вход? Ты о чём вообще?
     
  13. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @MouseZver
    А по проще нет, а то я в функциях не очень разбираюсь, имею введу примерный синтаксис как у меня сделать( а то ты сокращаешь куски кода, ты в них просто разбираешься а я нет.
    Короче вот 2 файла, и как с них сообразить такой же класс, как у тебя?
    PHP:
    1. <?php
    2. /*Конфигурационный файл*/
    3. $db_server = 'localhost';
    4. $db = '';
    5. $user = 'root';
    6. $pass = '';
    7. //Кодировка
    8. $charset = 'utf8';
    9. $err_connect = 'Не могу соединится с БД';
    10. $err_db_select = 'Данная БД отсутствует на сервере';
    и второй файл который обрабатывает эти данные:
    PHP:
    1. <?php
    2. include ($_SERVER['DOCUMENT_ROOT'].'/system/data/db.php');
    3. $dsn = "mysql:host=$db_server;dbname=$db;charset=$charset";
    4. $opt = [
    5.      PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    6.      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    7.      PDO::ATTR_EMULATE_PREPARES   => false,
    8. ];
    9. $pdo = new PDO($dsn, $user, $pass, $opt);
    10. ?>
    Как написать такой же класс, понятным для меня методом?
    Хотелось бы сделать такой класс...
    Спасибо!!!
    --- Добавлено ---
    @mkramer
    То ошибся, за единственный вход!!!
     
  14. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.810
    Симпатии:
    1.332
    Адрес:
    Лень
  15. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    @MouseZver, какие классы, если человек глобальные переменные от локальных не сильно отличает, и конфиг от единой точки входа, функции-то не сильно понимает.
    @_ne_scaju_, делать единую точку входа или нет - тебе решать. Если единая точка входа, конфиг в ней подключается, если точек входа много - конфиг в каждой подключается.
     
  16. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    Да я сейчас не отличаю глобальные от локальных, но о них знаю :D
    Буду читать и развиваться...
     
  17. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Это как?
     
  18. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    Но ты же считаешь что я не знаю, чем отличаются глобальные от локальных переменных.
     
  19. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    @MouseZver
    Если я правильно понял, при использовании класса для БД нужно будет всего лишь, ВЫЗЫВАТЬ сам класс и пользоваться им?
    Покажите пожалуйста на этом примере, или скажите что не так делаю?
    PHP:
    1. //Запрос на вывод логина юзера
    2. SQL::P('SELECT `user_login` FROM `users` WHERE `user_id` = :user_id');
    3. ##############а дальше как действовать?###########
    4. ##############что делать что подставлять?#########
    5. ##############и действуют ли тут плейсхолдеры?####
    6. $user->execute(['user_id' => $user_id]);//Из сессии подставляем id пользователя
    7. $res_user = $user->fetch();
    8. if ($res_user){
    9. echo 'Привет '.$res_user['user_login'].'<br>';
    10. }
     
    #19 _ne_scaju_, 7 июн 2017
    Последнее редактирование: 7 июн 2017
  20. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Классы не вызывают. Вызывают методы. В случае с кодом от @MouseZver статические методы, поэтому без создания экземпляра. Я тебе про классы не стал писать, поскольку считаю, что сначала с функциями надо разобраться. ну и не люблю я вот такие классы, из одной статики.
     
  21. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    вот кстати я согласен с тобой надо разобраться с функциями а классы на потом оставить.
    Так а как же добиться чтобы я не подключал в каждом файле БД, что для этого потребуется?
    И подключения которое я использую к БД нормальное?
     
  22. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Ещё раз. Зависит от архитектуры приложения. Если у тебя единая точка входа, то включаешь в самом верху index.php и радуешься. Если не единая - то включаешь в каждом файле.
     
  23. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.810
    Симпатии:
    1.332
    Адрес:
    Лень
    как тогда обращаешься к бд вне класса какого - либо если
    PHP:
    1. $db = new db();
    2.  
    3. function test()
    4. {
    5. return $db -> ... # хрена ибо non object
    как с другой стороны статическим методом глобально прописывать где угодно можно.
    --- Добавлено ---
    убирем:
    global $var - это прошлое
    function ..() use () - х2потеря производительности
     
  24. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.596
    Симпатии:
    1.764
    Я написал функцию чуть выше. А ещё есть паттерн registry, если мы уж про ООП говорим.
    --- Добавлено ---
    И ещё куча паттернов, которые упоминать в этой теме не сильно уместно, чтоб ТС не грузить непонятными названиями
     
    Fell-x27 нравится это.
  25. _ne_scaju_

    _ne_scaju_ Старожил

    С нами с:
    25 ноя 2016
    Сообщения:
    2.149
    Симпатии:
    118
    @mkramer
    пока что нет у меня единой точки, подключения идет во всех файлах.
    Хотел спросить единая точка, это типа в этом файле подключены все модули все скрипты сайта?
    --- Добавлено ---
    @MouseZver
    не много не понял тебя!!!