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

Практика использование ООП

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

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Это хороший код?

    Он выводит имя пользователя и возраст.

    Код не мой, просто изучаю его, по накидайте пожалуйста небольшие нормальные примеры. Только не надо там где машина заводится, едет и останавливается.

    PHP:
    1. <?php
    2.     class Db
    3.     {
    4.         private $link;
    5.         private $host = 'localhost';
    6.         private $user = 'root';
    7.         private $password = '';
    8.         private $database = 'oop';
    9.         private $table = 'users';
    10.  
    11.         //Подключается к базе:
    12.         public function __construct()
    13.         {
    14.             $this->link = mysqli_connect($this->host, $this->user, $this->password, $this->database );
    15.         }
    16.  
    17.         //Делает запрос к базе:
    18.         public function get($id, $field)
    19.         {
    20.             $query = $this->createSelect($id, $field);
    21.             $result = $this->makeQuery($query); //будет в виде ['age'=>25]
    22.             return $result[$field]; //а тут достанем 25
    23.         }
    24.  
    25.         //Создает строку с запросом:
    26.         private function createSelect($id, $field)
    27.         {
    28.             $table = $this->table;
    29.             return "SELECT $field FROM $table WHERE id=$id";
    30.         }
    31.  
    32.         //Совершает запрос к базе:
    33.         private function makeQuery($query)
    34.         {
    35.             $result = mysqli_query($this->link, $query);
    36.             return mysqli_fetch_assoc($result);
    37.         }
    38.     }
    39.    
    40.     $bazaDan = new Db;
    41.    
    42.     echo $bazaDan->get('1', 'name');
    43.     echo '<br>';
    44.    
    45.  
    46.     class User
    47.     {
    48.         private $id;
    49.         private $db;
    50.  
    51.         public function __construct($id)
    52.         {
    53.             $this->id = $id;
    54.  
    55.             //Создаем объект для работы с БД:
    56.             $this->db = new Db;
    57.         }
    58.  
    59.         public function getName()
    60.         {
    61.             return $this->db->get($this->id, 'name');
    62.         }
    63.  
    64.         public function getAge()
    65.         {
    66.             return $this->db->get($this->id, 'age');
    67.         }
    68.  
    69.     }
    70.    
    71.     $user = new User('1');
    72.    
    73.     echo $user->getName();
    74.     echo '<br>';
    75.     echo $user->getAge();
    76.    
    77. ?>
     
  2. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    У класса Db как минимум две проблемы:
    1. Количество соединений с базой равно количеству экземпляров этого класса
    2. К базе можно выполнить только простейший вариант запроса выборки данных и в результате получить значение одного поля.
     
  3. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Почему, там же один раз вызов mysqli_connect ?
     
  4. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Но он происходит каждый раз, когда создается экземпляр этого класса. В приведенном коде их два.
     
    Fell-x27 нравится это.
  5. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Друг, я конечно в ооп слабоват, но там один экземпляр класса $link идет на вызов, а другие в аргументы mysqli_connect (кроме table)
     
    #5 keren, 26 ноя 2017
    Последнее редактирование: 26 ноя 2017
  6. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Часто вижу, что к базе обращаются через self или static, почему?
     
  7. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Потому что static свойства и методы принадлежат классу, а не его экземплярам. Класс один - соединение с базой одно. Обращение self - обращение к классу, тогда как $this - обращение к экземпляру.
    $link - это не класс, а его свойство. И создается два экземпляра: один - просто в коде, второй внутри экземпляра класса User.

    PHP:
    1.     $bazaDan = new Db;
    2.    ...
    3.     class User
    4.     {
    5.         ...
    6.         public function __construct($id)
    7.         {
    8.             ...
    9.             //Создаем объект для работы с БД:
    10.             $this->db = new Db;
    11.         }
    12.     ...
    13.     }
    14.  
    15.     $user = new User('1');
     
    [vs] и Dimon2x нравится это.
  8. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Но User не использует функцию подключения к дб mysqli_connect !
     
  9. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Зато использует конструктор Db, где эта функция используется.
     
  10. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Там два отдельных, не связанных между собой класса - Db и User, и во втором ее нет и из нее туда ничего не попадет потому что это ооп.
     
  11. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @keren, вот тут про конструкторы, но там справа еще куча всего полезного.

    P.S.: "справа" - меню php.net, но ссылку исправили на php.ru
     
  12. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    @Dimon2x очень нехватает документирования кода)) очень люблю когда документирован)
     
  13. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    self, static и global это такой общий доступ, статические переменные еще сохраняют данные между вызовами, есть отрицательное мнение об этом.
     
  14. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    @Maputo где по ссылке говорится что объект одного класса можно засунуть в конструктор другого класса? И я не имел в виду что link это класс, ты вначале употребил слова экземпляры класса, а я за тобой повторил, конечно это свойство класса, и вот это - $this->db = new Db; - объект одного класса внутри другого класса, я не в курсе что такое может быть, и ссылка на private $db; в классе User, я не представляю как это может запустить подключение в классе Db.
     
  15. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Вот кстати тут решение:
    https://php.ru/forum/threads/podkljuchenie-k-baze-dannyx-oop.58985/
    PHP:
    1. class Books
    2. {
    3. private $mysqli;
    4. public function __construct(\mysqli $mysqli)
    5. {
    6.     $this->mysqli = $mysqli;
    7. }
    8. public function otherMethod ()
    9. {
    10.     $this->mysqli->query("SELECT 1");
    11. }
    12. }
    13. $mysqli = new DB_CONFIG();
    14. $books = new Books($mysqli);
     
  16. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.557
    Симпатии:
    631
    что же произойдет, если мы сделаем
    PHP:
    1. $user1 = new User(1);
    2. $user2 = new User(2);
    сколько раз будет вызвана функция mysqli_connect()?
     
  17. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @[vs] получается 2 раза, потому что создаётся 2 объекта
     
  18. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.557
    Симпатии:
    631
    @Dimon2x верно, но можно обойтись без статик-свойств в классе User и без аргумента в конструкторе, если класс DB будет Singleton.
    PHP:
    1. $this->db = DB::getInstance();
     
    Dimon2x нравится это.
  19. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    А вы понимаете разницу между обращением к классу и обращению к методу?
    И что будет если объект одного класса засунуть внутрь метода другого класса?
    Вы посмотрите внимательнее первый пост.
     
  20. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.557
    Симпатии:
    631
    @keren конструктор (функция __construct()) выполняется при создании каждого нового экземпляра с помощью new. Уже была ссылка на то, как работают конструкторы.
     
  21. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Я знаю как работает конструктор, объект для конструктора в том классе User это $user = new User('1'); А там еще внутрь вставили левый $this->db = new Db;,
    вы думаете сервер это прочитает?
     
  22. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.557
    Симпатии:
    631
    Ошибок в этом коде нет, это будет работать.
    --- Добавлено ---
    @keren о чем тут говорить, если так просто взять и проверить?)
    --- Добавлено ---
    @keren о чем тут говорить, если так просто взять и проверить?)
     
  23. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @keren, я Вам дал ссылку для того чтобы Вы еще раз посмотрели в какой момент используется конструктор. Каждый раз когда имя класса используется с оператором new - работает конструктор этого класса. Если объект базы создается внутри конструктора класса пользователя, то в этот же момент будет задействован код, находящийся внутри конструктора класса базы.
    Подобный код:
    PHP:
    1. $bazaDan = new Db;
    2. ...
    3. $user = new User('1');
    создаст два экземпляра класса базы. А это значит, что код конструктора класса базы будет запущен дважды.
     
  24. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.580
    Симпатии:
    1.760
  25. askanim

    askanim Старожил

    С нами с:
    7 апр 2016
    Сообщения:
    2.201
    Симпатии:
    166
    Адрес:
    GABRIEL
    Потому что ты не понимаешь, что такое ООП!
    --- Добавлено ---
    Исходя из постов выше ты даже запаха ООП не чувствуешь!