За последние 24 часа нас посетили 22544 программиста и 1014 роботов. Сейчас ищут 709 программистов ...

PDO

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

  1. Дюран

    Дюран Активный пользователь

    С нами с:
    9 мар 2018
    Сообщения:
    256
    Симпатии:
    19
    Прочитать еще недостаточно, как в поговорке говорят - смотреть в книгу, видеть фигу. И никакие селфи на фоне книжек не помогут если после их прочтения вы все равно топите за синглтоны на статике
    Так что он в эту тему должен все over 100 файлов примера своей архитектуры для вас запощивать?
     
  2. Valick

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

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Дюран, а ничего что @MouseZver уложился в несколько строчек кода, о каких "over 100 файлов" идёт речь???
    Ещё раз повторю начинающему программисту ответ должен соответствовать уровню.
    ок уговорил, рисуй сюда пример своего кода где синглтон без статики
    @askanim, я так и не понял, ты к умным или к красивым? Или еще не определился?
     
  3. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    По второй моей ссылке в #23 посте.
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    там не код, а структура логики.
    --- Добавлено ---
    Он не сможет, или понимает и молчит, так как глобально задействовать, без статики свой класс БД, не сможет.
    --- Добавлено ---
    P.s: я знаю как во фреймворках работается с экземпляром класса по БД и на будущее присеку вопрос "а зачем нужна глобальная доступность"
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    Ты считаешь, что какие-то проблемы даёт работа с экземпляром?
    --- Добавлено ---
    Лучший вариант - держать БД в di-контейнере, вариант похуже, но приемлемый - положить в реестр.И в том и в другом случае синглтон не нужен.
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    А я считаю, что какие то проблемы дает работа с экземпляром во внутренней стороны ? Внешний Э. не будет доступен новому классу, если нету единой точки Containers, где все классы могут взаимодействовать. Иначе велосипедрон с доп аргументом $link, $db
    --- Добавлено ---
    И повторюсь
    --- Добавлено ---
    Можно вопрос ? - а зачем это автору ?
     
  7. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Пишем класс DB:
    PHP:
    1. class DB
    2. {
    3.     private $pdo;
    4.     public function __construct(PDO $pdo)  {
    5.         $this->pdo = $pdo;
    6.     }
    7.     public function query(string $sql, array $params = []): PDOStatement {
    8.         $stmt = $this->prepare($sql, $params);
    9.         $stmt->execute();
    10.         return $stmt;
    11.     }
    12.     public function prepare(string $sql, array $params = []): PDOStatement {
    13.         $stmt = $this->pdo->prepare($sql);
    14.         foreach ($params as $name => $value) {
    15.             $stmt->bindValue($name, $value);
    16.         }
    17.         return $stmt;
    18.     }
    19. }
    Конфигурируем в config/db.php:
    PHP:
    1. return [
    2.     'config' => [
    3.         'pdo' => [
    4.             'dsn' => getenv('DB_DSN'),
    5.             'username' => getenv('DB_USERNAME'),
    6.             'password' => getenv('DB_PASSWORD'),
    7.         ],
    8.     ],
    9.     PDO::class => static function (ContainerInterface $container) {
    10.         $config = $container->get('config')['pdo'];
    11.         return new PDO($config['dsn'], $config['username'], $config['password'], [
    12.             PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    13.             PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    14.         ]);
    15.     },
    16.     DB::class => static function (ContainerInterface $container) {
    17.         return new DB($container->get(PDO::class));
    18.     },
    19. ];
    Используем его в модели чтения:
    PHP:
    1. class PostsFetcher
    2. {
    3.     private $db;
    4.  
    5.     public function __construct(DB $db) {
    6.         $this->db = $db;
    7.     }
    8.  
    9.     public function all(): array {
    10.         $stmt = $this->db->query('SELECT * FROM posts ORDER BY date DESC');
    11.         return $stmt->fetchAll();
    12.     }
    13.  
    14.     public function findBySlug(string $slug): ?array  {
    15.         $stmt = $this->db->query('SELECT * FROM posts WHERE slug = :slug', [':slug' => $slug]);
    16.         return ($row = $stmt->fetch()) ? $row : null;
    17.     }
    18. }
    Выводим посты в контроллере:
    PHP:
    1. class PostsController
    2. {
    3.     private $posts;
    4.  
    5.     public function __construct(PostsFetcher $posts)  {
    6.         $this->posts = $posts;
    7.     }
    8.     public function index(Request $request, Response $response): Response {
    9.         $posts = $this->posts->all();
    10.         return $response->withJson($posts);
    11.     }
    12.     public function show(Request $request, Response $response, array $args): Response {
    13.         if (!$post = $this->posts->findBySlug($args['slug'])) {
    14.             return $response->withJson([], 404);
    15.         }
    16.         return $response->withJson($post);
    17.     }
    18. }
    Собираем сайт:
    PHP:
    1. $container = new Slim\Container(array_merge_recursive(
    2.     require 'config/slim.php',
    3.     require 'config/db.php'
    4. ));
    5.  
    6. $app = new Slim\App($container);
    7.  
    8. $app->get('/posts', [PostsController::class, 'index']);
    9. $app->get('/posts/{slug}', [PostsController::class, 'show']);
    10.  
    11. $app->run();
    И всё работает. Без синглтонов и статики.
    Смог.
     
    #32 ElisDN, 24 июн 2019
    Последнее редактирование: 24 июн 2019
    Дюран и Dimon2x нравится это.
  8. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    Да ты Капитан очевидность, класс в классе. Пост выше прочти.

    За конфиг лайк.
     
  9. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    А что там интересного? Потенциальное неиспользование реализуется lazy-сервисами для отложенного подключения.
     
    #34 ElisDN, 24 июн 2019
    Последнее редактирование: 24 июн 2019
  10. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Нарисовал тестируемый код без лапшекодного смешения ответственностей, синглтонов и статики. Проверяй, солнышко наше ясное.
     
    Дюран нравится это.
  11. teanrus

    teanrus Новичок

    С нами с:
    11 июн 2019
    Сообщения:
    6
    Симпатии:
    0
    Я думаю что гораздо лучше использовать конструкцию типа
    Код (Text):
    1. require_once($_SERVER[DOCUMENT_ROOT]."/cfg/config.php");
    или же (что гораздо удобнее будет в дальнейшем) конструкцию типа:
    Код (Text):
    1. define ("CFGPATH", $_SERVER[DOCUMENT_ROOT].'/cfg/');
    и далее в нужном месте:
    Код (Text):
    1. include CFGPATH."config.php";
     
  12. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    Про то, что ты написал после.
    нафига оно тут ? если у автора обвертка, которую я оптимизировал без всякого дополнительного кода и сделал ее ( повторяться не буду, выше писал два раза ).
     
  13. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Как хотите. Любите глобальные синглтоны - используйте. Ваше дело.
     
  14. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    тут даже не в деле "люблю или нет". Конкретную ситуацию учитывай и исходя от нее выводи код без "лишнего".
     
  15. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    А тот конфиг это не это? Обработку исключений куда там всунуть?
     
  16. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Не это.
    Например, в middleware.
     
    #41 ElisDN, 24 июн 2019
    Последнее редактирование: 24 июн 2019
  17. teanrus

    teanrus Новичок

    С нами с:
    11 июн 2019
    Сообщения:
    6
    Симпатии:
    0
    По поводу Вашего кодя я ничего не сказал, я лишь имел ввиду, что у автора идет подключение внешнего файла относительного текущего. Я предложил подключение относительно корня сайта (тогда где бы не находилось подключение ссылка будет работать).
    А по поводу функции define, то использование ее скажем в конфигурации сайта как определение именованных констант (например для задания пути на определенные каталоги как то: images, css, js и т.д.) является на мой взгляд предпочтительнее.
     
  18. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Это не к вам был вопрос, а ко мне.
     
  19. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    DOCUMENT_ROOT не прокатит, так как входные скрипты для web, console и запуска тестов могут быть в разных папках. Так что при необходимости абсолютных путей используйте константу __DIR__. А при указании относительных путей во всех точках входа укажите корневую директорию проекта через chdir(dirname(__DIR__));
     
  20. Павел Голубцов

    Павел Голубцов Активный пользователь

    С нами с:
    4 мар 2019
    Сообщения:
    183
    Симпатии:
    4
    Создал для нужного мне теста в корне config.php с данными по структуре похожими как и в конфиге бд.
    Так что мне удумал сайт, он взял при выводе постов когда вызывается подключение к бд, подключил config из корня сайта да еще и закешировал хитро, что если удалить все равно он работает.
    Вот задумался путь надо прописывать как то полней.
    Или вот вопрос, а что плохого если конфиг бд, просто всунуть в класс подключения к бд?
     
  21. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    используешь *_once ? при подключении файлов
     
  22. Павел Голубцов

    Павел Голубцов Активный пользователь

    С нами с:
    4 мар 2019
    Сообщения:
    183
    Симпатии:
    4
    да, но тут то не в этом дело а то что если в классе $config = require_once 'config.php';
    и создать в корне сайта файл config.php то он его может подключить вместо, который в корне класса.
    Сделал вот так:
    PHP:
    1. private function config()
    2.     {
    3.         return
    4.         [
    5.         'host' => 'localhost',
    6.         'db_name' => 'users',
    7.         'username' => 'root',
    8.         'password' => '',
    9.         'charset' => 'utf8',
    10.         ];
    11.     }
    12.    
    13.     private function connect()
    14.     {
    15.         $config = $this -> config();
     
  23. teanrus

    teanrus Новичок

    С нами с:
    11 июн 2019
    Сообщения:
    6
    Симпатии:
    0
    я обычно использую вот такой класс
    PHP:
    1. class MyDB
    2. {
    3. var $dblogin = "root"; // ЛОГИН К БАЗЕ ДАННЫХ
    4. var $dbpass = "pass"; // ПАРОЛЬ К БАЗЕ ДАННЫХ
    5. var $db = "dbname"; // НАЗВАНИЕ БАЗЫ
    6. var $dbhost="host";
    7. var $link;
    8. var $query;
    9. var $err;
    10. var $result;
    11. var $data;
    12. var $fetch;
    13.  
    14. function connect() {
    15. $this->link = mysql_connect($this->dbhost, $this->dblogin, $this->dbpass);
    16. mysql_select_db($this->db);
    17. mysql_query('SET NAMES utf8');
    18. }
    19. function close() {
    20. mysql_close($this->link);
    21. }
    22. function run($query) {
    23. $this->query = $query;
    24. $this->result = mysql_query($this->query, $this->link);
    25. $this->err = mysql_error();
    26. }
    27. function row() {
    28. $this->data = mysql_fetch_assoc($this->result);
    29. }
    30. function fetch() {
    31. while ($this->data = mysql_fetch_assoc($this->result)) {
    32. $this->fetch = $this->data;
    33. return $this->fetch;
    34. }
    35. }
    36. function stop() {
    37. unset($this->data);
    38. unset($this->result);
    39. unset($this->fetch);
    40. unset($this->err);
    41. unset($this->query);
    42. }
    43. }
    Хочу услышать ваше мнение по этому поводу.
     
    #48 teanrus, 25 июн 2019
    Последнее редактирование: 25 июн 2019
  24. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.553
    Симпатии:
    1.754
    @teanrus
    • Синтаксис php 4, когда на дворе 7.3 - беееееееееее
    • Расширение mysql, устаревшее 6 лет назад - беееееееееее
    • Отсутствие средств для облегчения экранирования - бееееееее
     
  25. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.745
    Симпатии:
    1.321
    Адрес:
    Лень
    Мне до сих пор интересно что все не увидели ошибку @ElisDN , при написании БД, а точнее метода query. Хотя это мелочь как по мне и при тесте все образуется
     
  26. ElisDN

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

    С нами с:
    13 фев 2018
    Сообщения:
    605
    Симпатии:
    130
    Это не баг, а фича.