My PHP 8++ cheat sheet

Be aware it's not an exhaustive list.

Permalink to heading Important PHP Concepts to know Important PHP Concepts to know

PHP (Hypertext Preprocessor) is a powerful C-like scripting language that sometimes suffers from a bad reputation due to its legacy. While most constructive critics have some points with PHP 4 or 5, PHP 7 and PHP 8 are a new done.

The language has now strong types, syntactic sugars and many other features you will love, especially if you come from other programming languages.

PHP is an interpreted language Unlike some languages, PHP is not self-contained. Your code will need in addition a third-party webserver (e.g., Apache, Nginx), a compiler and the PHP interpreter to work.
The interpreter reads your .php file, parses it, executes it, and then send the output to the webserver. Then, the server sends the output in the HTTP response to the browser (the client).
PHP extensions and reusable functions PHP works with extensions mostly written in C but some are third party libraries simply written in PHP. Some compile with the PHP binary and some are optional and must be included in the php.ini file where you write directives for PHP.
Lifecycle: Lexing Most of your php code turns into a sequence of tokens (tokenizing), but special symbols such as ?, =, or ; are already tokenized. The lexer generates lexemes which are a mix of numbers and letters representing the tokens and matching values.
Lifecycle: Parsing / AST The parser takes the streams of tokens generated with the lexer as input. It applies grammar rules to validate these tokens and generates an abstract tree (AST) using the php-ast extension.
Lifecycle: Compilation / opcodes Compilation is the act of consuming the AST. It generates opcodes by traversing the AST and run a few internal optimizations.
These opcodes are not unreadable but it's significantly different from the original source code with, for example, the results of intermediary operations such as true/false for a condition like $a === $b.
Lifecycle: Opcache Opcache can be enabled to cache opcodes, saving the results of previous operations and optimizing instructions to improve performances.
Lifecycle: Interpretation The Zend Engine (VM) takes opcodes as input to output the results and execute instructions.
Lifecycle: PHP 8 JIT compilation / opcache The Just-In-Time compilation works with Opcache (that stores precompiled sequences in memory to bypass parsing and interpretation) and improves the performances of CPU-intensive applications (e.g. Machine Learning, complexe mathematical operations, 3D, etc). JIT must be fine-tuned and does not fit all projects.
Composer Composer is the package manager for PHP. It's a smart way to handle and load dependencies.

Permalink to heading Data types in PHP 8 Data types in PHP 8

Integers Numbers such as 1, 2, 3, 4, 5, 6, ..., n
Booleans true or false
Strings Sequences of chars such as "Pink Elephants"
Doubles Floats such as 38.2
Arrays Collections of values such as ["a","b","c",]
Objects Instances of PHP classes that can carry lots of functions and values.
Resources Special references to external resources like remote connections (e.g., databases, cloud services).
NULL Special type with a unique value of NULL.
Mixed Anything!
Iterable Array or traverΒ­sable

Permalink to heading Common Escape Characters Common Escape Characters

\n Line
\t Horizontal tabulation
\v Vertical tabulation
\r Carriage return
\e Escape

Permalink to heading Basic PHP Syntax Basic PHP Syntax

Always use canonical tags All .php files must have opening and ending tags:
// my_script.php
Commenting code
// a comment using "//", you can also use "#"
Handle multiple lines 
with '/' 
and '*'
PHP is case sensitive $lower is not the same variable as $Lower.
Never omit the semi-colon Unlike with CSS or JavaScript, you cannot skip the ; at the end of expressions and statements:
echo 'test';
Indentation is for readability only Unlike Python, PHP does not care about indents and whitespaces.
Simple quotes
echo 'test';
Double quotes Double quotes allows variable interpolation and the use of escaped chars:
$my_var = 'test';
echo "\t\t\t This is a $my_var \n";

Permalink to heading Predefined variables Predefined variables

Also known as superglobals, predefined variables are useful to handle specific treatments:

$GLOBALS References all variables available in global scope.
$_REQUEST Associative array of variables passed to $_GET, $_POST and $_COOKIE.
$_POST Associative array of variables passed to the current script mostly with forms (application/x-www-form-urlencoded or multipart/form-data HTTP Content-Type)
$_COOKIE Associative array of variables passed to the current script via HTTP Cookies.
$_GET Associative array of variables passed to the current script via the URL parameters.
$_SERVER Server and execution environment information.

Find more superglobals here

Permalink to heading Predefined constants Predefined constants

__DIR__ Directory of the current file.
__FILE__ Full path of the current file.
__LINE__ Number of the current line in the file.
__CLASS__ Name of the current class, including its namespace.
__FUNCTION__ Name of the current function.
__METHOD__ Name of the current method.
__NAMESPACE__ Name of the current namespace.
__TRAIT__ Name of the current trait.

Permalink to heading Loop, loop, loop Loop, loop, loop

for ($i = 0; $i < 23; $i++) {
    echo $i;
$letters = ["a", "b", "c",]
foreach ($letters as $letter) {
    echo "$letter \n";
while Be careful, if the condition is malformed, you may end up with an infinite loop:
$j = 1;

while($j <= 5) {
  echo "$j \n";
do while It just checks the truth expression at the end of each iteration instead of in the beginning. You use it when a test is dependant upon the results of the loop:
$i = 0;
do {
    echo $i;
} while ($i > 0);

Permalink to heading Operators Operators

Permalink to heading Assignment Assignment

Assignment by value =
$a = 110;
$a += 1;
$b = "Hello ";
$b .= "World";
Assignment by reference &
$a = 111;
$b = &$a; // $b and $a point to the same data, there's no copy

Permalink to heading Arithmetic Arithmetic

+ Addition
- Substraction
* Multiplication
/ Division
** Exponentiation
% Modulo (reminder of a division)

Permalink to heading Logical Logical

&& And
|| Or
! Not
xor $a xor $b means $a or $b but not both.

Permalink to heading Comparison Comparison

=== Identical
!== Not identical
<> Not equal
< Lower than
> Greater than
<= Lower than or equal to
>= Equal to or greater than
<=> Lower than, equal to, or greater than

Permalink to heading Unusual or lesser known Unusual or lesser known

| or, but inclusive
^ xor
~ not
... Spread operator to merge elements
$arr = [1, 2, 3];
$arr2 = [...$arr, 4, 5, 6];
$price = 1_1_1;
echo $price; // 111

Permalink to heading Conditions Conditions

Classic conditions

} elseif (CONDITION2) {

} else {

Switch case
switch ($n) {
    case 1:
        $r = "You are alone";
    case 2:
        $r = "It's a double situation.";
    case 3:
        $r = "It's the third case.";
        $r = "I don't know.";
echo $r;
Null Coalescing operator (@since PHP 7)
$search = $_GET['search'] ?? 'does not exist or is null';
Match expression (@since PHP 8)
echo match ($n) {
  1 => "You are alone",
  2 => "It's a double situation.",
  3 => "It's the third case.",
  default => "I don't know.",
Ternary condition
$a = (expression1) ? expression2 : expression3;
Elvis condition (or operator)
$a = (expression1) ?: expression2; // I never use it, but it exists...
// the same as $a = (expression1) ? expression1 : expression2;

Permalink to heading Scopes Scopes

3 scopes global, local and static:
function test() {
    $b = "b"; // local
    global $c;
    $c = "c"; // global
    static $d = 0;
    $d++;// $d increment on each function call

Permalink to heading Date and time formats Date and time formats

D Days Mon to Sun
d Days 01 to 31
j Days 1 to 31
L Leap year or not (1 or 0)
l Days Sunday to Saturday
N Days 1 (Mon) to 7 (Sat)
w Days 0 (Sun) to 6 (Sat)
M Months Jan to Dec
m Months 01 to 12
n Months 1 to 12
F Months January to December
Y Year four digits (e.g., 2022)
y Year two digits (e.g., 22)
A AM and PM
a am and pm
G Hours 0 to 23
g Hours 1 to 12
H Hours 00 to 23
h Hours 01 to 12
i Minutes 00 to 59
s Seconds 00 to 59

See documentation for the complete list.

Permalink to heading Filters Filters

Filters flags and constants are particularly helpful to validate or sanitize inputs. For example, instead of using far-fetched regex to filter emails, you can do:

$email = "";

if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // process

See all filters.

Permalink to heading Advanced PHP syntaxes Advanced PHP syntaxes

Nowdoc and Heredoc syntaxes allows handling multiple lines in a very convenient way.

echo <<<EOT
Hello, this is a test
Thank you for your time
$my_var = 'test';
echo <<<EOT
Hello, this is a $my_var
Thank you for your time

Permalink to heading Working with arrays Working with arrays

Maybe start with this guide. Arrays are not specific to PHP, but a PHP developer uses them all the time.

You cannot skip it if you want to learn the language.

Permalink to heading Working with Generators Working with Generators

Make sense of generators

Permalink to heading Getting started with files Getting started with files

Reading a file as a string
echo file_get_contents($file);
Writing in a file
$file = 'file.txt';
$text = "Test write\n";
file_put_contents($file, $text, FILE_APPEND | LOCK_EX);
Deleting a file unlink($file);
Working with CSV Source:
$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num fields in line $row: <br /></p>\n";
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";

Permalink to heading Getting started with forms Getting started with forms

Forms are probably the most targeted elements by hackers, especially on PHP-based websites, as they’re often connected to other instances such as a SQL database.

Websites behind paywalls with various forms are primary targets.

In PHP, data often changes according to URLs (GET requests) or HTTP POST requests. For example, a search form will likely work with URL parameters, whereas a login form will send a POST request.

As a result, form processing may involve super globals $_GET and $_POST to catch input values.

See this guide

Permalink to heading Getting started with databases Getting started with databases

You will likely use a database along with PHP. Regardless of the database management system, you need to use the right PHP tools to connect and interact with the database from your PHP script.

Otherwise, your application might be prone to SQL injections.

Getting started with PDO
try {
    $pdo = new PDO("mysql:host=localhost;dbname=db_username;charset=utf8mb4", "db_username", "db_password");
    if ($pdo) {
	    $statement = $pdo->query("SELECT some_field FROM some_table");
        $row = $statement->fetch(PDO::FETCH_ASSOC);
        echo htmlentities($row['some_field']);
} catch(\PDOException $e) {
   throw new \PDOException($e->getMessage(), (int)$e->getCode());
Securing inputs with PDO PDO is pretty handy to escape and sanitize inputs:
$q = $pdo->prepare('SELECT name FROM users WHERE id = :id');
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$q->bindParam(':id', $id, PDO::PARAM_INT);

Source: PHP The Right Way - PDO

Permalink to heading PHP CLI PHP CLI

You can run PHP from the terminal in various ways:

Executing .php files
php my_script.php
Starting an interactive shell
php -a
Interactive shell

php > echo "hi";
php > 
Passing instructions as arguments
php -r 'echo "hi";'

You can write PHP scripts that are meant to be used from the terminal:

Passing arguments to PHP scripts
php my_script.php "test"
// my_script.php
print_r($argv[1]);// test
Start a local server php -S localhost:1001

Permalink to heading New in PHP 8 New in PHP 8

To be fair, PHP 7.4 initiated major evolutions such as typed properties, but PHP 8 puts PHP to the next level.

Be careful if you have to migrate from a previous version, though, as it’s much much stricter than before. PHP 8 throws way more fatal errors on purpose to be less permissive. The silence operator @ no longer exists and the default error_reporting level is E_ALL!

Here are cool new features I like, see release announcement for all details:

Named Parameters Allows for skipping optional parameters and much readable than positional arguments when using functions:
function say_hello(string $message = 'Hi', string $name) {
    echo "$message $name";
say_hello(name: "Zed");
Null-safe Operator Allows for removing LOTS of unnecessary verbose if/else conditions:
return $user->getJob()?->getSalary()?->bitcoins;
Union Types Allows using multiple types when casting parameters:
function convert(int|float $value): int|float {}
Constructor property promotion Allows for skipping LOTS of verbose initializations in PHP classes when passing arguments:
class Character {
    public function __construct(private string $name) {}
0 == 'ki' // false This condition returns true before PHP 8, which is permissive.
The JIT compiler See the first section: Important PHP Concepts
if (str_contains($string, 'target')) {
    // code

Permalink to heading New in PHP 8.1 New in PHP 8.1

Here are cool new features I like, see release announcement for all details:

Enumerations An Enum is a special kind of object that consists of a custom type that is limited to one or a discrete number of possible values:
enum Colors
    case Red;
    case Blue;
    case Green;
Array unpacking support for string-keyed arrays You can use the spread operator with string-keyed arrays (only num-keyed arrays in PHP 7 and 8):
$arr1 = ['a' => 1];
$arr2 = ['b' => 2];
$results = ['a' => 0, ...$arr1, ...$arr2];
Never return type The Never return type allows for specifying that the functions won't return any value and will likely die or exit:
function redirect_uri(string $uri): never {
    header('Location: ' . $uri);
Pure Intersection Types (&) Pure Intersection Types are a great way to force multiple constraints:
function count_and_iterate(Iterator&Countable $value) {
    foreach ($value as $val) {
        echo $val;


Permalink to heading Catching errors in PHP 8 Catching errors in PHP 8

In PHP 8, you don’t have to capture the exception, for example:

class CustomException extends \Exception {}

try {
    // code
 } catch (CustomException) { // instead of catch (CustomException $exception)
    Log::error("Error");// Log is a custom class too (not native)

It should be noted that PHP now throw exceptions frequently:

Most of the internal functions now throw an Error exception if the validation of the parameters fails.

Permalink to heading Misc Misc

$array = ['first', 'second', 'third',];
[, , $c] = $array;
// $c = 'third'
Arrow functions
$y = 111;
$f = fn($x) => $x + $y;
echo $f(222);// 333
Throw expressions
$err = fn () => throw new CustomErrors();
::class Lovely:
$my_class = new MyClass();
var_dump($my_class::class);// instead of using get_class()
Trailing comma in function or class definition
public static function(
    string $name,
    int $number,
) {
    // code

Permalink to heading PSR PSR

PSR are standards for writing PHP code. You might have already seen PSR-0 or PSR-4, especially when autoloading dependencies through Composer. These are specific versions of PHP standards.

Permalink to heading OOP OOP

Object-oriented programming is fun and powerful, but hard to master. The good news is that you find it in most programming languages, so learning it is a pretty good investment.

Some developers think it’s the only proper way to develop software, some stick with procedural code. In any case, you can’t skip it.

Learn Design Patterns

Permalink to heading Caching Caching

My favorite caching solutions for PHP

Permalink to heading Debugging and profiling Debugging and profiling

console.log PHP data
function console_log( $data ){
  echo '<script>';
  echo 'console.log('. json_encode( $data ) .')';
  echo '</script>';
xdebug xdebug
  • print_r(): accepts one parameter
  • var_dump(): accepts multiple parameters
  • var_dump(debug_backtrace()): generates a backtrace
  • debug_print_backtrace(): prints a backtrace
Profilers Applications may require profiling tools to prevent memory leaks and other performances issues:
Tests, tests, and tests Professionals run unit, integration, acceptance tests, and many other variants to prevent nasty regressions:

Permalink to heading Handling HTTP requests Handling HTTP requests

There are many ways but I prefer using the http-client package: composer require symfony/http-client.

This low-level HTTP client with support for both PHP stream wrappers and cURL. You can fetch data synchronously OR asynchronously.

See http-client cheat sheet.

This content is available in other languages: