10/11/2025
Where Everything Started - The Php notes

Pic

πŸ“– Table of contents

πŸ’Š What is all this about?

This is a part of my nostalgic journey to the roots of my programming adventure: the Php.

More specifically, this is a collection of re-freshed notes and some kind of cheat-sheet for the Php language which I decided lately to revisit. About which you can read more in my previous post.

Since no one is really reading my blog and the site is more like a personal archive, I can always come back to it when needed - which makes it a best place to store notes in this way.

☒️ The prep

PHP is like a Swiss Army knife. It’s not the best tool for any one job, but it’s incredibly versatile.

In order to get Php running in your local environment, you should at least have Php installed, which can be done in multiple ways, depending on your OS.

Since I work in hybrid environment, I usually use mix of local installation and Docker containers and WSL2 - it would take a while to describe all the options, so I will just point you to the official Php installation guide or the easier way: the Laravel Herd or Laragon if your are on Windows or official CLI installers for your Linux distro.

Once you have Php installed, you can check if everything is working by running:

php -v

Now create a directory to store your Php files, e.g. php-notes, and inside create a file named index.php with the following content:

<?php
echo "Hello, World! \n";

Which is the same as console.log in JavaScript or print in Python.

And we are ready to go. You can run your script using the built-in Php server by executing:

php index.php

Or with a local server:

php -S localhost:8000

Then open your browser and navigate to http://localhost:8000 to see the output.

πŸ“ Syntax

Variables and Data Types

As you probably already know, to declare a variable we use the famous dollar sign $ followed by the variable name:

$name = "John Doe"; // String
$age = 30;          // Integer
$height = 5.9;     // Float
$isStudent = false; // Boolean
$nullValue = null;  // Null

To delete a variable, you can use the unset() function:

unset($name);

Constants and Operators

Contants can be defined using the define() function or the const keyword:

define("PI", 3.14);
echo "Value of PI is " . PI . "\n";

const E = 2.71;
echo "Value of E is " . E . "\n";

Spaceship operator (<=>) is used for three-way comparison

  • Returns 0 if values on either side are equal
  • Returns 1 if value on the left is greater
  • Returns -1 if the value on the right is greater
$result = 5 <=> 10; // -1
$result2 = 10 <=> 5; // 1
$result3 = 5 <=> 5; // 0
echo "Spaceship operator results: $result, $result2, $result3\n";

All other operators are pretty much standard and similar to other languages.

Un-packing

You can also un-pack arrays into variables using the list() function or the shorthand [] syntax:

$address = ['123 Main St', 'Pine Ridge', 'CA', '90210'];
[$street, $city, $state, $zip] = $address;
[,, $stateOnly, ] = $address; // Skipping values
echo "The state: $stateOnly \n"; // The state: CA

Casting

In Php, you can cast variables to different types using the (type) syntax:

$number = "42";
$casted = (int)$number; // Cast to integer
echo "Casted value: $casted\n";

Collection types

The Php has two main collection types: arrays and objects (associative arrays):

$fruits = ["Apple", "Banana", "Cherry"]; // Array
$fruits[] = "Mango"; // Adding an element to the array
array_push($fruits, "Orange"); // Another way to add an element
unset($fruits[1]); // Removing an element (Banana)

// Looping through an array
foreach ($fruits as $fruit) {
    echo "Fruit: $fruit\n";
}

$person = ["name" => "John", "age" => 30]; // Associative Array, most commonly used
echo "The name is: $person[name] and age is: $person[age] \n";
$person["height"] = 5.9; // Adding a new key-value pair
echo "The height is: $person[height] \n";

// Looping through an associative array
foreach ($person as $key => $value) {
    echo "$key: $value\n";
}

The arrays can be "mixed", meaning they can hold different data types:

$mixed = [
    "name" => "Alice",
    18,
    "other value",
    "isStudent" => true,
];

$mixed["email"] = "alice@queen.co";

foreach ($mixed as $key => $value) {
    echo "$key: $value\n";
}

Those can be also more complex, nested arrays:

$config = [
    "database" => [
        "host" => "localhost",
        "user" => getenv("DB_USER"),
        "password" => getenv("DB_PASSWORD"),
    ],
    "app" => [
        "debug" => true,
        "version" => "1.0.0",
    ],
];

