Megas
@Megas

Как уловить ошибку о которой умалчивает PHP интерпритатор?

Работая над чужим кодом обнаружил баг примерно такого содержания:

function foo()
{
	$bar->test['a']['b'] = 5;
}


Очевидно, что переменная $bar тут не определена и соответственно обращение к ее свойству тут некорректно... но "гибкий" PHP просто создает пустой класс с нужной переменной и нужной вложенностью массива. Даже нотификации не выдает!

object(stdClass)[67]
  public 'test' => 
    array (size=1)
      'a' => 
        array (size=1)
          'b' => int 5


А сколько еще таких багов в коде? Что нужно сделать, чтоб интерпритатор ругался на такое? Директиву какую то прописать? Или в php.ini чтото изменить? На сервере стоит php 7.3
  • Вопрос задан
  • 192 просмотра
Пригласить эксперта
Ответы на вопрос 2
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
1. В начале каждого PHP-скрипта (глобально - не работает!): declare(strict_types=1);
2. Читаем тут и ставим свою перегрузку:
public function __get(string $var) : ?string {
    if (property_exists($this, $var)) {
        return $this->$var;
    }
    
    throw new Exception('property doesn’t exist');
  }

  public function __set(string $var, string $value) {
    if (property_exists($this, $var)) {
        $this->$var = $value;
        return;
    }
    
    throw new Exception('property ' . $var . ' doesn’t exist');
  }

3. В php.ini добавить (дополнить):
display_errors = On
error_reporting = E_ALL | E_STRICT

4. В начало PHP-скрипта добавить:
error_reporting(E_ALL | E_STRICT);
error_reporting(-1);
ini_set('error_reporting', E_ALL | E_STRICT);

5.В .htaccess:
php_flag display_startup_errors on
php_flag display_errors on

6. "Контрольный в голову": https://xdebug.org/docs/basic

7. PHPStan - проверка PHP-кода на ошибки без запуска.

PS: ещё есть также prepend/append скриптов в php.ini для установки любых значений (исполняется php-код внутри них) до/после загрузки любых скриптов, соответственно.
Ответ написан
402d
@402d
начинал с бейсика на УКНЦ в 1988
PhpShtorm для foo1 даст подсветку, что переменная не определена, во втором случае будет считать, что такое присвоение допустимо
function foo1()
{
    $bar->test['a']['b'] = 5;
}

/**
*@param  stdClass|object  $bar
*/
function foo2($bar)
{
    $bar->test['a']['b'] = 5;
}

здесь stdClass | object как иллюстрация, что он от них унаследован
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы