Bendegúz Csirmaz

PHP quiz #4 - hoisting

The term "hoisting" is used exclusively by JavaScript to describe its feature of moving variable and function declarations to the top of the current scope. Other languages have concepts resembling hoisting too, but for some reason they aren't discussed nearly as much as they should be.

Question

What will this code output?

<?php

echo helloWorld();

function helloWorld() {
  return "Hello World!\n";
}
  • A Fatal error: Uncaught Error: Call to undefined function helloWorld()
  • B Nothing
  • C Hello World!
  • D Warning + "helloWorld()"

Answer

Show the answer
C
Hello World!

Explanation

Hoisting

Similarly to JavaScript, function declarations are resolved at compile time. By the time the interpreter calls our function, it will have been already defined. The program will run without any problems.

Restrictions on hoisting

When the function is defined conditionally, this is not the case. For hoisting to work, it has to be defined on the top level. The following will throw a fatal error:

<?php

if (true) {
  // Fatal error: Uncaught Error: Call to undefined function helloWorld().
  echo helloWorld();

  function helloWorld() {
    return "Hello World!\n";
  }
}

Includes

What about includes?

Naturally, they are only resolved at runtime. When including a function, the include statement must run before the function call.

<?php

// Fatal error: Uncaught Error: Call to undefined function helloWorld().
echo helloWorld();

// Includes the helloWorld function.
include "helloWorld.php";

Classes

Functions are not the only unit of code organization (thank God!).

Hoisting applies to class, interface and trait declarations too. More or less.

<?php

class A extends B {}
class B {}

// OK!

It becomes less graceful when multiple levels of inheritance is introduced.

<?php

class A extends B {}
class B extends C {}
class C {}

// Fatal error: Class 'B' not found in ...

It's not that big of a problem though.

Avoiding top level functions and declaring one class per file is considered as best practice. This eliminates the possibility of ever relying on PHP to hoist your code.


This post is part of a series based on a presentation I gave on March 20, 2019.