yii2mod / yii2-enum

Enumerable helper

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Why don't use 『late-static-bindings』,this implementation is not correct in some condition

ihipop opened this issue · comments

$class = get_called_class();

http://php.net/manual/en/language.oop5.late-static-bindings.php

this feature was introduced as of PHP 5.3.0.
I'm using which PHP 7.1 is also worked well .

this is your code:

 public static function listData()
    {
        $class = get_called_class();
        if (!isset(self::$list[$class])) {
            $reflection = new ReflectionClass($class);
            self::$list[$class] = $reflection->getStaticPropertyValue('list');
        }
        $result = ArrayHelper::getColumn(self::$list[$class], function ($value) {
            return Yii::t(self::$messageCategory, $value);
        });
        return $result;
    }

In these codes,there are a piece of unnecessary logic and a potential bug. Both of them is caused by the coder not use late-static-bindings when it is necessary

  1. If you want to get the really instantiated class‘s static property $list So,you use Reflection to get the really called class name and get the $list (static property)。
    But this could be done by "late static bindings" mentioned above all you just need to do is to use static::$list to get the value you want.
  2. The use of Yii::t(self::$messageCategory, $value); also cause a bug in some condition,
    for example,In you project yii2-settings,You overwride the static property $messageCategory here
    But, In base class BaseEnum in this project ,You use
Yii::t(self::$messageCategory, $value);

not

Yii::t(static::$messageCategory, $value); 

which caused the self::$messageCategory === 'app' is always ,will cause the i18n fail to work in yii2-settings when calling this code

And Use array_map to replace ArrayHelper::getColumn is much more efficient,(in this condition),IMO

The fix is very Simple,here is one Suggested version

 public static function listData()
    {
        return ArrayHelper::getColumn(static::$list, function ($value) {
            return Yii::t(static::$messageCategory, $value);
        });

    }

There are some same problems in other line of codes,wish a new fix version:)

so i18n issue here is related 5786e51 #1

commented

@ihipop thanks for the issue. As far as I remember we were not able to move forward with static solution because of HHVM incompatibility, not sure is it possible now though.

@disem
I don't know very much about HHVM compatibility,
But In Yii2, there are very much static:: call https://github.com/yiisoft/yii2/blob/c19b2f7dc8f487f0a867f2cacab68b8e86b7a8f9/framework/base/Application.php#L197
https://github.com/yiisoft/yii2/blob/c19b2f7dc8f487f0a867f2cacab68b8e86b7a8f9/framework/BaseYii.php#L275
and ,You are identified as a Yii2-extension run upon Yii2....

and If you keep using Yii::t(self::$messageCategory, $value); in listData() the i18n issue 5786e51 won't work when you set your $messageCategory in Your other yii2 products such as yii2-settings here

consider a fix for this at least.
@igor-chepurnoi

Hi, thanks for issue. I am going to check it today

Resolved by 7af030e

@igor-chepurnoi I think you are a bit more overreacted

  1. If you plan to design a property as a private property ,and don't intent to be overwride by subclass, it should be keep is as it is ,you replace all self:: to static:: ,This is a bit crazy ..
    Every usage of self:: or static:: has it's own condition,None of them is a silver bullet.
    for the i18n issue related ( 5786e51 and #1 ),You have designed the $messageCategory could and should be override by subclass,so the useage of static:: is necessary .
    This doesn't mean that every self:: should be replaceed by static::
    Even in Yii2 framework, the useage of static:: is strictly restricted to the static property or method Intent To could be (or should be ) overide by subclass ,the abuse of static:: will cause some problems especially for some Core logic.
  2. why remove PHP 5.4-7.0 in travis ci ? late-static-bindings works well in this versions
  1. I replace on static call because I found places in my own code where self does not work properly. I changed the private -> protected because is a more flexible solution. For example
  2. I remove all php versions except 7.1 because travis was update phpunit version, that works only for php 7 version.

Thanks for your effort~ 💯
@igor-chepurnoi

Many thanks for your suggestions!