Comments 64
inline js, css, куча говнокода… вы удалите этот пост скорей, пока ждуниоры не стали вас в пример брать!
Yii первой версии (о котором вы пишете) уже очень отстал от современных трендов PHP, потому прием улучшений прекращен, а датой End of life объявлен конец 2018 года. Если вы пишете новый проект — обязательно посмотрите на Yii2, там вы найдете гораздо более гамотные и современные архитектурные решения.
На GitHub есть более-менее грамотно написанные проекты на YII 1.1, например РосЯма:
https://github.com/RosYama/RosYama.2
https://github.com/RosYama/RosYama.2
А спасибо.
А не подскажете то же самое на Yii2?
Я пока пишу свои поделки на первой версии, но уже становится понятно, что если не хочу превратиться в мамонта — то пора осваивать вторую, и чем быстрее — тем лучше.
Я пока пишу свои поделки на первой версии, но уже становится понятно, что если не хочу превратиться в мамонта — то пора осваивать вторую, и чем быстрее — тем лучше.
Думаю лучше обратиться к документации, кстати отличная тема для статьи и хаба. Осваивать новую версию и описывать миграции.
Документация — само собой. Но обычно кроме документации, полезно видеть уже готовые, более-менее грамотно написанные проекты, чтобы понимать… даже не coding style, а просто процесс мышления, менталитет фреймворка. На примерах из документации это не всегда видно, они достаточно упрощённые и оторванные от реальной жизни.
В общем, если кто знает хорошие проекты на Yii2, на которые можно посмотреть в плане изучения кода — буду признателен.
В общем, если кто знает хорошие проекты на Yii2, на которые можно посмотреть в плане изучения кода — буду признателен.
Есть проект, его делал один человек — его уволили. Пришли 3 новых программиста им код непонравился — начали переписывать — все писали на разных языках в разном стиле и парадигмах (сторонники разных подходов). И таких проектов много. Думаю от примеров из документации отталкиваться правильнее — он следует правилам кодирования язка и стилю фреймворка.
Я сейчас переезжаю с PHP на Java достаточно большая разница — постараюсь незахватить старых привычек.
Я сейчас переезжаю с PHP на Java достаточно большая разница — постараюсь незахватить старых привычек.
Код там на 3 с минусом. Не стал бы рекомендовать новичкам смотреть его и, тем более, брать пример.
Но в таком случае, какой можно порекомендовать?
Зачастую людям хотелось бы поглядеть на рабочий проект вместо очередного блога или hello world.
К сожалению не могу показать свой код, он под NDA. Но как и автор, я тоже отошёл от некоторых рекомендаций (например, меня коробит от CHtml).
YII — это только фреймворк, а демо-проекты — лишь рекомендация.
Мне, например многие подходы в YII 2 не понравились, и поэтому я пока остался на YII 1.1
Зачастую людям хотелось бы поглядеть на рабочий проект вместо очередного блога или hello world.
К сожалению не могу показать свой код, он под NDA. Но как и автор, я тоже отошёл от некоторых рекомендаций (например, меня коробит от CHtml).
YII — это только фреймворк, а демо-проекты — лишь рекомендация.
Мне, например многие подходы в YII 2 не понравились, и поэтому я пока остался на YII 1.1
Вот, например, большой открытый проект на 2.0: https://www.humhub.org/en
Совершенно согласен фреймворки, паттерны и подходы меняются время от времени — некоторые возможности зачастую не используются — по причине неудобства. Суть в рабочем коде, его можно менять как захочется.
Лицензия? Если вы не будите делиться наработками и техническими подробностями сектор остановится.
Я к примеру собрался писать игру на java: jmonkeyengine. Там будет достаточно проблем и на клиенте и на сервере. Наработки буду выкладывать в хаб так как люди которые затят научиться программированию или сделать тоже самое просто несмогут этого сделать. Неотчего будет отталкнуться.
Я к примеру собрался писать игру на java: jmonkeyengine. Там будет достаточно проблем и на клиенте и на сервере. Наработки буду выкладывать в хаб так как люди которые затят научиться программированию или сделать тоже самое просто несмогут этого сделать. Неотчего будет отталкнуться.
–4 Это не кода на 3 с минусом, а просто html.
а что там грамотного?
Местами код сумбурный, но позвольте, вы сразу умным родились и всё умели?
Лично я, когда начинал разбираться с миграциями, глядел в их код и кое-что почерпнул.
Вьюхи мне откровенно не нравятся. Но глянуть, как другие люди пишут всегда полезно.
Лично я, когда начинал разбираться с миграциями, глядел в их код и кое-что почерпнул.
Вьюхи мне откровенно не нравятся. Но глянуть, как другие люди пишут всегда полезно.
Ну к чему сразу переход на личности? Вы посоветовали новичкам источник, который Вам самим не очень нравится, просто рассказали бы в добавок к ссылке, что там хорошо, а что нет. Иначе будут воспринимать как эталон.
Простите, если задел. Но из того что мне в моём примере не по душе — только лапша в коде и куски с комментариями. Справедливости ради отмечу, что не везде. В остальном, вполне себе боевой проект.
А вот что неграмотного там заметили Вы?
А вот что неграмотного там заметили Вы?
Ну, например:
— тонны логики в контроллерах https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L140
— прямое обращение к $_GET и т.д. https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L205
— регистрация статики в контроллере — https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L237
— ужасное форматирование кода
— curl-лапша https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L720
Это только то, что бросилось в глаза в первом открытом контроллере.
— тонны логики в контроллерах https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L140
— прямое обращение к $_GET и т.д. https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L205
— регистрация статики в контроллере — https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L237
— ужасное форматирование кода
— curl-лапша https://github.com/RosYama/RosYama.2/blob/master/protected/controllers/HolesController.php#L720
Это только то, что бросилось в глаза в первом открытом контроллере.
Спорный вопрос: оборачивать каждую конструкцию языка в класс? — думаю это нехорошо, некоторые узкие места в PHP переписываются на С для улучшения производительности и экономии памяти. Тоесть с точностью до наоборот.
С вьюхами там несколько вариантов: 1)php сам по себе шаблонизатор. 2)стандартные вещи типа Chtml 3)Bootstrap 4) Любой вариант. Фреймворк очень гибкий.
Исходник. В зип архиве. На яндекс диске.
Достаточно интересная статья, но вот момент с экшенами несколько сбивает с толку, тоесть если я правильно понял, вы предлогаете использовать каждый экшн = класс, а не как изначально в Yii когда экшн = метод контроллера. Таким образом вы призываете уйти от абстракции контроллера к абстракции его экшенов, но зачем? В целом я правильно понимаю, что у нас будет 4 класса с экшенами для CRUD контроллера?
в фреймворке есть возможность указывать в контроллере экшн в виде названия класса а не в виде метода класса.
Это предназначено как раз для такого решения — когда действие одинаковое во многих контроллерах, и отличаются только детали.
Собственно ориентируясь именно на встроенное решение автор и писал данный код. Он типовой, но его обычно игнорируют.
Это предназначено как раз для такого решения — когда действие одинаковое во многих контроллерах, и отличаются только детали.
Собственно ориентируясь именно на встроенное решение автор и писал данный код. Он типовой, но его обычно игнорируют.
Суть в том что Экшен может быть один, а контроллеров с одинаковыми действиями 5 — повторное использование кода в данном случае. А вообще — пример использования поведений, экшенов и виджетов.
Просто я не очень понимаю, зачем отрывать экшен от контроллера, тогда ведь нарушается абстракция вся этого контроллера? А дублирование кода, да это плохо. Но в данном случае у меня все равно экшены относятся к контроллерам и не пишется множество не нужных классов, так как вся бизнес логика хранится в модели, ну и экшены у меня все таки просто принимают значения и вызывают метод модели, не более. И тогда никакого дублирования кода, нарушения абстракций и горождения кучи классов ради одного метода. Ведь YII следует парадигме MVC, а значит вся бизнес логика должна быть с моделях.
Это в теории, вспомните нормальные формы баз данных, есть много примеров когда для одного поля лучше не создавать отдельную таблицу:
И тут таже история всмысле парадигмы, у нас есть кусок кода который повторяется во многих контроллерах, мы его выносим в экшен:
class Trucks extends Advert{
public $bodyTypes = [
1 => "Закрытый-Тентованный",
2 => "Закрытый-Фургон",
3 => "Закрытый-Контейнер",
4 => "Закрытый-Цельнометаллич.",
5 => "Закрытый-Рефрижератор",
6 => "Закрытый-Изотермический",
7 => "Открытый-Бортовой",
8 => "Открытый-Контейнеровоз",
9 => "Открытый-Низкорамный",
10 => "Открытый-Самосвал",
11 => "Открытый-Шаланда",
12 => "Открытый-Платформа",
13 => "Открытый-Пирамида",
14 => "Автовоз",
15 => "Автотранспортер",
16 => "Эвакуатор",
17 => "Трал",
18 => "Автобус",
19 => "Микроавтобус",
20 => "Пикап",
21 => "Легковая-седан",
22 => "Легковая-хетчбек",
23 => "Легковая-универсал",
24 => "Ж/Д вагон",
25 => "Цистерна"
];
И тут таже история всмысле парадигмы, у нас есть кусок кода который повторяется во многих контроллерах, мы его выносим в экшен:
public function actionIndex(){
$model = new Model();
$this->render('index',['model' => $model]);
}
Тут скорее вопрос о том почему наследоваться от CRUDAction а не от CRUDController?
Да, именно это я и пытался сказать. Зачем плодить класс для каждого экшена если можно наследовать контроллер и не разрушать абстракцию контроллер->экшн.
Именно в этом коде экшены созданы для тех контроллеров который были сгенерированы модулем gii для работы с моделями. 5 моделей и 5 контроллеров с одинаковым содержимым.
Зачем 5 контроллеров с одинковым содержимым, если мы говорим о CRUD, то у нас одна сущность имеет 5 экшенов, тоесть если у нас 5 контроллеров (5 сущностей), то у нас 25 экшенов получается. И почему 5 моделей? Скорее 6, базовая модель плюс её наследеники если нужны. Таким образом у нас нормальный уровень абстракции, каждый экшн принадлежит к сущности контроллера и вызывает бизнес логику на основе входящих данных из модели. Все равно ведь Yii реализует парадигму MVC, тоесть даже в вашем случае вся бизнес логика должна быть в модели и у вас просто получается класс-экшн который просто вызывает бизнес логику из модели. Ваш подход применим только к RESTFull API и только если вы не реализуете бизнес логику в моделях, а реализуете её в экшенах.
Но модель чаще всего будет разная в зависимости от сущности, а вот рендер, не думаю, что ради одной строки стоит создавать класс обертку для экшена. А по поводу вашего примера с грузовиками, так мне кажется, что применение нормальных форм баз данных к ООП не очень приминимо.
Нормальные формы — это тоже своеобразные правила которые можно и нужно нарушать в пользу скорости кода, просто аналогия. Модель может быть и будет разная, я про типовые вещи findByPk().
Смотрите как теперь выглядит контроллер — насколько меньше кода:
Если я захочу поменять что то в 10 контроллерах, мне нужно будет поменять это только в одном экшене который к ним прикрепляется, так выглядит контроллер:
Yii::import('application.controllers.CrudController');
class MaterialsController extends CrudController{}
Смотрите как теперь выглядит контроллер — насколько меньше кода:
Если я захочу поменять что то в 10 контроллерах, мне нужно будет поменять это только в одном экшене который к ним прикрепляется, так выглядит контроллер:
Yii::import('application.controllers.CrudController');
class MaterialsController extends CrudController{}
Но так же вы можете поменять это в одной модели, ведь модель в парадигме MVC и модель в Yii вообще вещи разные, так же никто не запрещает абстракцию модели, тоесть таким образом вы наследуете базовую модель которая реализует базовую бизнес логику для всех моделей, которые в свою очередь реализуют только уникальные методы бизнес логики в зависимости от сущности.
Да, все стандартные методы реализованы в базовой модели, а уникальные в наследнике — но в итоге вызов методов происходит в контроллере. Мы же не переносим всю логику в модель — а только делаем вызов или нет? Это может по разному выглядеть в контроллерах так:
или так
Или так:
Но речь идет о повторном использовании кода контроллера.
$model = Cities::model()->findAll([
'condition' => 'name like :term',
'params' => [
':term' => "%$term%"
]
]);
$arr = [];
foreach($model as $city){
$arr[] = ['id' => $city->id, 'value' => $city->name];
}
или так
$model = Cities::model()->findByName($name);
$arr = [];
foreach($model as $city){
$arr[] = ['id' => $city->id, 'value' => $city->name];
}
Или так:
$arr = Cities::model()->findByNameArray($name);
Но речь идет о повторном использовании кода контроллера.
Все правильно, и вся бизнес логика у вас находится в модели, так зачем тогда вам 25 классов экшенов если достаточно 5 классов контроллеров, ведь обычно контроллер = сущность и согласно вашему примеру в каждом контроллере будет использоваться разная модель? Или одна? Хорошо, даже предположим, что экшены полностью идентичны для разных 5-ти контроллеров. Но учитывая что вся бизнес логика в модели, вы просто создадите класс-экшн для одной, двух строк. Да вы избавитесь от повторного использования кода, но, возникает три вопроса:
- Почему нельзя реализовать все таки контроллер с этими экшенами и наследоватся от него?
- Что вы будете делать когда один экшн одного контроллера потребует изменения логики? Создавать новый экшн-класс?
- Стоит ли ради "избежания повторного использования кода" разрушать абстракцию данных сущность-экшн? Ведь этого можно избежать используя наследование контроллеров.
С первым согласен это в общем то одно и тоже создать экшены или наследоваться от общего. На мой взгляд отдельные экшены более гибкая штука. Похоже на хэндлер больше.
Отдельные экшены имеет смысл только когда нужно использовать некий компонент который должен предоставлять экшн, для примера загрузка изображения в таком случае в контроллер просто подгружается компонент и экшн. Но вы же в статье показали пример на CRUD, а в CRUD мне сложно представить ситуацию, когда у двух сущностей будут идентичные экшены. А если создавать отдельный экшн для каждой сущности, то выйдет каша и классов.
ob_start();
header('Content-Type: '. $mimeType);
$imageFunction($thumb,null,100);
$img = ob_get_contents();
@unlink($path);
@file_put_contents($path,$img);
а не проще сразу в фаил писать `$imageFunction($thumb,$path,100);` и ещё один момент.
@unlink($path);
@file_put_contents($path,$img);
тот кто скопирует это, долго будет искать почему картинка не сохранилась, ведь ошибок нет.
Чистота кода она конечно важна, но так можно: рефакторить, улучшать, "подкрашивать", переписывать код до бесконечности — потратить кучу времени которое стоит дороже чем красота кода.
Так то да. Но если не тратить время на рефакторинг(можно сказать работу над ошибками). Движет всё таки изучать ЯП, и применять оптимальные решения. Да кто то зарабатывает деньги тратой времени на написание «нечистого кода» большого объёма, а кто то пишет «более чистый код», и зарабатывает на том что, элементарные задачи на подобие «вывести тайтл с префиксом» решает за 5 минут, а кто то разбираеться в своём же коде пишит велосипеды и тратит 30 минут, и того 25 минут разницы. По вашему кому заплатят больше? первому или второму. Конечно первому т.к. это вложение в будущее проэкта, это меньший порог вхождения и стабильность работы, а второй стоит дешевле так как, в будущем это высокий порог вхождения, низкая стабильность, разработка нового решения… А по статье правда отвлекает от чтения. И не обежайтесь это моё сугубо личное мнение.
Идея насчет тайтла в коде интересная мысль:
<?php
class MetaTagMap extends CComponent{
public static $map = [
'credits/index' => [
'description' => 'Взять кредит без залогов и поручителей',
'keywords' => 'кредит,взять кредит,кредит без поручителей,кредит без залогов,кредит без залогов и поручителей',
'title' => "Взять кредит"
],
'trucks/index' => [
'description' => 'Поиск грузоперевозчиков',
'keywords' => 'перевезти груз,грузоперевозки',
'title' => "Грузоперевозки"
],
'buildings/index' => [
'description' => 'Коммерческая недвижимость',
'keywords' => 'аренда офиса,аренда склада,купить склад,купить офис,купить здание,арендовать здание',
'title' => "Недвижимость"
],
'biztrade/index' => [
'description' => 'Купить бизнес',
'keywords' => 'купить бизнес,купить долю,купить франшизу',
'title' => "Купить бизнес"
],
'materials/index' => [
'description' => 'Товары ',
'keywords' => 'купить,',
'title' => "Купить "
],
];
public static function getKeywords($key, $add = ''){
return self::$map[$key]['keywords'].$add;
}
public static function getTitle($key, $add = ''){
return self::$map[$key]['title'] . " ". $add ." | ".Yii::app()->name;
}
public static function getDescription($key, $add = ''){
return self::$map[$key]['description']. ' ' . $add;
}
}
Сорри не понял Вашего заявления… Собственно, title в коде смотря как использовать:
1. Когда просто сайтик без админки — почему бы нет если это ваш сайт и вам в принципе удобно напрямую работать с файлами(кодом) или базой.
2. Когда это cms — и вам необходимо хранить их в базе данных 'как они есть' так как, мета title,description,keywords и теги такие как h1,h2,p их содержимое должно редактироваться из админки и отображаться та как было это вписано в поле в админки. Что собственно приводит к гибкости проэкта.
1. Когда просто сайтик без админки — почему бы нет если это ваш сайт и вам в принципе удобно напрямую работать с файлами(кодом) или базой.
2. Когда это cms — и вам необходимо хранить их в базе данных 'как они есть' так как, мета title,description,keywords и теги такие как h1,h2,p их содержимое должно редактироваться из админки и отображаться та как было это вписано в поле в админки. Что собственно приводит к гибкости проэкта.
С одной стороны да, с другой нужно писать "паттерны" та как мета теги почти везде и всегда динамические, например: Отделение ВТБ 24 ${Новосибирск} Филиал № 5411 | concat{Все для бизнеса 2biz.net}
С точки зрения СЕО они не должны быть динамические, вот несколько аргументов почему:
1. 'Сухие' тайтлы, с точки зрения пользователя я перейду 'Отделение ВТБ-24 в новосибирске', да и в сео есть приёмы как сокращение слов к примеру городов, 'Отд-ние ВТБ в городе Новосибирске', т.е. Вам придёться писать чуть ли не каждой странице свой уникальный title и description.
2. Обязательно найдёться город/регион, филиал, другая информация, которая сломает title(вероятность генерации неверных словосочетаний, к примеру из жизни «купить зонта в нашем интернет магазине»).
3. Meta Description должен быть в своем роде уникален.
4. Keywords тем более (хотя вроде как их можно опустить)
5. h1 страницы не должен повторять title и зависить от него, и он должен встречаться только один раз на странице
6. h2 подобно пункту 5.
7. p — «сеотексты» (в большинстве случаев он отображаеться в описание при выдачи) должен быть уникальным и в краткой форме раскрывать суть страницы.
8. etc
Я мог бы перечислять дальше но думаю, понятен ход моих мыслей. По этому можно добавить ваш «паттерн» способностью гибко редактировать, любое из свойств для странице, допустим title, и приоритет вывода довать title из базы если он существует.
1. 'Сухие' тайтлы, с точки зрения пользователя я перейду 'Отделение ВТБ-24 в новосибирске', да и в сео есть приёмы как сокращение слов к примеру городов, 'Отд-ние ВТБ в городе Новосибирске', т.е. Вам придёться писать чуть ли не каждой странице свой уникальный title и description.
2. Обязательно найдёться город/регион, филиал, другая информация, которая сломает title(вероятность генерации неверных словосочетаний, к примеру из жизни «купить зонта в нашем интернет магазине»).
3. Meta Description должен быть в своем роде уникален.
4. Keywords тем более (хотя вроде как их можно опустить)
5. h1 страницы не должен повторять title и зависить от него, и он должен встречаться только один раз на странице
6. h2 подобно пункту 5.
7. p — «сеотексты» (в большинстве случаев он отображаеться в описание при выдачи) должен быть уникальным и в краткой форме раскрывать суть страницы.
8. etc
Я мог бы перечислять дальше но думаю, понятен ход моих мыслей. По этому можно добавить ваш «паттерн» способностью гибко редактировать, любое из свойств для странице, допустим title, и приоритет вывода довать title из базы если он существует.
fetch_assoc :)
http://cs623131.vk.me/v623131445/4d2bc/Eo7GB3WAAa4.jpg
Sign up to leave a comment.
Yii framework разбор кода