Yii3 Properties

Config merging was there in Yii 2 advanced app template. It was moved to composer plugin. And yes, this thing is kind of magical but alternative is manual config merging that I don’t like. As for caching, DB schema cache was not that magical compared to what is there in Symfony.

Thank you for that. I was thinking a lot about it and sorry if I hadn’t communicated clearly why it went the way it went. In case of not having Cache decorator:

  1. We’ll have to copy-paste what’s in the decorator for every cache backend then: array, memcached, wincache, apcu etc.
  2. In case of need to use third party PSR cache backend, user would be required to implement adapter first. Now it could be used right away.
  3. Current structure potentially increases non-Yii usage of cache packages which is beneficial to potential contributions.

Another thing with cache is that it’s a library that isn’t strictly tied to Yii itself. It could be used separately. As for refactoring, I guess you are referring more to splitting individual drivers into their own packages. There are benefits in doing that:

  1. Ability to release separately from other code.
  2. Ability to specify platform dependencies in composer.json.
  3. Potentially more usage by PHP community as a whole thus more contribution.

So yes, indeed in case of cache it become a bit more complicated in initial configuration but

$cache = new Cache(new ApcuCache());

instead of

$cache = new ApcuCache();

is a very low price to pay for benefits gained.

Also such trade-offs are mainly introduced where PSR interoperability is considered or libraries are meant to be used out of context of Yii as a framework. In yii- packages that’s not the case (or at least I’m trying hard to keep these extra layers under control).

Reviewing more from Yii 3 would be certainly helpful.

1 Like

I’m not saying that it is wrong, IMO it is unavoidable at some scale, but this is kind of Symfony bootstrap magic you’re complaining about.

Maybe, I’m not that experienced with Symfony to judge. But situation, when state of schema cache affects list of attributes available in AR model (so cache affects list of properties available in PHP class) is pretty close to worst possible magic.

You could use base class with shared code and implement only necessary methods - it worked in that way in Yii 2 and it was a lot simpler, not mention less code duplication.
Also, current design seems to create some artificial limitations resulting in the worse implementation of some features. For example, APCu has native add support, but ApcuCache is no using it, because add() is implemented at decorator level. So now ACPu backend uses less efficient and non-atomic implementation, ignoring native support of this feature in APCu. There would be no such problem if ApcuCache would implement Yiisoft\Cache\CacheInterface directly.

That is a good reason why decorator is implemented, but not explain why it is required by Yii backends. Yii backends could implement interface directly, and decorator would be required only for 3rd-party implementations.

I’m not sure how few additional methods in PSR implementation could change that.

Actually, this is the only part of this refactoring I like. :wink:

1 Like

Yes. Still, AR is exactly that if you need any acceptable level of performance. I guess that’s one of the reasons explicit mapping got popular despite being more cumbersome to handle.

Correct. See ↓

It’s not required by cache backends if you meant that. cache and cache-apcu (or any other cache package) aren’t inter-dependent now. Implementing decorator directly would:

  1. Cause specific cache packages to depend on main cache.
  2. Code duplication since we still need separate decorator.

If these issues are solved (or considered not important), I’m fine with having cache backends implement additional methods such as add() in a storage-specific manner.

You are correct. That is not a problem for our case.

I don’t think that performance is the problem. Defining list of attributes and its types at PHP class level could save some cache-related WTFs and improve performance (no need for extra queries to fetch schema).

It is required if you want to target Yiisoft\Cache\CacheInterface in your app. If you want only Psr\SimpleCache\CacheInterface, then you have plenty of existing packages, Yii implementation does not give any additional value.

I don’t think this is a problem. yiisoft/cache does not have any additional dependencies, there is no technical problem with requiring yiisoft/cache by yiisoft/cache-apcu.

