I find your lack of data-value objects disturbing

What are you doing to me, Yii?

https://www.yiiframework.com/doc/api/2.0/yii-widgets-menu

echo Menu::widget([
    'items' => [
        // Important: you need to specify url as 'controller/action',
        // not just as 'controller' even if default action is used.
        ['label' => 'Home', 'url' => ['site/index']],
        // 'Products' menu item will be selected as long as the route is 'product/index'
        ['label' => 'Products', 'url' => ['product/index'], 'items' => [
            ['label' => 'New Arrivals', 'url' => ['product/index', 'tag' => 'new']],
            ['label' => 'Most Popular', 'url' => ['product/index', 'tag' => 'popular']],
        ]],
        ['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest],
    ],
]);

How about using a MenuItem class instead of putting everything in associative arrays? Arrays like these are not type safe and does not communicate intent. Further more, you can’t use inheritance to make subclasses of different types of menu items. Associative arrays lead to spaghetti code and does not scale well.

Edit: Some links:

Edit 2: One patchy solution to this could be using objects with ArrayAccess implemented.

Edit 3: Remember that our project is HUGE. First commit from 2003, 200+ contributors. It’s not a web page, but a scientific web app.

If you had been around since the very beginning of Yii, when @qiang started writing Yii after having created PRADO, you’d know that there are good reasons for Yii using e.g. arrays for things like this and many other parts of Yii as well. It was intentionally made more lightweight.

If you think about it, it could have abstracted a lot of other arrays as well into classes of different type. But it hasn’t done that, and I think it’s good. There’s no point overengineering.

Instead, you are completely free to create classes for this if you want or need to, and as you mentioned yourself, just make them arrayable. That should solve your problem unless I’m missing something.

The point I’m trying to make is that Yii is a framework that is pragmatic yet nicely designed, but part of this is not overengineering such as in this case. Simply go ahead and extend your menu stuff with classes if you want to. This makes sense in your large project, but it doesn’t make much sense for the tons of smaller projects that have a simpler menu.

3 Likes

Thanks for answering! One has to wonder which project size Yii is optimized for, though.

Why would it matter what the project size is? Project size isn’t what dictates how well you write your code.

1 Like

Well, type-safety might be worth it or not depending on size and time. Longer/bigger --> type-safety brings stability. Especially if lots of people will read the code and extend it for 10+ years.

Perhaps you want a more opinionated framework than Yii, as someone else suggested in some other thread.

Not possible. Both programming languages and frameworks have a strong lock-in. But superpose our internal “opinions” on top of Yii might be the solution. If we can agree in the team. :laughing:

You already have the tools to do what you need, so there’s not much to agree on is there? :slight_smile:

Just an example of how readability can be improved by using objects.

There was a reason not to wrap everything in objects. First of all, it was not cheap with the PHP versions that were there at Yii 1.1 and Yii 2.0 creation times.

In Yii 3 we are moving to way more strictness while trying not to lose overall feeling of simplicity (with mixed success).

3 Likes

You have a link to this?

Yep, it’s not always easy or obvious which kind of interfaces are correct, or how to design interfaces. In my screenshot above I’m passing an array $options to the constructor. This still has several benefits over associative arrays, like default values, validation, immutability, encapsulation and type-safety (even if it’s mostly a “tag” on a data package). Named arguments would probably make the $options array obsolete.

To Yii 3? Entry point is at https://github.com/yiisoft/app. Docs are at https://github.com/yiisoft/docs.

Nice. But no CMenu or similar? Or how would you exemplify “more strictness” in relation to Yii 1 and 2? I see that the FlashMessage widget accepts not an array of data but explicitly typed objects in the constructor instead. https://github.com/yiisoft/app/blob/master/src/Widget/FlashMessage.php :+1:

Bascially simplicity is a virtue.

Then maybe Yii is not the ideal framework for you?

As stated above, frameworks have lock-in symptom. It’s not easy to switch in an enterprise setting.

I’d argue associative arrays are not more simple than classes. :stuck_out_tongue:

The idea may have been that more logic/structure is visible in one code piece.

But ok, for new code and nowadays, one would rather go your way.