Да, так будет правильно. Но зачем вызывать статический метод, если он всё равно инициализирует объект ?
та да согласен чтото здесь не так , я планировал создать статический метод без созданий обьектов , так как методы часто использую во вьюхах и обращаюсь напрямую , но получилось что все равно я создаю обьекты , всем спасибо буду разбираться с теорией ООП
@Evgenij85, методы, используемые во вьюхах, выносят в отдельные классы, называемые хелперами. И в них обычно да, все методы статические
PHP: namespace app\helpers; use app\models\user\Service; use app\models\user\service\VendorService; use yii\helpers\Html; class ShorteningHelper { /** * @param Service $service * * @return string */ public static function asphaltConcreteShort(Service $service): string { $short = "АБС "; $short .= str_replace(["мелкозернизстый", "крупнозернистый", "плотный", "пористый"], ["МЗ", "КЗ", "плот.", "пор"], mb_strtolower($service->sort, "utf-8")) . " "; if (mb_strpos($service->sort, "пористый", 0, "utf-8") === false) { $short .= "Тип$service->asphaltConcreteType "; } $short .= "М" . (array_search($service->asphaltConcreteMark, VendorService::ASPHALT_CONCRETE_MARKS) + 1); return $short; } /* .... */ } Из моего проекта.
У тебя view - это уже объект, при условии использования нормального фреймворка. В этот объект ты можешь засунуть функцию получения объекта хелпера. Причем хэлпер тоже можно объектом хранить. В шаблоне приведенный выше пример можно использовать так: PHP: <? /** $var View $this **/?> <?= $this->getShorteningHelper()->asphaltConcreteShort($service) ?> А сам ShorteningHelper получать либо ленивой загрузкой, либо в конструкторе.
Ну в хелперах - нормально, это ограниченное использование. Не просто же так в язык ввели эту фитчу. А так, представляешь во что класс View превратится? Конечно, как вариант, сделать так: PHP: $this->getHelper("shrotening")->asphaltConcreteShort($short); , тогда не такой трындец будет, но всё равно, большого преимущества перед статикой не вижу. Вот у меня в этом проекте есть бетонные смеси, есть асфальтобетонные, есть ещё щебень, есть ещё песок. А если бы проект был покрупнее, то вообще будет вместо класса view помойка. Лучше уж несколько хелперов написать, и радоваться. Основная логика, согласен, на статике не должна быть, потому что должен быть использован и полиморфизм, и инкапсуляция по-возможности нормальной должна быть (здесь, если что, ActiveRecord, поэтому поля напрямую доступны (на самом деле через магию).
А в самом хэлпере у вас уже не помойка? Если вы в довольно абстрактном, судя по названию, классе, работаете с довольно конкретными списками. Т.е. это дело подхода - если разработчик позволит себе делать помойку, то она будет в любом случае. Хотя с данным моментом согласен.
я как раз на днях переделывал класс для работы с БД в моем велосипеде)) PHP: <?php /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ namespace natCMF\core; /** * Description of Db * * @author 27087 */ class Db { /** * Храним экземпляр текущего класса * @var object Db */ static private $_instance = null; /** * Храним объекс работы с БД - имплементированный от интерфейса * DbInterface * @var object - implement DbInterface. На данный момент это может быть * DbMysqli или DbSqlite3 */ private $_db = null; /** * Создаем подключенте БД * @return object Db - возвращает экземпляр себя хранимый в _instance */ static public function getInstance() { if (is_null(self::$_instance)) { self::$_instance = new self; $dbParams = Config::get('dbParams'); if ($dbParams['dbType'] == 'Sqlite3') { self::$_instance->_db = new mysql\DbSqlite3($dbParams); } elseif ($dbParams['dbType'] == 'mysqli') { self::$_instance->_db = new mysql\DbMysqli($dbParams); } else { self::$_instance->_db = false; } } return self::$_instance; } /** * Запрос к БД * @param string $query * @param array $values * @return object */ static function query(string $query, array $values = []) { return self::getInstance()->_db->query($query, $values); } /** * Возвращает количество строк полученых в результате запроса к БД * @param type $result * @return int */ static function numRows($result) { return self::getInstance()->_db->numRows($result); } /** * Очищает объект БД * @param type $result * @return boolean */ static function freeResult(&$result) { return self::getInstance()->_db->freeResult($result); } /** * Перебирая объект $result возвращает строки в виде ассоциативного * массива * @param type $result * @return array */ static function fetchAssoc($result) { return self::getInstance()->_db->fetchAssoc($result); } /** * Перебирая объект $result возвращает строки в виде индексированного * массива * @param type $result * @return array */ static function fetchRow($result) { return self::getInstance()->_db->fetchRow($result); } /** * Получаем информацию о модели/таблице * @param type $table * @return array */ static function tableInfo($table) { return self::getInstance()->_db->tableInfo($table); } /** * Возвращает количество запросов сделанных к базе * @return int */ static function getCountQuery() { return self::getInstance()->_db->getCountQuery(); } }
@Алекс8 1) self::$_instance не должен быть false 2) почему сразу не вызывать Db::getInstance()->query(), кроме того, что запись короче? 3) почему класс бд (mysql\DbSqlite3 или другой) не вынести в конфиг? PHP: $dbConfig = Config::get('dbConfig'); $dbClass = $dbConfig['class']; $params = $dbConfig['params']; $this->db = new $dbClass($params);
1. Согласен.. там вообще планируется добавить исключения)) сейчас читаю про них)) просто у велосипеда из деталей пока только спицы да и то не все)) 2. Потому что короче запись)) мне так больше нравится)) плюс мой NetBeans не будет методам подсказки выводить) 3. ХЗ))) может и надо)) это уже у меня 5 или 6 мой велосипед)) я дохожу до определенного момента когда мне велосипед перестется нравится, и я делаю новый))
выводить будет.. только мне нравится когда запись короткая)) --- Добавлено --- я для того что бы короткая запись была добавляют в родителя моих моделей метода типа getRow getRows getCount insert update что бы модели были более лаконичные когда работаешь с одной таблицей без связей с другими таблицами. . ну а если связи там у меня уже начинаются джоины и классические записи запросов к мускулу.. только плейсхолдеры немного доработанные))
@Алекс8 1) да, именно исключения надо добавлять. 2) переходи на phpstorm. Аннотации у getInstance помогут с подсказками. @return $this работает. 3) отказывайся от getInstance вообще. во первых - это объект подключения к БД. БД у тебя может быть несколько, при чем вторая появится значительно позже. И ты не сможешь переиспользовать данный класс просто создав новый объект. во вторых - данный класс не должен ничего знать о таблицах, об их полях и тем более о том, какие там джойны. Для каждой таблицы отдельный класс, где и реализуется логика запросов к БД. Хранить объект(ы) БД можно в каком-нибудь синглтоне (App::getInstanse()) Например PHP: App::getInstance()->get('db')->query($params); Yii::$app->db->query($params); Yii::$app->db2->query($params); Либо в сервис локаторе и пр. Т.е. в итоге у тебя будет только одна единственная глобальная переменная - App (Yii) К тому же всё это на много проще тестируется
Так в конструкторе и надо создавать соединение. Но не столько раз, сколько нужно сделать запросов к БД, а один раз за всё время выполнение скрипта. Но я писал, что лучше не кучу синглтонов хранить, а один - в котором уже хранятся нормальные объекты.