This is true, but:

  1. It could be limited by using base class for all classes implementing Yiisoft\Cache\CacheInterface, so only a few proxy methods would need to be declared.
  2. There is already a lot of code duplication (key or ttl normalization, redundant exceptions). I believe that using Yii 2 architecture (base cache class extended by specific backends) will reduce code duplication compared to current state of Yii 3 cache packages. Just compare APCu implementations (one of the simplest backends - does not even need serialization): Yii 2 vs Yii 3 - which one is simpler?

This way you’ll loose main benefit of AR: dynamic schema introspection. You’ll essentially move it very close to data mapper.

I’ll take some time to see if cache can be revised: https://github.com/yiisoft/cache/issues/35

What do you mean by that? The fact that list of available attributes in AR depends on state of DB is not a feature for me - it is a problem. AR is usually a base of model layer in the app, it is not good if you can’t relay on it as a type and its behavior depends on DB (and cache) state. In practice it is just another thing to worry about, because in most cases app will not work if DB state (or schema cache) is not in sync with PHP code (you may try to read value from non-existing column).

There is more code in Yii3 version because several issues that were in Yii2 were fixed. The code is the same except those fixes.

1 Like

What issues? If there are bugs in Yii 2 implementation, they should be fixed there too. But I’m seeing mostly redundant keys and ttl normalization.

https://github.com/yiisoft/yii2/issues/17292 for example

I’ve meant that schema introspection and dynamic properties is one of the core concepts of Active Record as a pattern. I’m not saying it’s good. It’s, indeed, brings some problems.

That is one extra line of code. :smiley:

Thanks for posting this - What I have been concluding based on discussions here after studying the “history” of Yii3 posts and trying to sort out what’s where on github.

One other point I will add: while openness and maintainability are excellent goals, that has to be balanced by practicality in “real-world” projects. I once created a graph of a node.js project charting the full dependency tree - probably unsurprisingly, it was so complex as to be un-parasble. Now every time I install a set of node requirements for a project, I get all sorts of warnings about security issues in code I have no concept of or time to investigate.

Yii3 is headed down a similar path it appears. While I understand the reasoning, there is a very strong case for having a “core” project or codebase, or a small set of packages - fewer dependencies, and much lower risk from unintended consequences when doing updates. I have an application running in production today which handles 200-300k new database records a day, and can handle most user queries in under 100ms, and I have all of ~15 direct requirements in my composer.json. I know what all the packages are, what they do, and what the potential impacts are from running an update. I don’t know all their dependencies in detail, but at a high level I know what projects they come from and why they’re there, and could go spelunking if I needed to.

Contrast that with the 8+ hours I spent dealing with working around some node.js code that was crashing due to being unable to parse some file 12+ links deep in the dependency tree that came from a package whose function was not in any way germane to the code at hand.

I found Yii2 due to looking for something that implemented AR in PHP. I’ve used it for many years due to its superior architecture and design (somehow completely ignored in the “agile” world, but massively important on large projects), general simplicity of use, and high performance being able to be maintained at scale more effectively than other PHP or even non-PHP approaches.

So in the end, I need a framework that checks certain arcitectural / pattern boxes, like active record. If I can’t find such a framework, I’ll write one, or pick a different tool that does what I need.

I am actively engaged in the early stages of a major development effort now planned to target Yii2 (don’t think 3 will be released soon enough, which is fine). The current state of Yii3 discussions is giving me pause. I have already started a team off on a trade study to investigate alternates and have been leaning toward picking something other than Yii2, or forking it in such a way as to maintain some of the features above. The study is not yet complete, but I have been proceeding under the assumption that Yii3 will not meet our needs and will require too much extensive re-work of existing code to justify the investment in new development, especially as key architectural tenets are being altered. (architecture changes == expensive)

That is not to say that all the ideas are bad. But there seems to be such a great emphasis on addressing a specific set of challenges (maintenance issues, “portability” to other projects, etc.) that the core of what differentiates Yii (a particular approach to architecture) is being lost in the noise.

So if there is some room for debate on that point, perhaps it is worth re-considering, but until I saw this post I had lost all hope that there was any future in Yii or any point in pursuing further development.

Just my $0.02…

2 Likes

