Как уловить ошибку о которой умалчивает PHP интерпритатор?
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-код внутри них) до/после загрузки любых скриптов, соответственно.
PhpShtorm для foo1 даст подсветку, что переменная не определена, во втором случае будет считать, что такое присвоение допустимо function foo1()
{
    $bar->test['a']['b'] = 5;
}

/**
*@param  stdClass|object  $bar
*/
function foo2($bar)
{
    $bar->test['a']['b'] = 5;
}
здесь stdClass | object как иллюстрация, что он от них унаследован