Yii3 Properties


(Oleg) #19

Simple things on the outside often are quite complex inside, and opposite is also true. For example CodeIgniter is much more simple than Yii, buy it is more diffecult to use, for example it is not IDE friendly.

I disagree that simplicity is the main virtue, I think you mix simplicity and well build. Well thought out things usually works as simple possible because complexity adds upp very quickly, and not optimal solutions just would collapse under its weight.

Everything should be made as simple as possible, but no simpler

Original: It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience. Albert Einstein


(Oleg) #20

And I did not say that technical things are not important, it all about technology, I said that every product must have some global concepts, ideology. It helps to synchronize “moving” parts and make work product as one “organism”, not just a set of tools.


(Breg) #21

Einstein speaks about scientific theories, not (technical) constructions.
For these one has to add the phrase ‘for a given task’.
And in a web framework the builders / programmers choose the task.
Now here we discuss what the task is, or should be. You request the kind of simplicity and abstraction that Laravel (seems to) offer, and I prefer more inner simplicity, which I see at Yii.

And no, not every product must have global concepts, there are much more examples that proove this theory wrong than right. What is the global concept in a CNC mill (just to avoid the much simpler and thus maybe misleading hammer example)?


(Oleg) #22

Paragraph 1:
I did not not request simplicity att all, this is you who started talking about simplicity.

Paragraph 2:
I am not talking about tool, I am talking about product. I just believe that Laravel is now leading because of marketing. this happens often in real world, this is not enough to be good, the product also need to be “sexy”/“appealing”.

Think not about CNC mill, but about brands of CNC mills. For example some brand can be known for durability, other brand for wide functionality, and another for the price. There are also brands or products for industural or small companies/home use. This is concept. You can not create a CNC mill for home using industrial concept, and Vise Versa.

You started with bikes. Think about Harley vs Ducati, in my opinion they have distinct “global concepts”


(Breg) #23

CNC mills do not need a ‘global vision’, and could not profit from it, that was my point.
Using one for several years - typical, not like a smartphone - the reliability and quality is more depending on your maintenance and attention when you use it. It is important that the various parts can easily be checked, maintained or changed - by the user. You may exchange a bearing here, a stepper motor there, or update to a new controller. After the years, it has more become a ‘Oleg84 mill’ than a ‘XYZ’ brand mill.
So this is very similar to a web framework.

About motorbikes, you chose the right examples - for your POV :slight_smile:
If you believe in a growing market for motorbikes, buy the shares from Ducati (Audi, VW) and Harley.
I had a new Ducati once, and sold it after some years, having spend many hours just to keep it running (because of lack of attention to detail in the construction; with new engines every 1…2 years).
HDs have a stupid riding position, ok for slow and straigt highways, not for eurasian streets, only for posers.
So everyone who really likes the road and the wind would prefer other brands (and old models, with simpler mechanics).


(Oleg) #24

I do not think CNC mills have a massmarket.

Bikes have. Web frameworks have.

Mass market means, in my opionon, also lot of neophites. If professionals use rational thinking, neophits are driven by emotion. Thats why Web Framework needs to have some nice “Philosophy” - to attracts new blood. When I say philosophy I do not mean “the system”, I mean more a slogan. Nike - “Just do it”. Or Communism - “Same rights and level of living for everyone”. But then we can unpack this short stories in a whole philosophy. But this is only one small aspect of a big thing, it was just an example how “Global vision” could be usefull.


#25

@olegl84 @ED42 Please move this discussion to email or slack - it has nothing to do with this topic.


(Oleg) #26

In my opinion the current biggest problem of Yii is that it is not considered as suitable for big projects. And this is not far from true.


(Oleg) #27

yes, It went too far :slight_smile:


(Breg) #28

Sorry, the discussion is still about the core topic:
“The thing is that I don’t want Yii to continue being closed community. … Yii 3 is meant to work with any PHP classes without wrappers and to reuse PSR-compatible libraries.”

@Oleg, I don’t see Yii as a product in a market. It’s free.
Other frameworks have collected money on the investor markets and play or mimic the startup game. Their choice, but not a neccessary property of a web framework.


(Mike) #29

I was just going to open an issue for yii3 for a way how properties could work, when I found out that things there changed quite drastically since yii2. So let’s try here:

I also think that a trait for properties could be useful somewhere in the core. Here’s my suggestion.

Problem

I often find myself writing a pattern like this:

protected $_foo;

public getFoo()
{
    if ($this->_foo === null) {
        // Initialize $this->_foo here:
        $this->_foo = 'initial value';
    }
    return $this->_foo;
}

public function setFoo($value)
{
    $this->_foo = $value;
}

This pattern is:

  • repetitive
  • bloats the class with 2 methods per property

Proposal