No. Not that extreme. We aren’t going to have leftpad. We aren’t going to depend on many external packages that are of questionable quality.

Isn’t it better to maintain these without forking?

I completely agree with you @rob006. @samdark we’ve to balance between having every part of the framework can be used in different php projects which are not necessarily Yii, and between keeping the spirit of Yii.
IMO as @rob006 I don’t need to write a fast code in Laravel that will take me weeks to maintain.
And on the same time the framework should keep the framework nature, it’s not just a collection of libraries, if our goal is to just have list of libraries we can go with a composer based php project from scratch.
@samdark one more point as many folks mentioned regarding the Java / Spring Boot Style for code, that’s really an old fashion, unreadable / and boilerplate style. IMO the component-based style of Yii2 is a good thing and provides uniqueness / control for our code. Actually even in Java to avoid these parts there’s now libraries / annotations like Lombok which will implement the setter/getter nature for you. Another point really that Yii2-rest is one of the greatest rest framework ever among multiple frameworks / languages.

The main lesson in Yii 1 and 2 was to kill routine jobs, and that appears in multiple areas in the framework, but in Yii 3 I can confirm that many routine / repetitive will happen starting from setters/getters.

I believe we’ve to keep the uniqueness of Yii 2 features to keep as is in Yii 3, and for junior / middle level developers its their responsibility to have more effort following best practices, there’s no guarantee at all that you can prevent / limit less skilled programmers doing bad practices and no framework can guarantee that.

2 Likes

I love the monolithic approach of Yii2.
I love Yii2 magic, primarily for AR.
I love Yii2 API.
But I agree source code splitting, autoloading, application configuration, separation libraries and as @anasjaghoub says:“keep the uniqueness of Yii 2 features to keep as is in Yii 3…”
Now I’m worried about loosing many of the features of Yii2 in the next Yii3.
Many of us have Yii2 projects in production and many new projects to start and the more we have consciousness of what and how will be the transition, the less we will have problems to apply It.
Balance, balance, balance!!
@samdark less is more! :wink:

@anasjaghoub, @mikem If you like Yii2 and it enough for us, maybe you don’t need Yii3 ? Yii2 is not dead, but it hit a wall.
Yii3 doing good step forward. Separated libraries allow to use it without big core, and build app with only necessary dependencies without overhead, for ex as api or console. PSR-standarts allow to use more libraries without adapters. It don’t be same as nodejs modules. As i know Cycle ORM can be used as AR and it less complicated then Doctrine at whole. Also yii2 AR can be ported too, but may be later or as third party. I think after then yii3 became more stable and some starter-kits and scaffold-generators will be adapted, it can make better impression.

About magic getters/setters in some cases, for ex. DTO, etc… these are not bad. But when it in even core class - sometimes it make a pain. And also with good IDE getter/setter generation is very fast.

So a few thoughts -

  • “Separated libraries allow to use it without big core” => I don’t mind this, as long is there is also some place a common set of these libraries are tested and released as a versioned whole. But make no mistake - you’re trading increased risk of emergent / unintended bugs for the “composability” of the libraries. There isn’t a right or wrong answer, but at least be aware of the downsides too. There are good reasons to keep things in a “core” package, but that isn’t the only way to do it. However, without some level of integrated testing, all I have is a bunch of libraries that will likely break something somewhere every time I run “composer update”. I already have that with the core vs packages external to yii. So this is likely to make that issue worse, not better.

That doesn’t mean that it shouldn’t be done, that just means that the implicit benefit of having a core library must now be made explicit in some other manner. This is a key benefit to having a framework in the first place - stability / reliability of non-application-specific foundational code.

