18

Migrating from php 7.1 to 7.4. We have like 500 functional tests for an API, and some of them started to fail with an error after the migration was complete. These tests were passing before everywhere, and now fail everywhere - not all, just 39.

Environment information:

  • php 7.4
  • codeception
  • yii2

Stack trace:

...\api\vendor\codeception\codeception\src\Codeception\Subscriber\ErrorHandler.php:83
...\api\tests\functional\SomeFileHereCest.php:72
...\api\vendor\codeception\codeception\src\Codeception\Lib\Di.php:127
...\api\vendor\codeception\codeception\src\Codeception\Test\Cest.php:138
...\api\vendor\codeception\codeception\src\Codeception\Test\Cest.php:97
...\api\vendor\codeception\codeception\src\Codeception\Test\Cest.php:80
...\api\vendor\codeception\codeception\src\Codeception\Test\Test.php:88
... more stuff here, not important

Since ErrorHandler.php:83 this is just catching the error, let's look at the SomeFileHereCest.php:72:

// declaration of the apiPrefix variable in the class.
protected $apiPrefix;
//...

public function _before(FunctionalTester $I)
{
    $this->apiPrefix = $this->config['backend']['api_prefix']; // this is the line 72
    //... more similar stuff later

So the $this->config['backend']['api_prefix'] this is a string("v1")

And I dont see where is the issue with this and how to dig into it deeper. Any ideas?

Dharman
  • 30,962
  • 25
  • 85
  • 135
Random Dude
  • 872
  • 1
  • 9
  • 24
  • 4
    check `isset($this->config)`, `isset($this->config['backend'])` and `isset($this->config['backend']['api_prefix'])` first – delboy1978uk Dec 13 '19 at 11:59
  • 1
    Okay, Idk why, but it didn't load the config in this file - even that the code is not changed at all. So if you create an answer from this I can accept it as a good one, because I could solve the issue with this by calling a load the config function here first, thanks! – Random Dude Dec 13 '19 at 12:10

3 Answers3

22

Sounds like your variable isn't set.

Check with the following isset calls:

isset($this->config); 
isset($this->config['backend']);
isset($this->config['backend']['api_prefix']);

You can actually check multiple vars in one isset call (isset($x, $y, $z)), but this will let you see which var specifically is missing

delboy1978uk
  • 12,118
  • 2
  • 21
  • 39
3

use (??) (double question mark operator) ("null coalescing operator") to avoid unset arrays.

this unit test is giving me "success"

class PhpTest extends TestCase
{
    public function test_php_74()
    {
        //Trying to access array offset on value of type null

        $this->assertSame('7.4.9', phpversion());

        $a = null;
        $this->assertTrue($a ?? true);
        $this->assertTrue($a['a'] ?? true);
        $this->assertTrue($a['a']['a'] ?? true);

        $a = [];
        $this->assertSame([], $a);
        $this->assertTrue($a['a'] ?? true);
        $this->assertTrue($a['a']['a'] ?? true);
    }
}
Yevgeniy Afanasyev
  • 37,872
  • 26
  • 173
  • 191
  • This is usually a bandaid. If the variable is supposed to be set, you don't want to suppress the error. – Barmar Nov 22 '21 at 22:32
0

It is related to PHP 7.4 Issue. The solution is we can put isset in PHP or Laravel Blade Old Code

@foreach ($widgets->get('dashboard') as $widget)
 {!! $widget->render() !!}
@endforeach

New code update with isset

@if(isset($Widget))
@foreach ($widgets->get('dashboard') as $widget)
    {!! $widget->render() !!}
@endforeach
@endif