I therefore suggest an alternative way of defining these properties. The above would be equivalent to:

public function props()
{
    return [
        'foo' => function() {
            // Initialize value here
            return 'prop value'; 
        },
    ];
}

For more complex properties an alternative array syntax can be used:

public function props()
{
    return [
        'bar' => [
            'readOnly' => false, // default
            'init' => function() { 
                return 'prop value'; 
            },
            'validate' => function ($value) {
                // Either return false or throw exception for invalid values
            },
            // more options ??
    ];
}

Pros

  • Less repetition
  • Less code and thus less bloat
  • All properties are defined clearly at a single location

(Alexander Makarov) #30

You forgot property annotations you need to have in order to get IDE autocomplete.


(Mike) #31

Can’t we add them in the class comment header as usual?

/**
 * ....
 *
 * @property string $foo some foo for bar
 */

(Alexander Makarov) #32

We can. I’m pointing to “less” points.

In case of plain class that’s:

class Post
{
    private $title;

    public function __construct(string $title = '<please write some text>')
    {
        $this->validateTitle($title);
        $this->title = $title;
    }

    public function getTitle(): string
    {
        return $this->title;
    }

    public function setTitle(string $title): void
    {
        $this->validateTitle($title);
        $this->title = $title;
    }

    private function validateTitle(string $value)
    {
        if (mb_strlen($value) > 255) {
            throw new \Exception('invalid!');
        }
    }
}

In case of your variant it’s:

/**
 * @property string $title
 */
class Post
{
     use PropertyTrait;

     protected $_title;

     private function properties(): array
     {
         return [
             'title' => [
                 'validate' => function ($value) {
                     if (mb_strlen($value) > 255) {
                          throw new \Exception('invalid!');
                     }
                 },
                 'default' => function() {
                     return '<please write some text>';
                 }
             ]
         ];
     }
}

First variant is a bit more verbose but is way less magical.


#33

Not really. With getter and setter you also have 2 methods which could be part of interface for example. And syntax is clear and obvious, while props() approach is another magical solution which needs to be learned.

In general I would recommend to NOT use magic attributes whenever possible. They may look like a great idea at first look, but the bigger the project, the more WTFs you will get. Using getters and setters directly usually gives less confusion (for both - programmers and SCA tools) and saving 3-5 chars is not worth the trouble.


(Mike) #34

Well I agree to all you said. But on the other hand this means that Yii 3 will be quite different from all its predecessors. In my view one of Yii 1 and 2’s goals was to let you write code that keeps boilerplate at a minimum. Remember one of its marketing claims was “Less noise - more signal”. I liked that a lot.

Looking at Yii 3 I understand the motivations and goals (SOLID, GRASP, etc.) and also think that’s the way to proceed. But this also comes at a cost: It often means that code get more “java-ish” which equals to more noise in your code. I’m curious if this can be solved so that we can keep the Yii feeling we all like.

On a sidenote: If magic methods are avoided (which I can understand), how will this affect ActiveRecord? With PRADO (Yii’s predecessor) we had to define all DB columns as public properties of your class. IMO this would be an acceptable tradeoff. Or will there be any AR implementation in Yii 3 at all?


(demonking) #35

Because of AR, at the moment no implementation are planned.

Discussion : Using Cycle ORM

Reason : Using Cycle ORM


#36

I wouldn’t say that using getter explicit is a noise. It is actually signal - it shows you what is really happening. For example it is quite strange that you can’t use $this->someArray['someKey'] = $someValue;. But it becomes more obvious if you write it as $this->getSomeArray()['someKey'] = $someValue;.

In general I don’t think that magic attributes are that important to keep “Yii feeling”. I would be more concerned about removing some known patterns (Yii::$app - it may be ugly, but is is really convenient and easier to understand and control in small projects) or parts of original framework (URL manager, AR, console).


(Lazarevic Ivica) #37

I hate writing Java classes with bunch of trivial getter and setters. Also I hate Java for spending more time configuring than programming. I hope Yii3 is not following Java path.


(Alexander Makarov) #38

I am as well :slight_smile: Will try to avoid unnecessary boilerplate where possible but not at the cost of clarity of what actually happens.

Active Record is an exception there. Can not be done without some magic in case we don’t want to define properties manually.

Maybe.

Yii::$app is a bad and convenient thing at the same time. It is extremely easy to misuse resulting in testing and maintenance hell. In your apps you’ll be able to do it easily if needed though by defining a global class holding container right in index.php.

Current URL manager is different but porting old good one is possible. It is not a priority for me personally though since interface is in place and it works by leveraging FastRoute.

As for AR and console, sadly, I don’t have enough time to port these myself. But if there will be someone willing doing that, I’ll help with reviews, directions and will gladly accept it as part of the framework.