echo "Database host: " . $config["database"]["host"] . "\n";

Control Structures (functions, loops, conditionals etc.)

Control structures in Php are similar to other C-like languages:

  • Functions: Defined using the function keyword, or by using arrow functions (PHP 7.4+).
  • Loops: for, foreach, while, and do...while loops are available.
  • Conditionals: if, else, elseif, and switch statements are used for branching logic.

Few examples:

// The data
$nums = [1, 2, 3, 4, 5];

// Arrow functions with map
$squared = array_map(fn($n) => $n * $n, $nums);
echo "Squared numbers: " . implode(", ", $squared) . "\n";

// Arrow functions with filter
$even = array_filter($nums, fn($n) => $n % 2 === 0);
echo "Even numbers: " . implode(", ", $even) . "\n";

// Classic arrow function
$double = fn($x)  => $x * 2;
echo "Doubled value of 4 is: " . $double(4) . "\n";

// Optionals
function add(int $a, int $b, ?int $c = null): int
{
    return $a + $b + ($c ?? 0);
}

echo "Sum: " . add(5, 10) . "\n"; // 15
echo "Sum with optional: " . add(5, 10, 5) . "\n"; // 20

// Default parameters
function greet(string $name = "Guest"): string
{
    return "Hello, $name!";
}

There are also enums (Php 8.1+) for better type safety:

enum UserRole: string {
    case ADMIN = 'admin';
    case EDITOR = 'editor';
    case VIEWER = 'viewer';
}

function getPermissions(UserRole $role): array {
    return match ($role) {
        UserRole::ADMIN => ['create', 'edit', 'delete', 'view'],
        UserRole::EDITOR => ['edit', 'view'],
        UserRole::VIEWER => ['view'],
    };
}

$role = UserRole::EDITOR;
$permissions = getPermissions($role);

echo "Permissions for " . $role->value . ": " . implode(", ", $permissions) . "\n"; // Permissions for editor: edit, view

And there are also named arguments and more advanced function signatures:

// Usage of named arguments (parameters) (Php 8.0+)
enum Runner {
    case SWARM;
    case SINGLE;
    case KUBERNETES;
}

function setConfiguration(Runner $runner, int $maxJobs = 10, bool $debug = false): void {
    $config = [
        "runner" => $runner->name,
        "max_jobs" => $maxJobs,
        "debug" => $debug,
    ];
    echo "Configuration set: " . json_encode($config) . "\n";
}

setConfiguration(runner: Runner::KUBERNETES, maxJobs: 15, debug: true);
setConfiguration(runner: Runner::SINGLE, debug: true);

// Classic while loop
while ($age < 18) {
    echo "Age is $age, still a minor.\n";
    $age++;
}

// Do while loop
$age = 13;
do {
    echo "Age is $age, still a minor.\n";
    $age++;
} while ($age < 18);

// Classic for loop
for ($i = 0; $i <= count($fruits); $i++) {
    echo "Fruit at index $i is: " . $fruits[$i] . "\n";
}
// Alternative syntax for control structures (useful in templates)
?>

<?php if ($x): ?>
This is displayed if the test is truthy.
<?php else: ?>
This is displayed otherwise.
<?php endif; ?>

But there are some interesting things like match expression (Php 8.0+) in more functional style, together with arrow functions (Php 7.4+) or more newer pipe operator (Php 8.5+) or array_first() or array_last().

$age = 15;

$cat = match (true) {
    $age < 13 => "Child",
    $age >= 13 && $age < 20 => "Teenager",
    $age >= 20 && $age < 65 => "Adult",
    default => "Senior",
};

echo "Category: $cat \n"; // Category: Teenager
$output = " Docker Runner "
    |> trim(...)
    |> strtolower(...)
    |> (fn($str) => str_replace(" ", "_", $str));

echo "Transformed output: $output \n"; // Transformed output: docker_runner

Of course there are also if statements or ternary operators:

$age = 18;

// If statement
if ($age < 18) {
    echo "Minor";
} elseif ($age < 65) {
    echo "Adult";
} else {
    echo "Senior";
}

// Ternary operator
$status = ($age < 18) ? "Minor" : "Adult";
echo "Status: $status\n";

Enforce types

In Php since version 7.0 you can enforce types for function parameters and return values. You can specify types like int, float, string, bool, array, object, callable, and even class/interface names.

