За последние 24 часа нас посетил 22081 программист и 1153 робота. Сейчас ищут 347 программистов ...

Зависимости классов

Тема в разделе "Прочие вопросы по PHP", создана пользователем Vladbara705, 5 июл 2019.

Метки:
  1. Vladbara705

    Vladbara705 Новичок

    С нами с:
    30 июн 2019
    Сообщения:
    7
    Симпатии:
    0
    Есть код для работы сервера на сокетах:

    Код (Text):
    1. <?php
    2. require_once __DIR__ . '../../vendor/autoload.php';
    3. use Workerman\Worker;
    4. use Server\Mysql;
    5. use Server\Logger;
    6. use Server\DataInterface;
    7. use Server\LoggerInterface;
    8. use Workerman\Lib\Timer;
    9. class Server
    10. {
    11.     private $users;
    12.     private $db;
    13.     private $mysql;
    14.     public function __construct(DataInterface $mysql, LoggerInterface $logger)
    15.     {
    16.         $this->ws_worker = new Worker("websocket://127.0.0.1:8000");
    17.         $this->mysql = $mysql;
    18.         $this->logger = $logger;
    19.     }
    20.     public function serverStart()
    21.     {
    22.         $this->users = [];
    23.         $this->ws_worker->count = 4;
    24. /*
    25. * Стартуем сервер и пингуем БД каждую минуту, что бы сохранить подключение
    26. *
    27. */
    28.         $this->ws_worker->onWorkerStart = function() {
    29.             $this->logger->save(date("H:m:s"),'Service', 'Сервер запущен');
    30.             $time_interval = 60;
    31.             $timer_id = Timer::add($time_interval, function() {
    32.                 $result = $this->mysql->ping();
    33.             });
    34.         };
    35. /*
    36. * При получении сообщения записываем его в БД и рассылаем пользователям
    37. *
    38. */
    39.         $this->ws_worker->onMessage = function($connection, $data) use (&$users) {
    40.             $data = json_decode($data);
    41.             $this->mysql->save('chat',array('time','name','text'),array($data->time,$data->name,$data->message));
    42.             $data = json_encode($data);
    43.             foreach ($this->users as $value) {
    44.                 $value->send($data);
    45.             }
    46.         };
    47. /*
    48. * При новом подключении уведомляем пользователей, достаем старые сообщения, пишем в лог
    49. *
    50. */
    51.         $this->ws_worker->onConnect = function ($connection) use (&$users) {
    52.             $connection->onWebSocketConnect = function ($connection) use (&$users) {
    53.                 $this->logger->save(date("H:m:s"),'Service', 'Пользователь присоединился');
    54.                 $result = $this->mysql->select('chat','time,name,text');
    55.                 $result = json_encode(['dialog' => $result]);
    56.                 $this->users[$connection->id] = $connection;
    57.                 $this->users[$connection->id]->send($result);
    58.                 foreach ($this->users as $value) {
    59.                     $service = json_encode(['service' => 'Пользователь присоединился.']);
    60.                     $value->send($service);
    61.                 }
    62.             };
    63.         };
    64. /*
    65. * При отключении уведомляем пользователей и пишем в лог
    66. *
    67. */
    68.         $this->ws_worker->onClose = function($connection) use (&$users) {
    69.             $this->logger->save(date("H:m:s"),'Service', 'Пользователь отключился');
    70.             foreach ($this->users as $value) {
    71.                 $service = json_encode(['service' => 'Пользователь отключился.']);
    72.                 $value->send($service);
    73.             }
    74.         };
    75.         Worker::runAll();
    76.     }
    77. }
    78. $server = new Server(new MySql(new Logger(),'localhost','chat','root',''), new Logger());
    79. $server->serverStart();

    Вопрос следующий:

    Этот класс (Server) зависит от класса для работы с БД (Mysql), но класс Server может работать самостоятельно (без класса Mysql). Как ослабить эту зависимость?
     
  2. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    уверен ?
    --- Добавлено ---
    это даже, как сказать - глупое существенное "БЕЗ"
     
  3. Vladbara705

    Vladbara705 Новичок

    С нами с:
    30 июн 2019
    Сообщения:
    7
    Симпатии:
    0
    Это сервер на сокетах. Если оттуда убрать работу с бд - ничего не изменится. Может мы не понимаем друг друга?
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    у тебя скрипт работает с БД - все ВЗАИМОСВЯЗАННО
    --- Добавлено ---
    СМОТРИ КОД СВОЙ
    --- Добавлено ---
    MYSQL
    --- Добавлено ---
    ->mysql->
    --- Добавлено ---
    PHP:
    1. new MySql(new Logger(),'localhost','chat','root','')
    это не знает никто, кроме тебя - что там внутри
     
  5. Vladbara705

    Vladbara705 Новичок

    С нами с:
    30 июн 2019
    Сообщения:
    7
    Симпатии:
    0
    Ну, например, пропало у нас подключение к базе, чат будет работать.

    Разве правильно, что класс сервер напрямую взаимодействует с Mysql и логгером ? Не нужна ли там прослойка в виде еще одного класса в который все будет аккумулироваться из класса server и в котором будет работа с бд и логгером ?
    --- Добавлено ---
    Код (Text):
    1. <?php
    2. declare(strict_types = 1);
    3. namespace Server;
    4. use Server\DataInterface;
    5. use Server\Logger;
    6. use Server\LoggerInterface;
    7. /*
    8. * Сделал небольшую обертку для запросов.
    9. * Здесь так же пишутся в лог события. Обертку можно еще сильно доработать :)
    10. */
    11. class MySql implements DataInterface
    12. {
    13.     private $db;
    14.     public function __construct(LoggerInterface $logger, $host,string $dbname, string $user, string $password)
    15.     {
    16.         $this->logger = $logger;
    17.         try {
    18.             $this->db = new \PDO("mysql:host=$host;dbname=$dbname", $user, $password);
    19.             $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
    20.             $this->db->exec("set names utf8");
    21.             $this->logger->save(date("H:m:s"),'Service', 'Подключились к Mysql.');
    22.             return '</br>Подключились к Mysql.</br>';
    23.         } catch(PDOException $e) {
    24.             $this->logger->save(date("H:m:s"),'Service', 'При подключении к Mysql возникла ошибка.');
    25.             return '</br>При подключении к Mysql возникла ошибка: '. $e->getMessage().'</br>';
    26.         }
    27.     }
    28. /*
    29. * Запрос для пинга в базу
    30. *
    31. */
    32.     public function ping() : string
    33.     {
    34.         try {
    35.             $ping = $this->db->query('SELECT 1');
    36.             $ping->setFetchMode(\PDO::FETCH_ASSOC);
    37.             if ($ping->fetch()) {
    38.                 $this->logger->save(date("H:m:s"),'Service', 'Запрос к Mysql был отправлен (ПИНГ)');
    39.                 return '</br>Запрос к Mysql был отправлен (ПИНГ).</br>';
    40.             }
    41.         } catch(PDOException $e) {
    42.             $this->logger->save(date("H:m:s"),'Service', 'Во время пинга Mysql возникла ошибка');
    43.                 return '</br>Во время пинга Mysql возникла ошибка: '. $e->getMessage().'</br>';
    44.         }
    45.     }
    46. /*
    47. * Сохранения данных.
    48. * 1 параметр - таблица, остальные 2 массива - поля и их значения
    49. */
    50.     public function save(string $table,array $field, array $value)
    51.     {
    52.         $fieldString = implode(',', $field); // превращаем массив в строку
    53.         array_walk($field, function (&$arr) {
    54.             $arr = ':'.$arr;
    55.         });
    56.         $valueString = implode(',', $field);
    57.         try {
    58.             $stmt = $this->db->prepare("INSERT INTO $table ($fieldString) VALUES ($valueString)");
    59.             foreach ($field as $key => $value1) {
    60.                 $stmt->bindParam($field[$key], $value[$key]);
    61.             }
    62.             $stmt->execute();
    63.             $this->logger->save(date("H:m:s"),'Service', 'Сообщение сохранено в Mysql.');
    64.             return '</br>Сообщение сохранено в Mysql.</br>';
    65.         } catch(PDOException $e) {
    66.             $this->logger->save(date("H:m:s"),'Service', 'Во время записи в Mysql произошла ошибка.');
    67.             return '</br>Во время записи в Mysql произошла ошибка.</br>';
    68.         }
    69.     }
    70. /*
    71. * Выборка из БД
    72. * 1 параметр - таблица, затем список полей, условие выборки, значения выборки
    73. * Последний параметр можно использовать для написания собственного запроса
    74. */
    75.     public function select(string $table, $field, string $where = NULL, string $value = NULL, string $query = NULL)
    76.     {
    77.         try {
    78.             if ($query == NULL) {
    79.                 if (is_array($field)) {
    80.                     $field = implode(',', $field); // превращаем массив в строку
    81.                 }
    82.                 $stmt = "SELECT $field FROM $table ";
    83.                 if ($where != NULL and $value != NULL) {
    84.                     $stmt.= "WHERE $where = ?";
    85.                 }
    86.                 $stmt = $this->db->prepare($stmt);
    87.                 $stmt->bindValue(1, $value);
    88.                 $stmt->execute();
    89.                 $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
    90.                 return $rows;
    91.             } else {
    92.                 $stmt = $this->db->query($query);
    93.                 $rows = $stmt->fetchAll();
    94.                 return $rows;
    95.             }
    96.         } catch(PDOException $e) {
    97.             $this->logger->save(date("H:m:s"),'Service', 'Во время запроса в Mysql произошла ошибка.');
    98.             return '</br>Во время запроса в Mysql произошла ошибка.</br>';
    99.         }
    100.     }

    Вот, надо только работу с логгером отсюда убрать :)
     
  6. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.750
    Симпатии:
    1.322
    Адрес:
    Лень
    включи все ошибки
     
  7. Vladbara705

    Vladbara705 Новичок

    С нами с:
    30 июн 2019
    Сообщения:
    7
    Симпатии:
    0
    Я не понимаю к чему ты ведешь. :)
    С точки зрения архитектуры правильно построен класс Server или нет? :)
     
  8. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.823
    Симпатии:
    736
    Адрес:
    Татарстан
    имхо -
    не айс
     
  9. Vladbara705

    Vladbara705 Новичок

    С нами с:
    30 июн 2019
    Сообщения:
    7
    Симпатии:
    0
    а какой еще способ есть ?
    почему этот метод не айс ? ведь он вообще никак не нагружает сервак :)
    конечно, можно время и побольше поставить. например, 2 минуты