Another PHP 8++ cheat sheet

spo0q

spO0q

Posted on February 22, 2022

Another PHP 8++ cheat sheet

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 or 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.

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

Common Escape Characters

\n

Line

\t

Horizontal tabulation

\v

Vertical tabulation

\r

Carriage return

\e

Escape

Basic PHP Syntax

Always use canonical tags

Opening and ending tags:

<?php
// my_script.php
?>
Enter fullscreen mode Exit fullscreen mode

Commenting code

<?php
// a comment using "//", you can also use "#"
/*
Handle multiple lines 
with '/' 
and '*'
*/
?>
Enter fullscreen mode Exit fullscreen mode

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:

<?php
echo 'test';
?>
Enter fullscreen mode Exit fullscreen mode

Indentation is for readability only

Unlike Python, PHP does not care about indents and whitespaces.

Simple quotes

<?php
echo 'test';
?>
Enter fullscreen mode Exit fullscreen mode

Double quotes

Double quotes allows variable interpolation and the use of escaped chars:

<?php
$my_var = 'test';
echo "\t\t\t This is a $my_var \n";
?>
Enter fullscreen mode Exit fullscreen mode

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

Magic 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.

Loop, loop, loop

for

<?php
for ($i = 0; $i < 23; $i++) {
    echo $i;
}
?>
Enter fullscreen mode Exit fullscreen mode

foreach

<?php
$letters = ["a", "b", "c",]
foreach ($letters as $letter) {
    echo "$letter \n";
}
?>
Enter fullscreen mode Exit fullscreen mode

while

Be careful, if the condition is malformed, you may end up with an infinite loop:

<?php
$j = 1;
while($j <= 5) {
  echo "$j \n";
  $j++;
}
?>
Enter fullscreen mode Exit fullscreen mode

do while

You use it when a test is dependant upon the results of the loop:

<?php
$i = 0;
do {
    echo $i;
} while ($i > 0);
?>
Enter fullscreen mode Exit fullscreen mode

Operators

Assignment

Assignment by value =

<?php
$a = 110;
$a += 1;
$b = "Hello ";
$b .= "World";
?>
Enter fullscreen mode Exit fullscreen mode

Assignment by reference &

<?php
$a = 111;
$b = &$a; // $b and $a point to the same data, there's no copy
?>
Enter fullscreen mode Exit fullscreen mode

Arithmetic

+

Addition

-

Substraction

*

Multiplication

/

Division

**

Exponentiation

%

Modulo (reminder of a division)

Logical

AND

And

&&

And

OR

Or

||

Or

!

Not

xor

$a xor $b means $a or $b but not both.

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

Unusual or lesser known

|

or, but inclusive

^

xor

~

not

...

Spread operator to merge elements

<?php
$arr = [1, 2, 3];
$arr2 = [...$arr, 4, 5, 6];
?>
Enter fullscreen mode Exit fullscreen mode

_

<?php
$price = 1_1_1;
echo $price; // 111
?>
Enter fullscreen mode Exit fullscreen mode

Conditions

Classic conditions

<?php
if (CONDITION1) {
} elseif (CONDITION2) {
} else {
}
?>
Enter fullscreen mode Exit fullscreen mode

Switch case

<?php
switch ($n) {
    case 1:
        $r = "You are alone";
        break;
    case 2:
        $r = "It's a double situation.";
        break;
    case 3:
        $r = "It's the third case.";
        break;
    default:
        $r = "I don't know.";
}
echo $r;
?>
Enter fullscreen mode Exit fullscreen mode

Null Coalescing operator (@since PHP 7)

<?php
$search = $_GET['search'] ?? 'does not exist or is null';
?>
Enter fullscreen mode Exit fullscreen mode

Match expression (@since PHP 8)

<?php
echo match ($n) {
  1 => "You are alone",
  2 => "It's a double situation.",
  3 => "It's the third case.",
  default => "I don't know.",
};?>
Enter fullscreen mode Exit fullscreen mode

Ternary condition

<?php
$a = (expression1) ? expression2 : expression3;
?>
Enter fullscreen mode Exit fullscreen mode

Elvis condition (or operator)

<?php
$a = (expression1) ?: expression2; // I never use it, but it exists...
// the same as $a = (expression1) ? expression1 : expression2;
?>
Enter fullscreen mode Exit fullscreen mode

Scopes

global, local and static:

<?php
function test() {
    $b = "b"; // local
    global $c;
    $c = "c"; // global
    static $d = 0;
    $d++;// $d increment on each function call
}
?>
Enter fullscreen mode Exit fullscreen mode

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.

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 = "elon.musk@tesla.com";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
    // process
}
Enter fullscreen mode Exit fullscreen mode

See all filters.

Advanced PHP syntaxes

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

Heredoc

<?php
echo <<<EOT
Hello, this is a test
Thank you for your time
EOT;
?>
Enter fullscreen mode Exit fullscreen mode

Nowdoc

<?php
$my_var = 'test';
echo <<<EOT
Hello, this is a $my_var
Thank you for your time
EOT;
?>
Enter fullscreen mode Exit fullscreen mode

Working with arrays

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.

