【问题标题】:PHP: Issue with parameter type hinting when class is namespacedPHP:类命名空间时参数类型提示问题
【发布时间】:2013-07-11 13:54:53
【问题描述】:

这失败了(编造的代码):

namespace Season\Summer;

class Summer
{
    public static function days(string $month)
    {
        // ...
    }
}

与:

"Argument 1 passed to Season\\Summer\\Summer::days() must be an instance of string, string given, called in /path/to/Seasons/Summer/Summer.php on line 5."

似乎命名空间导致 PHP 的内置类型提示出现问题,因为我认为它正在检查参数 $month 是标量类型 stringSeason\Summer\ 而不是 string 的全局定义(我可能错了) .

我该如何解决这个问题?解决办法是什么?函数内部给我们is_*()

【问题讨论】:

    标签: php types type-hinting


    【解决方案1】:

    PHP 不支持 string 作为类型提示。如果您需要 $month 作为字符串,请从方法参数中删除字符串,将其强制转换或使用 is_string() 检查它是否为字符串:

    namespace Season\Summer;
    
    class Summer
    {
        public static function days($month)
        {
            $month = (string) $month;
            // or
            if (! is_string($month)) {
                throw new Exception("Argument $month is not a string.");
            }
        }
    }
    

    Documentation can be found here

    【讨论】:

    • 就是这样 - 谢谢。我已经更新了答案,以便更清楚地供将来参考。
    • 由于 PHP 7 的发布,是时候更新这个答案了。
    【解决方案2】:

    我已经注册了一个自己的错误处理程序,看起来像这样:

    namespace framework;        
        class Error {
    
            static $arHintsShorts = array('integer'=>'int', 'double'=>'float');
    
        public static function execHandler( $iErrno, $sErrstr, $sErrfile, $iErrline ) {
    
    
        if ( preg_match('/Argument (\d)+ passed to (.+) must be an instance of (?<hint>.+), (?<given>.+) given/i',
                                    $sErrstr, $arMatches ) )
                    {
                        $sGiven = $arMatches[ 'given' ] ;
                        $arHints =  explode( '\\', $arMatches[ 'hint' ] );
                        $sHint  = strtolower( end($arHints) );
    
                        if (isset(self::$arHintsShorts[$sGiven])) {
                            $sGiven = self::$arHintsShorts[$sGiven];
                        }
    
                        if ( $sHint == strtolower($sGiven) || $sHint == 'mixed' || ($sHint == 'float' && $sGiven == 'int')) {
                            return TRUE;
                        } else {
                            if (self::$oLog != null) {
                                self::$oLog->error($sErrstr . '(' . $iErrno . ', ' . $sErrfile . ', ' . $iErrline . ')');
                            }
                            throw new \UnexpectedValueException($sErrstr, $iErrno);
                        }
                    }
    
            }
        }
    
    set_error_handler(array('framework\error', 'execHandler'), error_reporting());
    

    它处理所有原始类型,尽管在命名空间类中。

    【讨论】:

      猜你喜欢
      • 2016-05-22
      • 2015-12-14
      • 2022-12-31
      • 2019-03-24
      • 1970-01-01
      • 2016-06-26
      • 2014-08-12
      • 2013-06-01
      • 1970-01-01
      相关资源
      最近更新 更多