За последние 24 часа нас посетили 17853 программиста и 1703 робота. Сейчас ищут 1764 программиста ...

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

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

  1. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Это для меня не очень делает смысл :)
    Класс не может быть статик или не статик, статическими могут быть свойства и методы класса.
    Инстанс это экземпляр класса, инстанцирование это создание экземпляра класса. Статические свойства и методы позволяют обращаться к ним без создания экземпляра класса.
     
  2. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Собственно, в статье приводится пример синглтона, в котором возвращается копия(не копия) статического свойства
    PHP:
    1.    public static function get_instance() {
    2.       if ( ! isset( self::$instance ) ) {
    3.          self::$instance = new self();
    4.       }
    5.  
    6.       return self::$instance;
    7.    }
    Я склоняюсь к такому подходу с синглтоном:
    PHP:
    1. class DB
    2. {
    3. private static $connection;
    4. private function connect()
    5. {
    6.     if(!(self::$connection instanceof ...))
    7.     {
    8.     self::$connection = ...; // подключение к БД
    9.     }
    10. }
    11. final protected function query($query,...)
    12. {
    13.      $this->connect();
    14.      //выполнение запроса и все такое
    15. }
    16. }
    17.  
    18. class myDB extends DB
    19. {
    20.     public function my_function()
    21.     {
    22.     ...
    23.     $this->query('...');
    24.     ...
    25.     }
    26. }
    27.  
    28. $abc = new myDB();
    29. $abc->my_function();
    Это тоже говнофича?
     
    #52 Maputo, 28 ноя 2017
    Последнее редактирование: 28 ноя 2017
  3. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    @keren, здесь говорится о том (и @Fell-x27 достаточно хорошо аргументировал свою позицию), что, хотя php позволяет смешивать в одном классе статику и не-статику, это не является хорошей практикой программирования. Т.е. либо у тебя класс, предназначенный для того, чтоб создавались его экземпляры (объекты), и тогда в нём нет статики, либо у тебя утилитный класс, в котором всё статика, и тогда ты не создаёшь его объекты.

    @Maputo, насколько я понял нескольких лекторов, синглтоны нужно создавать через DI-контейнеры и Service Locator. Хотя сам я делаю обычные синглтоны, если проект не слишком сложный.
     
  4. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @mkramer, впринципе в статье рассмотрены хорошие альтернативы. Но сам "плохой" синглтон рассматривается в довольно частном случае.
     
  5. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Нехорошая практика это не смешивание статики и нестатики в классе, а статическое обращение к не статическим свойствам и методам класса. Те прежде чем обратится к чему либо статически нужно сделать статическим то к чему обращаешься, но от куда обращаешься не обязательно должно быть статическим.
     
    #55 keren, 28 ноя 2017
    Последнее редактирование: 28 ноя 2017
  6. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.583
    Симпатии:
    1.761
    Не, это не нехорошая практика, это баг php, который устранили. А вот смешивание статики и не статики имеет действительно описанные @Fell-x27 недостатки, а именно
     
  7. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Но там в альтернативу привели вордпресс но он процедурный и вовсю использует глобальные переменные.
     
  8. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    WP в этой статье не альтернатива, а скорее источник бед.
     
  9. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Задача, создать input с помощью ООП:

    PHP:
    1. echo $form->input(['type'=>'text', 'value'=>'!!!']);
    2. //Код выше выведет <input type="text" value="!!!">
    Правильно ли сделал, есть ли по лучше решение?

    PHP:
    1. <?php
    2.     error_reporting(E_ALL);
    3.  
    4.     class Form {
    5.         private $type ;
    6.         private $value;
    7.      
    8.         public function input($arr) {
    9.             $this->type = $arr['type'];
    10.             $this->value = $arr['value'];
    11.          
    12.             return '<input type="' .$this->type . '" value="' .$this->value . '">';
    13.         }
    14.     }
    15.  
    16.     $form = new Form;
    17.     echo $form->input(['type'=>'text', 'value'=>'!!!']);
    18. ?>
     
  10. mahmuzar

    mahmuzar Старожил

    С нами с:
    6 апр 2012
    Сообщения:
    4.631
    Симпатии:
    425
    Адрес:
    РД, г. Махачкала.
    Это уже не ООП это просто ты используешь объекты)). Верстку лучше оставить на своем месте, а объекту формы отдавать данные которые пришли на обработку)
     
    Dimon2x нравится это.
  11. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    @Dimon2x input без name бесполезен, а вот под каждый type можно и отдельный класс
    PHP:
    1. use Zend\Form\Element;
    2. use Zend\Form\Form;
    3.  
    4. $text = new Element\Text('firstName');
    5. $text->setLabel('Enter your name');
    6.  
    7. $form = new Form('my-form');
    8. $form->add($text);
     
    Dimon2x нравится это.
  12. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    PHP:
    1. <?php
    2.     error_reporting(E_ALL);
    3.    
    4.     class Form {
    5.         private $type ;
    6.         private $value = '';
    7.         private $placeholder;
    8.         private $action = '';
    9.         private $method;
    10.         private $name;
    11.         private $className;
    12.        
    13.         public function checkValue($arr) {
    14.             if (array_key_exists('value', $arr)) {
    15.                 $this->value = $arr['value'];
    16.             }
    17.         }
    18.        
    19.         public function checkName($arr) {
    20.             if (array_key_exists('name', $arr)) {
    21.                 $this->name = 'name="'.$arr['name'].'"';
    22.             }
    23.         }
    24.        
    25.         public function checkClass($arr) {
    26.             if (array_key_exists('class', $arr)) {
    27.                 $this->className = 'class="' . $arr['class'] . "\" ";
    28.             }
    29.         }
    30.        
    31.         public function input($arr) {
    32.             $this->type = $arr['type'];
    33.             $this->checkName($arr);
    34.             $this->checkValue($arr);
    35.             $this->checkClass($arr);
    36.             return '<input ' . $this->className . $this->name . ' type="' .$this->type . '" value="' .$this->value . '">';
    37.         }
    38.        
    39.         public function password($arr) {
    40.             $this->type = 'password';
    41.             $this->checkName($arr);
    42.             $this->checkValue($arr);
    43.             $this->checkClass($arr);
    44.            
    45.             return '<input '. $this->className . $this->name .' type="' .$this->type . '" value="' .$this->value . '">';
    46.         }
    47.        
    48.         public function submit($arr) {
    49.             $this->type = 'submit';
    50.             $this->checkName($arr);
    51.             $this->checkValue($arr);
    52.             $this->checkClass($arr);
    53.             return '<input ' . $this->className . $this->name .' type="' .$this->type . '" value="' .$this->value . '">';
    54.         }
    55.        
    56.         public function textarea($arr) {
    57.             $this->placeholder = $arr['placeholder'];
    58.             $this->name = $arr['name'];
    59.             $this->checkValue($arr);
    60.             $this->checkClass($arr);
    61.             return '<textarea ' . $this->className . $this->name . ' placeholder="' . $this->placeholder. '">' . $this->value . '</textarea>';
    62.         }
    63.        
    64.         public function open($arr) {
    65.             $this->action = $arr['action'];
    66.             $this->method = $arr['method'];
    67.             $this->checkClass($arr);
    68.             return '<form '.$this->className.' action="'.$this->action.'" method="'.$this->method.'">';
    69.         }
    70.        
    71.         public function close() {
    72.             return '</form>';
    73.         }
    74.     }
    75.    
    76.     $form = new Form;
    77.    
    78.     echo $form->open(['action'=>'index.php', 'method'=>'POST']) . "\n";
    79.     echo "\t ". $form->input(['type'=>'text', 'placeholder'=>'Ваше имя', 'name'=>'name', 'class'=>'name']) . "\n";
    80.     echo "\t ". $form->password(['placeholder'=>'Ваш пароль', 'name'=>'pass', 'class'=>'user-password']) . "\n";
    81.     echo "\t ". $form->submit(['value'=>'Отправить']) . "\n";
    82.     echo $form->close();
    83.    
    84. ?>
     
  13. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Не понимаю, я создал класс, который всё наследует от класса Form и почему, если после отправки, не сохраняется значение в input name?

    PHP:
    1. class SmartForm extends Form {
    2.    
    3.         public function checkValue($arr) {
    4.            
    5.             if(!empty($_POST['name'])) {
    6.                  $this->value = $_POST['name'];
    7.             }
    8.             parent::checkValue($arr);
    9.         }
    10.     }
    11.    
    12.     $form2 = new SmartForm;
    13.    
    14.     echo $form2->open(['action'=>'./2.php', 'method'=>'POST']) . "\n";
    15.     echo "\t ". $form2->input(['type'=>'text', 'placeholder'=>'Ваше имя', 'name'=>'name', 'class'=>'name']) . "\n";
    16.     echo "\t ". $form2->password(['placeholder'=>'Ваш пароль', 'name'=>'pass', 'class'=>'user-password']) . "\n";
    17.     echo "\t ". $form2->submit(['value'=>'Отправить']) . "\n";
    18.     echo $form2->close();
     
  14. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Если Вы хотите в дочернем классе использовать какие-либо скрытые свойства - им надо ставить область видимости protected, а не private.
    Еще есть DOM-элементы в php для создания таких вещей.
     
    Dimon2x нравится это.
  15. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Я изменил на protected. Теперь другая проблема, в value почему-то сохраняется значение, почему, если я его удаляю?

    В поле name и password будут одинаковые значения

    PHP:
    1.     class SmartForm extends Form {
    2.    
    3.         public function delValue() {
    4.             $this->value = null;
    5.         }
    6.    
    7.          public function checkValue($arr) {
    8.             echo '<pre>';
    9.                 print_r($_POST);
    10.             echo '</pre>';
    11.             if(!empty($_POST['name'])) {
    12.                 $this->value = $_POST['name'];
    13.             }
    14.            
    15.             if(!empty($_POST['pass'])) {
    16.                 $this->value = $_POST['pass'];
    17.             }
    18.            
    19.             parent::checkValue($arr);
    20.         }
    21.     }
    22.    
    23.    
    24.     $form2 = new SmartForm;
    25.    
    26.     echo $form2->open(['action'=>'./2.php', 'method'=>'POST']) . "\n";
    27.     echo "\t ". $form2->input(['type'=>'text', 'placeholder'=>'Ваше имя', 'name'=>'name', 'class'=>'name']) . "\n";
    28.     echo "\t ". $form2->password(['placeholder'=>'Ваш пароль', 'name'=>'pass', 'class'=>'user-password']) . "\n";
    29.     echo "\t ". $form2->submit(['value'=>'Отправить']) . "\n";
    30.     echo $form2->close();
     
  16. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    Вы пытаетесь переопределить родительский метод, но при этом его явно не вызываете в коде. А вызываете родительские методы, которые вызывают свои непереопределенные методы. И я так и не нашел где используется delValue()?
     
  17. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @Maputo
    PHP:
    1. public function password($arr) {
    2.             $this->type = 'text';
    3.             $this->checkName($arr);
    4.             $this->delValue();
    5.             $this->checkValue($arr);
    6.             $this->checkClass($arr);
    7.            
    8.             return '<input '. $this->className . $this->name .' type="' .$this->type . '" value="' .$this->value . '">';
    9.         }
    --- Добавлено ---
    Вообще не понимаю, почему после отправки, в значения подставляется Отправить?

    PHP:
    1. class SmartForm extends Form {
    2.          public function checkValue($arr) {
    3.            
    4.             if(!empty($_POST['pass'])) {
    5.                 $this->value = $_POST['pass'];
    6.             }
    7.            
    8.              parent::checkValue($arr);
    9.         }
    10.     }
    11.    
    12.    
    13.     $form2 = new SmartForm;
    14.    
    15.     echo $form2->open(['action'=>'./2.php', 'method'=>'POST']) . "\n";
    16.     echo "\t ". $form2->input(['type'=>'text', 'placeholder'=>'Ваше имя', 'name'=>'name', 'class'=>'name']) . "\n";
    17.     echo "\t ". $form2->password(['placeholder'=>'Ваш пароль', 'name'=>'pass', 'class'=>'user-password']) . "\n";
    18.     echo "\t ". $form2->submit(['value'=>'Отправить']) . "\n";
    19.     echo $form2->close();
    --- Добавлено ---
    Почему я его не использую, я же его переопределил?
    --- Добавлено ---
    ВооНе понимаю, почему после отправки, в значения подставляется Отправить?
    А как его вызвать в коде?
     
  18. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @Dimon2x, когда Вы вызываете родительский метод, внутри которого есть checkValue - этот самый checkValue берется из родительского класса, а не из дочернего. То что Вы пытаетесь реализовать - решается с помощью "контекста" или еще чего. В крайнем случае нужно определить поточнее какие методы должны быть определены в родительском классе, а какие в дочернем.
    Ну и посмотрите сами - насколько выгодно использовать такие классы? Не проще ли организовать это с помощью старого доброго html?
    Хотите потренироваться с классами и генерацией html - попробуйте сделать класс для создания таблиц из двумерных массивов, чтобы код с использованием класса выглядел так:
    PHP:
    1. $table = new Table($two_dimensional_array);
    2. echo $table;
     
  19. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @Maputo Мне же надо, как-то учить ООП.
    --- Добавлено ---
    Почему берется из родительского класса, а не из дочернего? Я же переопределил.
     
  20. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @Dimon2x, ООП нужно учить так как его будете в дальнейшем применять. ООП - для удобства придумали, а не для того, чтобы отделить "хороших" программистов от "плохих".
    Потому что Вы вызываете в коде родительские методы. Если бы Вы еще переопределили и методы input(), password() и submit() - вызывался бы дочерний метод.
    Rem.: одного переопределения мало - нужно использовать вызов дочернего метода внутри переопределенных методов.
     
  21. Sail

    Sail Старожил

    С нами с:
    1 ноя 2016
    Сообщения:
    1.593
    Симпатии:
    362
    Навели тень на плетень...
    @Dimon2x
    Если создается объект наследника (smartForm) - то из методов базового (Form) класса (input и прочие в этом примере) посредством $this->checkValue() вызывается именно метод класса smartForm, раз уж checkValue переопределен, а не базового (Form). Для этого не надо переопределять в наследнике методы input и другие.
    В данном случае метод checkValue был не столько переопределен, сколько дополнен... и в нем присутствует явный вызов метода из класса-родителя (parent::checkValue). Надо определиться - нужен этот вызов вообще, и если нужен - то до кода из класса smartForm, или после.
     
    Maputo нравится это.
  22. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    @Sail он нужен после условия, потому что в условии задаётся значение для value и потом уже идёт проверка в checkValue, что value не пуста и надо подставить в значение

    PHP:
    1. class Form {
    2.         protected $value;
    3.      
    4.         public function checkValue($arr) {
    5.             if (array_key_exists('value', $arr)) {
    6.                 $this->value = $arr['value'];
    7.             }
    8.         }
    PHP:
    1. public function input($arr) {
    2.             $this->type = $arr['type'];
    3.             $this->checkName($arr);
    4.             $this->checkValue($arr);
    5.             $this->checkClass($arr);
    6.             return '<input ' . $this->className . $this->name . ' type="' .$this->type . '" value="' .$this->value . '">';
    7.         }
    PHP:
    1. class SmartForm extends Form {
    2.          public function checkValue($arr) {
    3.             if(!empty($_POST['name'])) {
    4.                 $this->value = $_POST['name'];
    5.             }
    6.            
    7.              return parent::checkValue($arr);
    8.         }
    9.     }
    Только почему то не работает
     
  23. Maputo

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

    С нами с:
    30 июл 2015
    Сообщения:
    1.136
    Симпатии:
    173
    @Sail, да. Вы правы. То что я описал не относится к этой ситуации. Это происходит только при попытке переопределить приватные родительские методы.
     
  24. [vs]

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

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    На самом деле, генерация форм - это полезный инструмент, и он включен во многие фреймворки. И как правило, там же валилация, токены против csrf и тд
     
  25. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.210
    Симпатии:
    185
    Почему после отправки, в ключ [password] попадает значение отправить, как такое возможно?

    PHP:
    1. <?php
    2.     error_reporting(E_ALL);
    3.    
    4.     class Form {
    5.         protected $type ;
    6.         protected $value;
    7.         protected $placeholder;
    8.         protected $action = '';
    9.         protected $method;
    10.         protected $name;
    11.        
    12.         public function checkValue($arr) {
    13.             if (array_key_exists('value', $arr)) {
    14.                 $this->value = $arr['value'];
    15.             }
    16.         }
    17.        
    18.         public function checkName($arr) {
    19.             if (array_key_exists('name', $arr)) {
    20.                 $this->name = 'name="'.$arr['name'].'"';
    21.             }
    22.         }
    23.        
    24.         public function input($arr) {
    25.             $this->type = $arr['type'];
    26.             $this->checkName($arr);
    27.             $this->checkValue($arr);
    28.             return '<input ' . $this->name . ' type="' .$this->type . '" value="' .$this->value . '">';
    29.         }
    30.        
    31.         public function password($arr) {
    32.             $this->type = 'text';
    33.             $this->checkName($arr);
    34.             $this->checkValue($arr);
    35.             return '<input '. $this->name .' type="' .$this->type . '" value="' .$this->value . '">';
    36.         }
    37.        
    38.         public function submit($arr) {
    39.             $this->type = 'submit';
    40.             $this->checkName($arr);
    41.             $this->checkValue($arr);
    42.             return '<input '  . $this->name .' type="' .$this->type . '" value="' .$this->value . '">';
    43.         }
    44.        
    45.         public function open($arr) {
    46.             $this->action = $arr['action'];
    47.             $this->method = $arr['method'];
    48.             return '<form action="'.$this->action.'" method="'.$this->method.'">';
    49.         }
    50.        
    51.         public function close() {
    52.             return '</form>';
    53.         }
    54.     }
    55.    
    56.    
    57.     class SmartForm extends Form {
    58.    
    59.          public function checkValue($arr) {
    60.             if(!empty($_POST['password'])) {
    61.                 echo '<pre>';
    62.                     print_r($_POST);
    63.                 echo '</pre>';
    64.                
    65.                 $this->value = $_POST['password'];
    66.             }
    67.            
    68.              return parent::checkValue($arr);
    69.         }
    70.     }
    71.    
    72.    
    73.     $form2 = new SmartForm;
    74.    
    75.     echo $form2->open(['action'=>'./2.php', 'method'=>'POST']) . "\n";
    76.     echo "\t ". $form2->input(['type'=>'text', 'placeholder'=>'Ваше имя', 'name'=>'name', 'class'=>'name']) . "\n";
    77.     echo "\t ". $form2->password(['placeholder'=>'Ваш пароль', 'name'=>'password', 'class'=>'user-password']) . "\n";
    78.     echo "\t ". $form2->submit(['value'=>'Отправить']) . "\n";
    79.     echo $form2->close();
    80. ?>