За последние 24 часа нас посетили 92620 программистов и 5579 роботов. Сейчас ищут 1942 программиста ...

Нужен совет

Тема в разделе "PHP для новичков", создана пользователем Slash_gnr, 3 окт 2016.

  1. Slash_gnr

    Slash_gnr Новичок

    С нами с:
    21 сен 2016
    Сообщения:
    6
    Симпатии:
    0
    Друзья, нужен ваш совет. Имеются 3 класса для логирования сообщений(в файл, в базу данных и stdout). Нужно каким то образом применить наследование к этим классам. Проглядываются общие черты, но объеденить это всё не удаётся. Надеюсь на вашу помощь
    PHP:
    1. class LogFile
    2. {
    3.     protected $path_to_file;
    4.     private function __construct($path_to_file)
    5.     {
    6.         $this->path_to_file = $path_to_file;
    7.     }
    8.  
    9.     private function getDate()
    10.     {
    11.         return '[' . date("Y-m-d H:i:s") . ']';
    12.     }
    13.  
    14.     public function addLog($message)
    15.     {
    16.         if(gettype($message) == 'string'){
    17.             file_put_contents($this->path_to_file, self::getDate() .' '. $message . "\r\n", FILE_APPEND);
    18.         }
    19.         else if(gettype($message) == 'array'){
    20.             foreach ($message as $log){
    21.                 file_put_contents($this->path_to_file, self::getDate() .' '. $log . "\r\n", FILE_APPEND);
    22.             }
    23.         }
    24.         else if(gettype($message) == 'object'){
    25.             foreach ($message as $prop => $value){
    26.                 file_put_contents($this->path_to_file, self::getDate() .' '. $prop. ' => '. $value . "\r\n", FILE_APPEND);
    27.             }
    28.         }
    29.    
    30.     }
    31.     public function changePath($path){
    32.         $this->path_to_file = $path;
    33.     }
    34. }
    35.  
    36. class LogDB
    37. {
    38.     protected $host;
    39.     protected $dbname;
    40.     protected $tbname;
    41.     protected $login;
    42.     protected $password;
    43.     private function __construct($host, $dbname, $tbname, $login, $password)
    44.     {
    45.         $this->host = $host;
    46.         $this->dbname = $dbname;
    47.         $this->tbname = $tbname;
    48.         $this->login = $login;
    49.         $this->password = $password;
    50.     }
    51.  
    52.     private function getDate()
    53.     {
    54.         return '[' . date("Y-m-d H:i:s") . ']';
    55.     }
    56.     public function addLog($message)
    57.     {
    58.         $db = new PDO("mysql:host=$this->host; dbname=$this->dbName","$this->login", "$this->password");
    59.         if(gettype($message) == 'string') {
    60.             $db->query("INSERT INTO $this->tbName(date, message) VALUES('".self::getDate()."', '$message')");
    61.         }
    62.         else if(gettype($message) == 'array') {
    63.             foreach ($message as $item){
    64.                 $db->query("INSERT INTO $this->tbName(date, message) VALUES('".self::getDate()."', '$item')");
    65.             }
    66.         }
    67.         else if(gettype($message) == 'object'){
    68.             foreach ($message as $item => $value){
    69.                 $db->query("INSERT INTO $this->tbName(date, message) VALUES('".self::getDate()."', '$item : $value')");
    70.             }
    71.         }
    72.         $db = null;
    73.     }
    74.     public function changeConfig($host, $dbname, $tbname, $login, $password)
    75.     {
    76.         $this->host = $host;
    77.         $this->dbname = $dbname;
    78.         $this->tbname = $tbname;
    79.         $this->login = $login;
    80.         $this->password = $password;
    81.     }
    82. }
    83.  
    84. class LogSteam
    85. {
    86.     private function getDate(){
    87.         return '[' . date("Y-m-d H:i:s") . ']';
    88.     }
    89.     public function addLog($message)
    90.     {
    91.         $std = fopen('php://stdout', "a+");
    92.         if(gettype($message) == 'string'){
    93.             fwrite($std, self::getDate() . " " . $message . "\r\n");
    94.         }
    95.         else if(gettype($message) == 'array'){
    96.             foreach ($message as $item){
    97.                 fwrite($std, self::getDate() . " " . $item . "\r\n");
    98.             }
    99.         }
    100.         else if(gettype($message) == 'object'){
    101.             foreach ($message as $item => $value){
    102.                 fwrite($std, self::geDate() . " " . $item . " : " . $value . "\r\n");
    103.             }
    104.         }
    105.         fclose($std);
    106.     }
    107. }
     
  2. denis01

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

    С нами с:
    9 дек 2014
    Сообщения:
    12.213
    Симпатии:
    1.711
    Адрес:
    Молдова, г.Кишинёв
    С какой целью?
     
  3. Slash_gnr

    Slash_gnr Новичок

    С нами с:
    21 сен 2016
    Сообщения:
    6
    Симпатии:
    0
    Понимаете, это тестовое задание меня попросил сделать работодатель. В первом варианте я сделал абстрактный класс, дабы просто применить наследование (в задании сказано использовать объектно-ориентированный подход, я подумал что нужно использовать все его возможности :) ). Но меня попросили переделать с формулировкой "разобраться в наследовании". Лично мне кажется что в данном примере наследование не стоит применять, дабы не нагружать и без того простую систему. Но раз работодатель попросил, нужно выполнять)
     
  4. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    Ну так элементарно. Они все логируют, у всех есть абсолютно одинаковый метод getDate(), и у всех есть addMessage(), реализация которого меняется в зависимости от типа логирования. Получается достаточно простая картинка:
    upload_2016-10-3_16-34-6.png
    При этом у класса Loger getDate() - protected-метод, который используют наследники. A addMessage() - абстрактный, поэтому Logger (на картинке опечатка в названии, но не суть) - абстрактный класс. Делается для того, чтобы путём смены одной строки кода можно было выбирать, куда писать логи - в базу или в файл.
     
    Slash_gnr нравится это.
  5. Slash_gnr

    Slash_gnr Новичок

    С нами с:
    21 сен 2016
    Сообщения:
    6
    Симпатии:
    0
    Именно это я и делал в первой реализации)

    PHP:
    1. abstract class Loger {
    2.     abstract protected function getDate();
    3.  
    4.     abstract public function addLog($message);
    5. }
    Может быть в данном контексте разумнее было использовать интерфейс?
     
  6. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    А зачем getDate() абстрактная? Она же одинаково реализована во всех классах. Думаю, к этому и придрались. У меня на UML она не повторяется больше нигде
     
  7. Slash_gnr

    Slash_gnr Новичок

    С нами с:
    21 сен 2016
    Сообщения:
    6
    Симпатии:
    0
    Вполне может быть) К сожалению точной формулировки проблемы они не дали
     
  8. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    Ну а какой смысл повторять код getDate() во всех трёх классах? А ещё можно чуть-чуть модифицировать LogFile, и тогда от него можно будет унаследовать LogSteam:

    PHP:
    1. class LogFile extends Loger
    2. {
    3.     protected $path_to_file;
    4.     public function __construct($path_to_file)
    5.     {
    6.         $this->path_to_file = $path_to_file;
    7.     }
    8.  
    9.  
    10.    
    11.     public function addLog($message)
    12.     {
    13.         $std = fopen($this->path_to_file, "a+");
    14.         if(gettype($message) == 'string'){
    15.             fwrite($std, self::getDate() . " " . $message . "\r\n");
    16.         }
    17.         else if(gettype($message) == 'array'){
    18.             foreach ($message as $item){
    19.                 fwrite($std, self::getDate() . " " . $item . "\r\n");
    20.             }
    21.         }
    22.         else if(gettype($message) == 'object'){
    23.             foreach ($message as $item => $value){
    24.                 fwrite($std, self::geDate() . " " . $item . " : " . $value . "\r\n");
    25.             }
    26.         }
    27.         fclose($std);
    28.     }
    29.     public function changePath($path){
    30.         $this->path_to_file = $path;
    31.     }
    32. }
    33. class LogSteam extends LogFile {
    34.     public function __constuct() {
    35.          parent::__constuct("php://stdin");
    36.     }
    37.    
    38.  public function changePath($path){
    39.        throw new Exception();
    40.     }
    41. }
     
    Slash_gnr нравится это.
  9. Slash_gnr

    Slash_gnr Новичок

    С нами с:
    21 сен 2016
    Сообщения:
    6
    Симпатии:
    0
    Спасибо за помощь) Мне всё прояснилось)
     
  10. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.497
    Симпатии:
    1.726
    Ещё одна идея, кстати:
    PHP:
    1. class Logger {
    2.      
    3.     protected function getDate()
    4.     {
    5.         return '[' . date("Y-m-d H:i:s") . ']';
    6.     }
    7.    
    8.     abstract protected function writeMsg($msg);
    9.    
    10.     final public function addLog($msg)
    11.     {
    12.          
    13.          if(gettype($message) == 'string'){
    14.             $this->writeMsg($message)
    15.         }
    16.         else if(gettype($message) == 'array'){
    17.             foreach ($message as $item){
    18.                 $this->writeMsg(self::getDate() . " " . $item . "\r\n");
    19.             }
    20.         }
    21.         else if(gettype($message) == 'object'){
    22.             foreach ($message as $item => $value){
    23.                 $this->writeMsg(self::geDate() . " " . $item . " : " . $value . "\r\n");
    24.             }
    25.         }
    26.     }
    27. }
    Дальше сделаете? Опять же, чтоб ваши повторы кода сократить в разных классах.