За последние 24 часа нас посетили 22319 программистов и 1059 роботов. Сейчас ищут 684 программиста ...

PHP OOП статический метод

Тема в разделе "PHP для профи", создана пользователем Evgenij85, 12 фев 2018.

Метки:
  1. Abyss

    Abyss Старожил

    С нами с:
    12 дек 2015
    Сообщения:
    1.298
    Симпатии:
    218
    Адрес:
    Default city
    Да, так будет правильно. Но зачем вызывать статический метод, если он всё равно инициализирует объект ?
     
    Evgenij85 нравится это.
  2. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    та да согласен чтото здесь не так , я планировал создать статический метод без созданий обьектов , так как методы часто использую во вьюхах и обращаюсь напрямую , но получилось что все равно я создаю обьекты , всем спасибо буду разбираться с теорией ООП
     
  3. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    @Evgenij85, методы, используемые во вьюхах, выносят в отдельные классы, называемые хелперами. И в них обычно да, все методы статические
     
  4. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    а есть пример или где можно посмотреть как правильно создавать отдельные классы ?
     
  5. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    PHP:
    1. namespace app\helpers;
    2.  
    3.  
    4. use app\models\user\Service;
    5. use app\models\user\service\VendorService;
    6. use yii\helpers\Html;
    7.  
    8. class ShorteningHelper
    9. {
    10.    
    11. /**
    12. * @param Service $service
    13. *
    14. * @return string
    15. */
    16. public static function asphaltConcreteShort(Service $service): string
    17. {
    18.     $short = "АБС ";
    19.     $short .= str_replace(["мелкозернизстый", "крупнозернистый", "плотный", "пористый"], ["МЗ", "КЗ", "плот.", "пор"], mb_strtolower($service->sort, "utf-8")) . " ";
    20.     if (mb_strpos($service->sort, "пористый", 0, "utf-8") === false) {
    21.         $short .= "Тип$service->asphaltConcreteType ";
    22.     }
    23.     $short .= "М" . (array_search($service->asphaltConcreteMark, VendorService::ASPHALT_CONCRETE_MARKS) + 1);
    24.  
    25.     return $short;
    26. }
    27. /* .... */
    28. }
    Из моего проекта.
     
  6. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    У тебя view - это уже объект, при условии использования нормального фреймворка. В этот объект ты можешь засунуть функцию получения объекта хелпера.
    Причем хэлпер тоже можно объектом хранить.
    В шаблоне приведенный выше пример можно использовать так:
    PHP:
    1. <? /** $var View $this **/?>
    2. <?= $this->getShorteningHelper()->asphaltConcreteShort($service) ?>
    А сам ShorteningHelper получать либо ленивой загрузкой, либо в конструкторе.
     
  7. Evgenij85

    Evgenij85 Новичок

    С нами с:
    20 сен 2017
    Сообщения:
    48
    Симпатии:
    0
    спасибо
    Спасибо
     
  8. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Только ради этого переопределять View? Да ну :)
     
  9. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    А что в этом такого? Статику вообще вредно использовать.
     
  10. mkramer

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

    С нами с:
    20 июн 2012
    Сообщения:
    8.554
    Симпатии:
    1.754
    Ну в хелперах - нормально, это ограниченное использование. Не просто же так в язык ввели эту фитчу. А так, представляешь во что класс View превратится?
    Конечно, как вариант, сделать так:
    PHP:
    1. $this->getHelper("shrotening")->asphaltConcreteShort($short);
    , тогда не такой трындец будет, но всё равно, большого преимущества перед статикой не вижу.
    Вот у меня в этом проекте есть бетонные смеси, есть асфальтобетонные, есть ещё щебень, есть ещё песок. А если бы проект был покрупнее, то вообще будет вместо класса view помойка. Лучше уж несколько хелперов написать, и радоваться. Основная логика, согласен, на статике не должна быть, потому что должен быть использован и полиморфизм, и инкапсуляция по-возможности нормальной должна быть (здесь, если что, ActiveRecord, поэтому поля напрямую доступны (на самом деле через магию).
     
  11. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    А в самом хэлпере у вас уже не помойка? Если вы в довольно абстрактном, судя по названию, классе, работаете с довольно конкретными списками. Т.е. это дело подхода - если разработчик позволит себе делать помойку, то она будет в любом случае.
    Хотя с данным моментом согласен.
     
  12. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    я как раз на днях переделывал класс для работы с БД в моем велосипеде))

    PHP:
    1. <?php
    2.  
    3. /*
    4. * To change this license header, choose License Headers in Project Properties.
    5. * To change this template file, choose Tools | Templates
    6. * and open the template in the editor.
    7. */
    8.  
    9. namespace natCMF\core;
    10.  
    11. /**
    12. * Description of Db
    13. *
    14. * @author 27087
    15. */
    16. class Db {
    17.  
    18.     /**
    19.      * Храним экземпляр текущего класса
    20.      * @var object Db
    21.      */
    22.     static private $_instance = null;
    23.  
    24.     /**
    25.      * Храним объекс работы с БД - имплементированный от интерфейса
    26.      * DbInterface
    27.      * @var object - implement DbInterface. На данный момент это может быть
    28.      * DbMysqli или DbSqlite3
    29.      */
    30.     private $_db = null;
    31.  
    32.     /**
    33.      * Создаем подключенте БД
    34.      * @return object Db - возвращает экземпляр себя хранимый в _instance
    35.      */
    36.     static public function getInstance() {
    37.         if (is_null(self::$_instance)) {
    38.             self::$_instance = new self;
    39.  
    40.             $dbParams = Config::get('dbParams');
    41.             if ($dbParams['dbType'] == 'Sqlite3') {
    42.                 self::$_instance->_db = new mysql\DbSqlite3($dbParams);
    43.             } elseif ($dbParams['dbType'] == 'mysqli') {
    44.                 self::$_instance->_db = new mysql\DbMysqli($dbParams);
    45.             } else {
    46.                 self::$_instance->_db = false;
    47.             }
    48.         }
    49.  
    50.         return self::$_instance;
    51.     }
    52.  
    53.     /**
    54.      * Запрос к БД
    55.      * @param string $query
    56.      * @param array $values
    57.      * @return object
    58.      */
    59.     static function query(string $query, array $values = []) {
    60.         return self::getInstance()->_db->query($query, $values);
    61.     }
    62.  
    63.     /**
    64.      * Возвращает количество строк полученых в результате запроса к БД
    65.      * @param type $result
    66.      * @return int
    67.      */
    68.     static function numRows($result) {
    69.         return self::getInstance()->_db->numRows($result);
    70.     }
    71.  
    72.     /**
    73.      * Очищает объект БД
    74.      * @param type $result
    75.      * @return boolean
    76.      */
    77.     static function freeResult(&$result) {
    78.         return self::getInstance()->_db->freeResult($result);
    79.     }
    80.  
    81.     /**
    82.      * Перебирая объект $result возвращает строки в виде ассоциативного
    83.      * массива
    84.      * @param type $result
    85.      * @return array
    86.      */
    87.     static function fetchAssoc($result) {
    88.         return self::getInstance()->_db->fetchAssoc($result);
    89.     }
    90.  
    91.     /**
    92.      * Перебирая объект $result возвращает строки в виде индексированного
    93.      * массива
    94.      * @param type $result
    95.      * @return array
    96.      */
    97.     static function fetchRow($result) {
    98.         return self::getInstance()->_db->fetchRow($result);
    99.     }
    100.  
    101.     /**
    102.      * Получаем информацию о модели/таблице
    103.      * @param type $table
    104.      * @return array
    105.      */
    106.     static function tableInfo($table) {
    107.         return self::getInstance()->_db->tableInfo($table);
    108.     }
    109.  
    110.     /**
    111.      * Возвращает количество запросов сделанных к базе
    112.      * @return int
    113.      */
    114.     static function getCountQuery() {
    115.         return self::getInstance()->_db->getCountQuery();
    116.     }
    117.  
    118. }
     
  13. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    @Алекс8
    1) self::$_instance не должен быть false
    2) почему сразу не вызывать Db::getInstance()->query(), кроме того, что запись короче?
    3) почему класс бд (mysql\DbSqlite3 или другой) не вынести в конфиг?
    PHP:
    1. $dbConfig = Config::get('dbConfig');
    2. $dbClass = $dbConfig['class'];
    3. $params = $dbConfig['params'];
    4. $this->db = new $dbClass($params);
     
    Алекс8 нравится это.
  14. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    1. Согласен.. там вообще планируется добавить исключения)) сейчас читаю про них)) просто у велосипеда из деталей пока только спицы да и то не все))
    2. Потому что короче запись)) мне так больше нравится)) плюс мой NetBeans не будет методам подсказки выводить)
    3. ХЗ))) может и надо)) это уже у меня 5 или 6 мой велосипед)) я дохожу до определенного момента когда мне велосипед перестется нравится, и я делаю новый))
     
  15. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    выводить будет.. только мне нравится когда запись короткая))
    --- Добавлено ---
    я для того что бы короткая запись была добавляют в родителя моих моделей метода типа getRow getRows getCount insert update
    что бы модели были более лаконичные когда работаешь с одной таблицей без связей с другими таблицами. .
    ну а если связи там у меня уже начинаются джоины и классические записи запросов к мускулу.. только плейсхолдеры немного доработанные))
     
  16. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    @Алекс8
    1) да, именно исключения надо добавлять.
    2) переходи на phpstorm. Аннотации у getInstance помогут с подсказками. @return $this работает.
    3) отказывайся от getInstance вообще.
    во первых - это объект подключения к БД. БД у тебя может быть несколько, при чем вторая появится значительно позже. И ты не сможешь переиспользовать данный класс просто создав новый объект.
    во вторых - данный класс не должен ничего знать о таблицах, об их полях и тем более о том, какие там джойны. Для каждой таблицы отдельный класс, где и реализуется логика запросов к БД.
    Хранить объект(ы) БД можно в каком-нибудь синглтоне (App::getInstanse())
    Например
    PHP:
    1. App::getInstance()->get('db')->query($params);
    2. Yii::$app->db->query($params);
    3. Yii::$app->db2->query($params);
    Либо в сервис локаторе и пр.

    Т.е. в итоге у тебя будет только одна единственная глобальная переменная - App (Yii)
    К тому же всё это на много проще тестируется
     
    mkramer и Алекс8 нравится это.
  17. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Так такой багофичей обращаются к методу базы из другого класса.
     
  18. Алекс8

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

    С нами с:
    18 май 2017
    Сообщения:
    1.730
    Симпатии:
    359
    а почему это багофича?))
     
  19. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Да так субъективно, мне эти прокидывания классами своих инстансов не нужны :)
     
    Алекс8 нравится это.
  20. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    т.е. вы всякий раз, когда хотите сделать запрос к БД делаете new?
     
  21. keren

    keren Новичок

    С нами с:
    15 ноя 2017
    Сообщения:
    513
    Симпатии:
    42
    Да и в конструкторе создавать подключение а не в конфиге.
     
  22. valentinnew

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

    С нами с:
    30 янв 2011
    Сообщения:
    160
    Симпатии:
    35
    Так в конструкторе и надо создавать соединение. Но не столько раз, сколько нужно сделать запросов к БД, а один раз за всё время выполнение скрипта.
    Но я писал, что лучше не кучу синглтонов хранить, а один - в котором уже хранятся нормальные объекты.