But as it is structured now, not yet a step forward - though it could be eventually.

  • “PSR-standards allow to use more libraries without adapters” - that’s great in principle, however of the 37 sub-packages I have in @common\components right now which also had public libraries I could have used instead, lack of “PSR-standards” compliance was not the driving issue in any case for why a class was added to the app vs. just using github. That may or may not be common experience, but in all the years I’ve used Yii2, I have yet to come across PSR compliance as a show-stopper for using a third-party component. Feels like a problem in search of a solution. PSR compliance is not bad, but if I have to give up the AR library or being able to go to functioning app logic in minutes to get it, I’m not going to care much about PSR compliance. Again, everything is a trade…

  • “It don’t be same as nodejs modules” - I used very early versions of nodejs. It didn’t start out the way it is now either, and the current state wasn’t exactly planned. I’m not worried about this at launch, I’m worried about it when I run “composer update” a year from now. Look at the length of the list of dependencies installed in Yii2.0.1 vs. now. I’m not sure it has gotten shorter…

  • “As i know Cycle ORM can be used as AR and it less complicated then Doctrine at whole” - Sure, except I already have 200k+ lines of Yii2 AR code AND a custom AR generator that works off of swagger files. The issue isn’t whether or not Cycle ORM works or how complicated it is - I’m not comparing it to Doctrine, I’m comparing it to my production code that I will end up having to port. The comparison / issue that matters here is the fact that you are deprecating a key component of the framework, which happens to be where a good portion of application code tends to live, and with no clear path to port to the next version to boot. I’m not demanding 100% backward compatibility, but when you make architecture / pattern level changes, the cost of migration for users is significant. These sorts of concerns seem to be being dismissed out of hand, as if there is no value to the current AR library and no impact to changing patterns.

  • “I think after then yii3 became more stable and some starter-kits and scaffold-generators will be adapted, it can make better impression.” - deferring stability and integration to later stage / third party starter kits and code generators does not tend to give one confidence in what should be foundational, reliable code. Again, a large part of the rationale from my perspective for using Yii is that there is a first-party, core / tested library and application management framework (basic / advanced template). Handing me a list of dependencies to install is not the same as handing me a tree which I know has tested all those dependencies in a common set of use cases / an integrated manner that is known to work “out of the box.”

  • " And also with good IDE getter/setter generation is very fast." - If I wanted to use Visual Studio to write PHP, I would… This was tried over a decade ago - In my opinion it doesn’t work, and turns into an unmaintainable mess over time. Having lived through both options, the current approach is superior in almost every way. In fact, I recently completed a PoC using Yii2 that finished almost a week earlier than a similar effort in .Net to implement the same use case, and the lack of getter/setter maintenance and mapping requirements was actually cited as a key reason why we were able to move faster.

Again, just my $0.02…

3 Likes

“No. Not that extreme. We aren’t going to have leftpad. We aren’t going to depend on many external packages that are of questionable quality.”

But if you’re starting to pull in a number of external libraries with their own dependency trees, I’m not sure this is up to you any longer, especially if each library is now maintained independently with minimal integration / testing against other components…

“Isn’t it better to maintain these without forking?”

That depends. If porting from Yii2 to Yii3 exceeds the cost of maintaining a fork, then fork it is. Better is a question of “can I deliver for my customers / users?”. If I spend all my time / budget on a port instead of delivering the features they’ve requested or I’ve discovered they need, or fixing existing bugs, then there’s little point in doing a port to Yii3.

Or, if I’m going to have to re-architect anyway, might as well spend that effort looking at it more broadly than just porting between framework versions. (The cost will generally be the same between porting and doing a next version on a different stack, given the fundamental nature of the proposed changes)

Completely agree. I think revolution instead evolution can kill the Yii.
Yii has great ideas. Why to kill something that works.

Instead of being practical yet simple, it tring to be follow “academic correctness”. But PHP does not work like this, for example until 7.4 Interfaces did not have covariance, which made them impossible to use in real life. I feel that Yii2 follows “PHP spirit”, being resonably magical. But in current state Yii3 becomes to look like Java, with one exeption, it does not have same level of type safety, what makes impossible to create complicated constructions.

I’ve meant maintaining Yii 2, not porting things to Yii 3. Yii 2 is currently maintained and will be maintained for some years so there is no need to fork it: https://www.yiiframework.com/release-cycle