I’m asking this question b/c a certain PHP (and IDE) behaviour confuses me, and I was wondering if anyone can make sense of it. If you are proficient in variable scope questions, then this question is for you!
So I have an index.php file in which at one point I define a variable called $pageKat = "";
and later assign it a value based on certain conditions.
Then I require
another php file from index.php called _actual-content.php.
<?php # index.php
...
$pageKat = "";
...
if (...) {
$pageKat = "foo";
}
...
require __DIR__ . '/_actual-content.php';
The first 11 lines of my _actual-content.php look like this:
<div id="theMan">
<header>
<?php if ($GLOBALS["pageKat"] == "home") echo "<h1 class='h1Home'>"; ?>[REDACTED-HTML]<?php if ($pageKat == "home") echo "</h1>"; ?>
</header>
<nav class="headerMenu" aria-label="Haupt-Navigation">
<ul>
<?php generateMainMenu($pageKat); print_r($pageKat); ?>
</ul>
</nav>
The [REDACTED-HTML]
part is there to make it all easier readable. There’s really just plain static HTML there that generates a logo. It has nothing to do with the question at hand and I’ve redacted it to de-clutter the code block.
Now, as you can see, I am accessing $pageKat three times here (actually four times, if you count the debugging print_r
).
Here’s the weird part:
-
In the first
<?php ... ?>
block, I’m using the $GLOBALS array to access pageKat (as one would expect is necessary). I first tried to access $pageKat, but that doesn’t work, as $pageKat is not in the scope of _actual-content.php (again, as expected). -
In the second and third
<?php ... ?>
block, though, weirdly, I AM able to access $pageKat directly. The IDE (PhpStorm) marks it as "undefined" (with a red wavy line beneath it, again: as expected)… but it works. Theif
statement is processed correctly and the</h1>
HTML is echoed if $pageKat is "home". The generateMainMenu() function is also called correctly and works like a charm, the print_r() dumps $pageKat’s value… all fine.
So my question is: Why? Why does it work? (I tried checking whether you can access a global variable inside a scope "directly" after having accessed it once via $GLOBALS, but this does not seem to be in PHP specs.)
Again, I’m asking this question because I’m trying to wrap my head around how variable scope works, and this behaviour looks completely odd to me. I’m curious what the heck is going on, so if anyone can enlighten me, I’d be very thankful.
(Please let’s not have this question degenerate into a discussion about how bad global variables are. I’m a total noob and I know it, I’ve always loved global vars, and I will fight for their right to exist until my last breath. 😉 This is not the point here.)
2
Answers
The answer is: $pageKat actually is a global var and as such defined in the included .php, OP (me) simply assumed it wasn't because of the wavy red line by the IDE that marked it as "undefined". I'll show myself out.
For final clarification, here's a screenshot of what global variables in included files look like in PhpStorm 2023.1.2:
(Disclaimer: Demonstrating here with a different global variable than the one mentioned in the original q.)
Additional info: Clicking "Add 'global $[variable]'" causes PhpStorm to add
global$[variable]
(w/o whitespace before $) to the beginning of the current file...As commented earlier, I was not able to reproduce it. For future reference, my setup:
This means: It is likely with your older PhpStorm 2013.1.2 Build #PS-231.9011.38 you still need to mark the variable as global.
Here a preview:
Ctrl + Left Mouse Button (LMB) opens Choose Declaration pop-up menu. Both entries resolve to index.php locations:
Ctrl + Mouse Hover show type inference of the variable, it’s a string. Ctrl + LMB resolves to $pageKat = ""; in index.php.
Full rundown: