Unset variable not recognised in local project, but flagged in remote file

  • ALM used: GitHub
  • CI system used: Local Visual Code Studio with SonarCloud integrated
  • Languages of the repository: PHP
    Error observed

Unset variable not flagged in local project/file, but correctly flagged in remote file (edited in same editor).

  1. In my local VCS WorkSpace (SonarCloud fully integrated and properly working), the $variable that is never set is not flagged (neither in “errors” tab, nor as underlined/highlighted error). It only tells me unset $var when I hover the variable.
  2. The same file but from remote server, edited in the same VCS, does correctly highlight the unset $var as an error, and when hovering it, also tells the actual error ID (which in case one is not happening).

Faulty Code:
This is a chunk of a method in a larger class, but, it clearly illustrates that $tier_2 is NEVER defined and can as such not work

public function the_transcript( $post_id = null ) {

		$user      = wp_get_current_user();
		$logged_in = is_user_logged_in();
		$post_id   = null === $post_id ? get_the_ID() : $post_id;
		$field   = get_post_meta( $post_id, 'my-field', true );

		if ( ! empty( $field )
			&& true === $logged_in
			&& ( array_intersect( $this->var, $user->roles )
				|| in_array( $this->return_user_var_value( $user->ID ), $this->$var )
			)
		) {

As we can see, $this->$var cannot work since no $var is ever defined.
And, when editing the remote file, it properly flags it, see screenshot:


(notice the yellow underline, AND the more extensive context when hovering)

However, when editing the file in the local copy of this code (a GitHub repo), then this is NOT flagged properly!


(Notice no yellow underline, and the context is missing, no sonar-lint information, the “error” only becomes clear when hovering the $var). We can however see that SonarLint DOES work on this file, as the function is flagged for naming convention issues!

Note, the code above has been edited for anonymity, which is why the var names do not match what you see in the screenshot

Why does this happen? It is quite bad - it completely defies the purpose of having the linter because the error will happily be committed…

And this gets much weirder.

foreach ( $node->stmts as $stmt ) {
								if ( $stmt instanceof \PhpParser\Node\Stmt\Class_ ) {
									echo "{$namespace}/{$stmt->name->name}\n";
									$this->classes[] = array( $namespace . '\\' . $stmt->name->name );
								}
							}

… it tells me $stmt is never initialised. (!?)

I mean, of course it is not: it is the whole point of a foreach to populate the as $var with the “each” part of the array provided.