declare(strict_types=1);

OOP

Php supports object-oriented programming (OOP).

We would start with the most basic example of a class with properties and methods:

class Store {
    public string $storeInternalCode;
    public array $config;

    public function isOpen(): bool {
        $hour = (int)date('H');
        return $hour >= 9 && $hour <= 21;
    }
}

$store = new Store();
$store->storeInternalCode = "STORE_001";
$store->config = [
    "currency" => "USD",
    "size" => "Large",
    "address" => [
        "street" => "123 Main St",
        "city" => "Pine Ridge",
        "zip" => "12345",
    ]
];

echo "Store Code: " . $store->storeInternalCode . "\n"; // Store Code: STORE_001
echo "Is store open? " . ($store->isOpen() ? "Yes" : "No") . "\n"; // Is store open? Yes/No
// Depending on current time
echo "Store City: " . $store->config["address"]["city"] . "\n"; // Store City: Pine Ridge

But you can always use constructors to initialize properties:

class Store {

    public function __construct(public string $storeInternalCode, public array $config) {
        $this->storeInternalCode = $storeInternalCode;
        $this->config = $config;

    }

    public function isOpen(): bool {
        $hour = (int)date('H');
        return $hour >= 9 && $hour <= 21;
    }
}

$store = new Store(
    storeInternalCode: "STORE_001",
    config: [
        "currency" => "USD",
        "size" => "Large",
        "address" => [
            "street" => "123 Main St",
            "city" => "Pine Ridge",
            "zip" => "12345",
        ]
    ]
);

echo "Is store open? " . ($store->isOpen() ? "Yes" : "No") . "\n";

Of course, you can always use visibility modifiers (public, protected, private), destructors, static properties/methods, abstract classes, interfaces, and traits to build more complex OOP structures.

For example, here is another example with static properties and methods, constructors, and more complex logic:

class Invoice {

    public static array $invoiceNumbers = [];
    public Store $store;
    public string $invoiceNumber;


    public function __construct(Store $store) {
        $this->store = $store;
    }

    private function generateInvoiceNumber(): string {
        do {
            $number = 'INV-' . strtoupper(bin2hex(random_bytes(4)));
        } while (in_array($number, self::$invoiceNumbers));

        self::$invoiceNumbers[] = $number;
        return $number;
    }

    public function createInvoice(): void {
        $this->invoiceNumber = $this->generateInvoiceNumber();
        echo "Invoice " . $this->invoiceNumber . " created for store " . $this->store->storeInternalCode . "\n";
    }
}

$invoice = new Invoice($store);
$invoice->createInvoice();
echo "Invoice Number: " . $invoice->invoiceNumber . "\n"; // Invoice Number: INV-XXXXXXX

Classes and property promotion (new way)

There is a slight difference in defining classes in pre and post Php 8.0 versions, thanks to the new constructor property promotion feature:

Pre Php 8.0:

class User {
    public string $name;
    public int $age;

    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
    }
}

Post Php 8.0

class User {
    public function __construct(public string $name, public int $age) {}

    public function isAdult(): bool {
        return $this->age >= 18;
    }
}

There is no need to explicitly declare properties and assign them in the constructor - the promotion does it automatically.

So no more typing $this->property = $property; for each property.

Inheritance

Php of course supports inheritance (the classical Animal and Cat example):

class Animal {
    public function makeSound(): string {
        return "Some generic sound";
    }
}

class Cat extends Animal {
    public function makeSound(): string {
        return "Meow";
    }
}

$cat = new Cat();
echo $cat->makeSound(); // Meow

You can also block inheritance using the final keyword:

class Chasis {
    public final function getMaterial(): string {
        return "Aluminum";
    }
}

class Car extends Chasis {
    // This will cause an error
    // public function getMaterial(): string {
    //     return "Steel";
    // }

And also use Union Types:

class Discount {
    public function applyDiscount(int|float $amount, int|float $discount): int|float {
        return $amount - $discount;
    }
}

Interfaces

Similarly to other OOP languages, Php supports interfaces to define contracts for classes:

interface Logger {
    public function log(string $message): void;
}

class FileLogger implements Logger {
    public function log(string $message): void {
        file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
    }
}

$logger = new FileLogger();
$logger->log("This is a log message.");

Traits

trait LoggerTrait {
    public function log(string $message): void {
        file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND);
    }
}

