Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Не понятная ошибка
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Не понятная ошибка

Страниц (1): [1]
 

1. Anguis - 15 Января, 2019 - 13:26:14 - перейти к сообщению
Всем привет.
После обновления (не знаю точно с какой версии) до php 7.3.0 появилась ошибка. Всю голову сломал откуда она и почем до обновления все отлично работало.
есть простенький класс, для конвертации валют:
PHP:
скопировать код в буфер обмена
  1.  
  2. class currency{
  3.  
  4.   static $curr;
  5.   private static function get($q){
  6.     return self::$curr->$q;
  7.   }
  8.  
  9.   private static function to($n,$c){
  10.     return $n * self::$curr->$c;
  11.   }
  12.  
  13.   private static function from($n){
  14.     return round($n / self::$curr->{$_COOKIE['curr']},2);
  15.   }
  16.  
  17.   private static function get_rate($c){
  18.     return self::$curr->$c;
  19.   }
  20.  
  21.  
  22.  
  23.   static function __callStatic($modname,$args){
  24.     self::$curr = (object)['RUB'=>1,'USD'=>67,'EUR'=>77];
  25.     return call_user_func_array([__CLASS__ , $modname],$args);
  26.   }
  27. }
  28.  
  29. var_dump(currency::from(16));
  30.  

Этот код вызывает ошибку:
CODE (htmlphp):
скопировать код в буфер обмена
  1.  
  2. Fatal error: Uncaught ArgumentCountError: Too few arguments to function currency::from(), 0 passed
  3.  

При этом вот так все прекрасно работает:
PHP:
скопировать код в буфер обмена
  1.  
  2.  static function __callStatic($modname,$args){
  3.     self::$curr = (object)['RUB'=>1,'USD'=>67,'EUR'=>77];
  4.     $a=[16];
  5.     var_dump($a == $args); // TRUE
  6.     return call_user_func_array([__CLASS__ , $modname],$a);
  7.   }
  8.  

WTF?? Не понял
А еще интересно что манипуляции типа такого, тоже приводят к той же ошибке!
PHP:
скопировать код в буфер обмена
  1.  
  2. static function __callStatic($modname,$args){
  3.     self::$curr = (object)['RUB'=>1,'USD'=>67,'EUR'=>77];
  4.     $a=array_values($args);// не помогает
  5.     foreach($args as $arg){$a[]=$arg;}// тоже самое
  6.     return call_user_func_array([__CLASS__ , $modname],$a);
  7.   }
  8.  


Что самое интересное, есть похожий код в другом классе где та же самая конструкция call_user_func_array([__CLASS__ , $modname],$args); прекрасно работает!

Помогите кто чем может, уже третий час долблюсь - ни фига не понимаю!
2. Мелкий - 15 Января, 2019 - 13:48:31 - перейти к сообщению
Выкинем лишнее, добавим недостающее:

PHP:
скопировать код в буфер обмена
  1. class currency{
  2.  
  3.     private static function from () {}
  4.  
  5.  static function __callStatic($modname,$args){
  6.     var_dump($modname, $args);
  7.   }
  8. }
  9.  
  10. currency::from2(16);
  11. currency::from(16);
  12.  


И видим чтобы вы подумали...
Спойлер (Отобразить)
3. Anguis - 15 Января, 2019 - 13:59:21 - перейти к сообщению
Мелкий, очень интересно! А что это такое? Где я упустил такое поведение. почему раньше работало? Вообще ни чего не понимаю! Вывод то идет array(1) {}
Т.е. как бы он видит что один аргумент присутствует, но вот самого аргумента нет.
Прошу пните в мануал!
4. Мелкий - 15 Января, 2019 - 14:14:47 - перейти к сообщению
сдаётся мне путь вам прямиком в bugs.php.net
Это чудесный пример регрессии с простым и понятным reproducer, при том явно не запрещённым в документации.
На 7.2.4 похоже ещё работало (из ближайшего online sandbox), а я что-то разучился php компилировать
5. Anguis - 15 Января, 2019 - 14:26:37 - перейти к сообщению
Потрясающе! То то я все мануалы перерыл и ни малейшего упоминания о таком чудесном поведении не сыскал!
P.S. bugs.php.net походу не работает Недовольство, огорчение Эх, жаль конечно, но по всей видимости пых переживает не лучшие времена... Переживет ли?.
6. Мелкий - 15 Января, 2019 - 14:42:59 - перейти к сообщению
да нет, живой вроде: https://bugs.php.net/report.php если я случайно опечатался в адресе.

Вспомнил как собирать, в мастере уже починили, может и в уже вышедшем 7.3.1 исправлено, собирается пока. У меня 7.3.0 ещё был
(Добавление)
7.3.1 так же баг, исправление есть в ветке 7.3, то есть войдёт в 7.3.2 релиз и далее.

Anguis пишет:
по всей видимости пых переживает не лучшие времена...

Это фигня. В первых минорных релизах всегда что-нибудь весёлое может случиться.
Для первых минорных релизов мы и postgresql не советуем ставить свежей major версии в бой. А там код поприличнее на мой субъективный взгляд автора пары патчей.
7. Anguis - 15 Января, 2019 - 15:39:09 - перейти к сообщению
А я уж было подумал переписать класс на синглтон. объявить методы не статическими и в __CallStatic создавать/возвращать экземпляр и выполнять его метод. Только переписывать нужно не один класс..

Зашел на bugs.php.net через проксю. Роскомнадзор невзлюбил девелоперов? Но коль скоро будет исправление, думаю писать тудой уже нет смысла. А было собрался.

Короче СЛОВЕД Радость
8. MouseZver - 22 Января, 2019 - 11:07:56 - перейти к сообщению
Anguis пишет:
А я уж было подумал переписать класс на синглтон. объявить методы не статическими и в __CallStatic создавать/возвращать экземпляр и выполнять его метод. Только переписывать нужно не один класс..

Зашел на bugs.php.net через проксю. Роскомнадзор невзлюбил девелоперов? Но коль скоро будет исправление, думаю писать тудой уже нет смысла. А было собрался.

Короче СЛОВЕД Радость

Для 2к19:
PHP:
скопировать код в буфер обмена
  1. <?PHP
  2.  
  3. class currency
  4. {
  5.         private static $curr = [ 'RUB'=>1, 'USD'=>67, 'EUR'=>77 ];
  6.        
  7.         private static function get( string $q )
  8.         {
  9.                 return self::$curr->$q;
  10.         }
  11.  
  12.         private static function to( int $n, string $c )
  13.         {
  14.                 return $n * self::$curr[$c];
  15.         }
  16.  
  17.         private static function from( int $n )
  18.         {
  19.                 return round ( $n / self::$curr[$_COOKIE['curr']], 2 ); # откуда куки то берется ?
  20.         }
  21.  
  22.         private static function get_rate($c)
  23.         {
  24.                 return self::$curr[$c];
  25.         }
  26.        
  27.         public static function __callStatic( $modname, $args )
  28.         {
  29.                 return self::$modname( ...$args );
  30.                
  31.         }
  32. }
  33.  
  34. var_dump(currency::from(16));

 

Powered by ExBB FM 1.0 RC1