Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <h2>What is "variable scope"?</h2> <p>Variables have a limited "scope", or "places from which they are accessible". Just because you wrote <code>$foo = 'bar';</code> once <em>somewhere</em> in your application doesn't mean you can refer to <code>$foo</code> from <em>everywhere</em> else inside the application. The variable <code>$foo</code> has a certain scope within which it is valid and only code in the same scope has access to the variable.</p> <h2>How is a scope defined in PHP?</h2> <p>Very simple: PHP has <em>function scope</em>. That's the only kind of scope separator that exists in PHP. Variables inside a function are only available inside that function. Variables outside of functions are available anywhere outside of functions, but not inside any function. This means there's one special scope in PHP: the <em>global</em> scope. Any variable declared outside of any function is within this global scope.</p> <h3>Example:</h3> <pre><code>&lt;?php $foo = 'bar'; function myFunc() { $baz = 42; } </code></pre> <p><code>$foo</code> is in the <em>global</em> scope, <code>$baz</code> is in a <em>local</em> scope inside <code>myFunc</code>. Only code inside <code>myFunc</code> has access to <code>$baz</code>. Only code <em>outside</em> <code>myFunc</code> has access to <code>$foo</code>. Neither has access to the other:</p> <pre><code>&lt;?php $foo = 'bar'; function myFunc() { $baz = 42; echo $foo; // doesn't work echo $baz; // works } echo $foo; // works echo $baz; // doesn't work </code></pre> <h2>Scope and included files</h2> <p>File boundaries do <em>not separate</em> scope:</p> <p><em>a.php</em></p> <pre><code>&lt;?php $foo = 'bar'; </code></pre> <p><em>b.php</em></p> <pre><code>&lt;?php include 'a.php'; echo $foo; // works! </code></pre> <p>The same rules apply to <code>include</code>d code as applies to any other code: only <code>function</code>s separate scope. For the purpose of scope, you may think of including files like copy and pasting code:</p> <p><em>c.php</em></p> <pre><code>&lt;?php function myFunc() { include 'a.php'; echo $foo; // works } myFunc(); echo $foo; // doesn't work! </code></pre> <p>In the above example, <code>a.php</code> was included inside <code>myFunc</code>, any variables inside <code>a.php</code> only have local function scope. Just because they <em>appear</em> to be in the global scope in <code>a.php</code> doesn't necessarily mean they are, it actually depends on which context that code is included/executed in.</p> <h2>What about functions inside functions and classes?</h2> <p>Every new <code>function</code> declaration introduces a new scope, it's that simple.</p> <h3>(anonymous) functions inside functions</h3> <pre><code>function foo() { $foo = 'bar'; $bar = function () { // no access to $foo $baz = 'baz'; }; // no access to $baz } </code></pre> <h3>classes</h3> <pre><code>$foo = 'foo'; class Bar { public function baz() { // no access to $foo $baz = 'baz'; } } // no access to $baz </code></pre> <h2>What is scope good for?</h2> <p>Dealing with scoping issues may seem annoying, but <strong>limited variable scope is essential to writing complex applications!</strong> If every variable you declare would be available from everywhere else inside your application, you'd be stepping all over your variables with no real way to track what changes what. There are only so many sensible names you can give to your variables, you probably want to use the variable "<code>$name</code>" in more than one place. If you could only have this unique variable name once in your app, you'd have to resort to really complicated naming schemes to make sure your variables are unique and that you're not changing the wrong variable from the wrong piece of code.</p> <p>Observe:</p> <pre><code>function foo() { echo $bar; } </code></pre> <p>If there was no scope, what would the above function do? Where does <code>$bar</code> come from? What state does it have? Is it even initialized? Do you have to check every time? This is not maintainable. Which brings us to...</p> <h2>Crossing scope boundaries</h2> <h3>The right way: passing variables in and out</h3> <pre><code>function foo($bar) { echo $bar; return 42; } </code></pre> <p>The variable <code>$bar</code> is explicitly coming into this scope as function argument. Just looking at this function it's clear where the values it works with originate from. It then explicitly <em>returns</em> a value. The caller has the confidence to know what variables the function will work with and where its return values come from:</p> <pre><code>$baz = 'baz'; $blarg = foo($baz); </code></pre> <h3>Extending the scope of variables into anonymous functions</h3> <pre><code>$foo = 'bar'; $baz = function () use ($foo) { echo $foo; }; $baz(); </code></pre> <p>The anonymous function explicitly includes <code>$foo</code> from its surrounding scope. Note that this is not the same as <em>global</em> scope.</p> <h3>The wrong way: <code>global</code></h3> <p>As said before, the global scope is somewhat special, and functions can explicitly import variables from it:</p> <pre><code>$foo = 'bar'; function baz() { global $foo; echo $foo; $foo = 'baz'; } </code></pre> <p>This function uses and modifies the global variable <code>$foo</code>. <strong>Do not do this!</strong> <sub>(Unless you really really really really know what you're doing, and even then: don't!)</sub></p> <p>All the caller of this function sees is this:</p> <pre><code>baz(); // outputs "bar" unset($foo); baz(); // no output, WTF?! baz(); // outputs "baz", WTF?!?!! </code></pre> <p>There's no indication that this function has any <em>side effects</em>, yet it does. This very easily becomes a tangled mess as some functions keep modifying <em>and requiring</em> some global state. You want functions to be <em>stateless</em>, acting only on their inputs and returning defined output, however many times you call them.</p> <p>You should avoid using the global scope in any way as much as possible; most certainly you should not be "pulling" variables out of the global scope into a local scope.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload