I’ve made it no mystery that I work with Yii and enjoy using it. I’m somewhat of an old school guy and don’t mind reading a book to get started. I like the way they normally give you a gradual introduction to something you want to gain knowledge about. It’s a more subtle way to start with something and you don’t immediately drown in the huge amount of information.
That’s the way I started on Yii 1.1 some years ago. Unfortunately, I tossed the book I used back then half way through; it went too slow for me. Going over simple things repeatedly made me lose my interest quite fast. I wanted to learn more, faster. I had a whole bunch of ideas in my head and I wanted to find out how to realize them.
We’re a few years down the road and with the introduction of Yii 2.0 I let myself be tempted yet again by a book before starting some serious work with Yii 2.0. With mixed experiences in mind I started on a copy of Web Application Development with Yii 2 and PHP and ended up pleasantly surprised.
The structure of this 2.0 version is somewhat similar to the previous one (which caused Jeffrey Winesett’s name to be on the cover) but this one is entirely written by Mark Safronov.
Having had some experience with Yii, I was looking for the differences and an insight into how you build an application from nothing.
The book does this, as usual, by taking an example application and gradually extending it. It starts with a test-first approach. If you feel serious about your application and maintaining it long-term, you’ll probably agree that tests are a vital part. Luckily, this approach relaxes quite fast, not spelling out how to define a test every time something new is added.
The book covers all the key components of the framework; rendering, authentication, authorization, modules, behavior, extensions, events, grid view and route management. All the components are reviewed along with how to use them. It also dives into the working of the framework quite often, showing the logic in it and explaining in detail how they work.
It has a slight touch of humor every now and then, making it a very easy read.
I did, again, skip some pages right around modules and the behavior part, but that was more because I was very interested in seeing what was coming in the chapters after that. Ever since I finished the book and started on my first real Yii 2.0 project, I’ve already gone back to the book a few times. I came across a few new things and remembered some of the nice suggestions that were made for improvement. For me, that was proof enough that it was at least worth the read.
Being left with quite a good feeling about this book, I went to contact Mark Safronov for some Q&A on the book and Yii itself.
Can you tell us a bit about your background, who are you?
There’s not much to brag about. I am a full-time developer in Clevertech, and I am Russian, living in a country where horses ride YOU.
I am working on a website based on Yii 1.1 every day and have been doing it for more than two years already. This website is sufficiently large and complex to really test the system-building skills of anyone deeply involved in the development, with the requirements changing on daily basis. So I dare to consider myself knowing thing or two about building and maintaining real-world Yii-based Web applications.
In the meantime, I maintained the opensource YiiBooster and rewrote from scratch the YiiBoilerplate project.
I have been poisoned by PHP for around 5 years already. I started my career in a Russian Web studio which made websites for its customers based on the dreaded 1C-Bitrix CMS. You westerners probably don’t know this Frankenstein of CMS-es but I certainly do regret knowing it.
Over the years, I switched my habits from reading sci-fi and fantasy novels to reading hardcore fundamental technology books like Working Effectively with Legacy Code, GooS, DDD and such. This has proven itself a lot more entertaining, if not enlightening.
How did you end up writing this book?
I have co-authored another title, “INSTANT Yii 1.1 Application Development Starter”. At that time, the publisher lost the original author (literally lost, they could not contact him after he sent them the drafts) and chose me, because they already had me as a reviewer for that title.
So, we already had some cooperation prior to this book and they probably decided that I write convincingly.
Why Yii 2.0, since the list of frameworks is quite long?
First of all, I got no other choice; the publisher gave me the offer specifically for a book about Yii. And Yii is the framework I am dealing with on a daily basis.
Also, version 2 is an obvious next step. I saw this as an opportunity to learn about the intricacies of its internals. On a project I am currently working on it’s a common practice to delve into the source code of the framework itself, because you frequently need absolutely exact knowledge of how a method (like
I do need to make a major disclaimer here. I am not biased towards Yii in any way. To be honest, I actually dislike it, but bear with it at the same time. I have no attachment and only a strictly professional relation to this framework. This certainly affected both the overall style of the book and the areas it covers.
What do you feel was the weak point of Yii 1.1?
The most important pain point of Yii was, and still is, the Service Locator, which is, incidentally, the central idiom of the whole framework. If you are accustomed to sticking calls to
Yii::$app everywhere through your whole application, then I guarantee you, you will experience major butthurt later on, when your project grows. Even earlier if you try to auto-test it.
Yii 2 tried to overcome it by shipping the DI container inside, but it has almost no coverage in documentation, every tutorial assumes you do
Yii::$app everywhere. Due to my enormous mental inertia, I have not covered
yii\di\Container in the book, which I regret.
A second issue is its tight coupling to the classes. Most of the time, when you need to meddle with something built-in to Yii, you need to both subclass what you need and copy the old behavior from superclass.
Yii 2 has a lot of improvements here. But nevertheless; try to write the custom Column class which has automatic calculation of totals in the footer, without copy-pasting parts of the Column class.
The reason is very simple: as long as you have a
Yii::app()->something call in your class, you can’t test it in isolation; it will be the integrated test, because you need to include the YiiBase class and, actually, your application config, autoloader and also you need to start the Yii application because you need your components attached and configured.
If you don’t see it as a pain, all right, but I personally think that even in terms of run time alone this is a totally failed approach. Gary Bernhardt says that even 100ms test runtime is too much and I usually prefer to listen to people of his caliber. And running time is not the only problem with such tight coupling.
What should we use, then? And how would using this influence automated tests?
Dependency Injection techniques, in particular, separating the creating of the application object graph and actually performing processing. As far as I know, people do this by using some kind of IoC container, but I have no actual first-hand experience working with them as the project I am working on on daily basis is too legacy to even try to use such things there.
I have already said above how it influences automated tests. In short, we have the Law of Demeter for years now, and sticking to it actually works (with this I do have first-hand experience) and leads to decoupled, maintainable, testable design.
You say that Yii 2 “tried to overcome” this. Formulating it that way implies that they didn’t succeed.
They would succeed by completely throwing the
Yii singleton away and making everything build itself decoratively in the
index.php entry point. This way we would actually work with Yii in a TDD manner. I dare to spell my personal opinion: I am reading professional literature every single day trying to catch up with all the community knowledge I missed while wasting time in university, and sometimes I think that the percentage of people that actually care about problems already solved is extremely low; the majority of the community is just spitting out code in code-fix and write-forget manner thinking that there’s no way to do better. I haven’t seen the techniques described in “DDD” by Eric Evans actually implemented ever and I find this completely unbelievable. I tried to use what I learned in the course of the “Web app development with Yii 2” but I consider myself failed at this approach, as I have too little experience working in such a way.
Since you have quite a bit of experience with Yii, what is your general feeling about what changed in version 2.0? And how does that influence the way we can work with it?
- I was very pleased with the improvements in the Yii 2 framework. It was a physical feeling of pleasure sometimes.
- They use namespaces, which is just great, as I have namespace seams now and can have classes with identical names through my project;
- There are interfaces now in critical places, like DataProviderInterface, which means that I can provide my own implementation without the need to subclass the whole huge CComponent.
- On the other hand, they subclass everything from the custom-made
Object class, but this class is actually a nice invention – it’s the stdClass with automatic
setSomething() methods, configurable by the associative configuration array and some other features. At the same time, this class uses a static call to
Yii::configure() right inside its constructor which, again, reverts the dependencies inside out.
- They finally extracted some entities as separate components, like Response and View. The Response concept is amazing, as we can finally implement sane CSV and JSON formatting in an idiomatic way and without crazy hacks involving sub classes again.
- They actually have a dependency injection container in the code base, so we can finally hope to decrease the usage of calls to
Yii::$app through the code base.
This is just what I can recall right now. There is absolutely no need to keep sticking to Yii 1.1 if you can migrate. However, I am pretty sure nobody will be able to migrate existing Yii 1.1 application to Yii 2 without substantial rewriting of most of the application.
I noticed several times throughout the book that you refer to the ‘excellent’ documentation on the Yii website regarding some subjects. Did it help in the book research?
Honestly, I admire the amount and quality of documentation in Yii, regardless of my overall feelings about it. As a developer using the software which should be the root for my work, I usually need precise information about the tiniest details, for example, contracts needed to be followed when calling a particular function. Especially when we’re quite far from the type safety of compiled languages. When I praise its documentation I usually mean its self-documentation, its docblocks in code.
Yii 1.1 was enormously hard for me to understand back when I just started to understand OOP, but with time, all the pieces came into place finally and I figured out its structure. Yii 2 doesn’t have a lot of significant changes in architecture so it was really easy to research.
You make a firm statement about decoupling your code from the ActiveRecord ORM layer. Can you tell us why we would want to do this?
The main reason for this lies in the object-relation impedance mismatch. At one point in time I realized that my logical domain model does not fit into a single table and so, ActiveRecord suddenly became a limiting factor. More than that, the whole set of features stuffed into them is completely unnecessary in the domain layer, where the actual business-related work happens. Shortly after that I learned about the object-relation impedance mismatch, Repository pattern, CQRS, and became completely convinced that the place of ORM should be at the lowest possible layer of the architecture, even lower than the actual data access layer.
This book however is about Yii, not general development. I could not gloss over the problem of having people calling ActiveRecords right from Controllers so I have shown the simplest possible decoupling method in chapter 2.
I admit, I spelled out my personal and my team’s opinion. There are probably a lot of people who use xdebug routinely and it helps them. I personally have found that when I am able to write automated tests, I simply don’t need the debugger at all, even if I don’t test first. Any data flow check I can manually perform with a debugger can be encoded as auto test at some level (ideally a unit one) and it will serve both as a regression test in future and the documentation example for others. A total win. And
var_dump(); die() when you’re hacking away is just quicker. Maybe I am just too dumb to use xdebug, though :)
In our conversation, Mark makes a side note which I’d like to close off with;
…if you’re still not sure about whether you need to migrate to Yii 2, be it from Yii 1.1 or from bare procedural PHP or from some CMS, then my answer is: if you are able to, then do it immediately. Yii 2 is an enormous leap in overall quality and expressibility. It builds upon virtually everything good which emerged in the PHP community over the recent years and you certainly don’t want to miss it.
I’d like to thank Mark for the time he took to answer my questions and the insights he gave into software development as a whole.