Working with Generators

Getting started with files

Reading a file as a string

<?php
echo file_get_contents($file);
?>
Enter fullscreen mode Exit fullscreen mode

Writing in a file

<?php
$file = 'file.txt';
$text = "Test write\n";
file_put_contents($file, $text, FILE_APPEND | LOCK_EX);
?>
Enter fullscreen mode Exit fullscreen mode

Deleting a file

unlink($file);

Working with CSV

Source:

<?php
$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";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />\n";
        }
    }
    fclose($handle);
}
?>
Enter fullscreen mode Exit fullscreen mode

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

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

<?php
try {
    $pdo = new PDO("mysql:host=localhost;dbname=db_username;charset=utf8mb4", "db_username", "db_password");
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    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());
}
?>
Enter fullscreen mode Exit fullscreen mode

Securing inputs with PDO

PDO is pretty handy to escape and sanitize inputs:

<?php
$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);
$q->execute();
?>
Enter fullscreen mode Exit fullscreen mode

Source: PHP The Right Way - PDO

PHP CLI

You can run PHP from the terminal in various ways:

Executing .php files

php my_script.php
Enter fullscreen mode Exit fullscreen mode

Starting an interactive shell

php -a
Interactive shell
php > echo "hi";
hi
php > 
Enter fullscreen mode Exit fullscreen mode

Passing instructions as arguments

php -r 'echo "hi";'
Enter fullscreen mode Exit fullscreen mode

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

Passing arguments to PHP scripts

php my_script.php "test"
Enter fullscreen mode Exit fullscreen mode
<?php
// my_script.php
print_r($argv[1]);// test
?>
Enter fullscreen mode Exit fullscreen mode

Start a local server

php -S localhost:1001

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:

<?php
function say_hello(string $message = 'Hi', string $name) {
    echo "$message $name";
}
say_hello(name: "Zed");
?>
Enter fullscreen mode Exit fullscreen mode

Null-safe Operator

Allows for removing LOTS of unnecessary verbose if/else conditions:

<?php
return $user->getJob()?->getSalary()?->bitcoins;
?>
Enter fullscreen mode Exit fullscreen mode

Union Types

Allows using multiple types when casting parameters:

<?php
function convert(int|float $value): int|float {}
?>
Enter fullscreen mode Exit fullscreen mode

Constructor property promotion

Allows for skipping LOTS of verbose initializations in PHP classes when passing arguments:

<?php
class Character {
    public function __construct(private string $name) {}
}
?>
Enter fullscreen mode Exit fullscreen mode

0 == 'ki' // false

This condition returns true before PHP 8, which is permissive.

The JIT compiler

See the first section: Important PHP Concepts

str_contains()

<?php
if (str_contains($string, 'target')) {
    // code
}
?>
Enter fullscreen mode Exit fullscreen mode

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:

<?php
enum Colors
{
    case Red;
    case Blue;
    case Green;
}
?>
Enter fullscreen mode Exit fullscreen mode

Array unpacking support for string-keyed arrays

You can use the spread operator with string-keyed arrays (only num-keyed arrays in PHP 7, 8):

<?php
$arr1 = ['a' => 1];
$arr2 = ['b' => 2];
$results = ['a' => 0, ...$arr1, ...$arr2];
print_r($results);
?>
Enter fullscreen mode Exit fullscreen mode

Never return type

The Never return type allows for specifying that the functions won't return any value and will likely die or exit:

<?php
function redirect_uri(string $uri): never {
    header('Location: ' . $uri);
    exit();
}
?>
Enter fullscreen mode Exit fullscreen mode

Pure Intersection Types (&)

Pure Intersection Types are a great way to force multiple constraints:

<?php
function count_and_iterate(Iterator&Countable $value) {
    foreach ($value as $val) {
        echo $val;
    }
    count($value);
}
?>
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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.

Misc

Destructuring

<?php
$array = ['first', 'second', 'third',];
[, , $c] = $array;
// $c = 'third'
?>
Enter fullscreen mode Exit fullscreen mode

Arrow functions

<?php
$y = 111;
$f = fn($x) => $x + $y;
echo $f(222);// 333
?>
Enter fullscreen mode Exit fullscreen mode

Throw expressions

<?php
$err = fn () => throw new CustomErrors();
?>
Enter fullscreen mode Exit fullscreen mode

::class

Lovely:

<?php
$my_class = new MyClass();
var_dump($my_class::class);// instead of using get_class()
?>
Enter fullscreen mode Exit fullscreen mode

Trailing comma in function or class definition

<?php
public static function(
    string $name,
    int $number,
) {
    // code
}
?>
Enter fullscreen mode Exit fullscreen mode

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.

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

Caching

My favorite caching solutions for PHP

Debugging and profiling

console.log PHP data

<?php
function console_log( $data ){
  echo '<script>';
  echo 'console.log('. json_encode( $data ) .')';
  echo '</script>';
}
?>
Enter fullscreen mode Exit fullscreen mode

xdebug

xdebug

Helpers

  • 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: PHPunit

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.

💖 💪 🙅 🚩
spo0q
spO0q

Posted on February 22, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related