class FileLogger {
    use LoggerTrait;
}

$logger = new FileLogger();
$logger->log("This is a log message.");

The main difference between traits and interfaces is that traits can provide default implementations for methods, while interfaces cannot, and they can be used to compose behavior across multiple classes.

So in other words, traits are neither classes nor interfaces - they are reusable pieces of code that can be included within classes to share functionality.

In order to use traits, you use the use keyword inside a class definition, like shown in the example above.

πŸ’Ž Namespaces and their usage

Php uses namespaces to organize code and avoid name collisions. You can define a namespace at the top of your Php file using the namespace keyword:

# model/ExampleModel.php
namespace App\Models;

class ExampleModel {
    public function getData(): string {
        return "Some data from ExampleModel";
    }
}

And then you can import and use that class in another file using the use keyword:

use App\Models\ExampleModel;

$model = new ExampleModel();
echo $model->getData(); // Some data from ExampleModel

❀️‍πŸ”₯ Summing up

So far so good!

The overall feel of modern Php is quite nice and familiar if you have experience with other C-like languages.

It feels kinda very similar to I am use do in Typescript and feels really productive and nice to write and read, especially using modern features like arrow functions, match expressions, union types, constructor property promotion, interfaces, traits, and more.

Time to deep-dive into the Laravel world next!

PS. Here is also a small cheat-sheet of some common standard library functions for quick reference, below.

πŸ€– Standard library (extras)

Here are some common standard library functions for OS, files, env, and related tasks, grouped by purpose.

Filesystem and file I/O

  • file_get_contents, file_put_contents β€” simple reads/writes to files; common for config and small files. Example: $s = file_get_contents('data.txt'); file_put_contents('out.txt', $s);
  • fopen, fread, fwrite, fclose, fgets, fread, feof β€” low-level stream-based file handling for large files or incremental IO.
  • fopen wrappers / readfile β€” open URLs or stream to output (when allow_url_fopen is enabled).
  • file_exists, is_file, is_dir, is_readable, is_writable, filesize, filemtime, fileperms β€” file metadata and checks.
  • rename, unlink, copy, mkdir, rmdir, scandir, glob β€” file and directory operations.

Streams, locking and atomics

  • flock β€” advisory file locking for safe concurrent writes.
  • stream_select, stream_get_contents, stream_copy_to_stream β€” advanced stream utilities for sockets and pipes.

Environment, INI and process / OS interaction

  • getenv, putenv, $_ENV β€” read/write environment variables from PHP runtime.
  • php_ini_loaded_file, ini_get, ini_set, ini_restore β€” inspect and change php.ini settings at runtime.
  • getcwd, chdir, realpath, sys_get_temp_dir, getenv('TMPDIR') β€” working directory and temp directories.
  • exec, shell_exec, system, passthru, proc_open, proc_close, proc_get_status β€” run external processes and capture output; use proc_* for fine-grained control.

Networking and sockets

  • fsockopen, stream_socket_client, stream_socket_server β€” simple TCP/UDP client and server sockets using streams.
  • socket_ family* (socket_create, socket_bind, socket_listen, socket_accept, socket_recv, socket_send) β€” low-level sockets extension for raw control.
  • curl_ functions (cURL extension)* β€” HTTP client for requests with advanced options (timeouts, headers, auth).

Utilities: JSON, serialization, date/time, hashing, compression

  • json_encode, json_decode β€” JSON serialization/parsing (ubiquitous for APIs).
  • serialize, unserialize β€” PHP native serialization (use with care for security).
  • DateTime, date, strtotime β€” date/time creation and formatting classes/functions.
  • hash, hash_hmac, password_hash, password_verify β€” hashing and password utilities.
  • gzopen, gzwrite, gzread, gzcompress, gzuncompress, ZipArchive β€” compression APIs and zip archive management.

SPL and standard containers / iterators

  • ArrayObject, ArrayIterator, Iterator, IteratorAggregate β€” object wrappers around arrays and custom iterable implementations.
  • SplDoublyLinkedList, SplStack, SplQueue, SplHeap, SplPriorityQueue, SplFixedArray β€” built-in data structures for stacks, queues, heaps and fixed arrays.

🧾 References