PHP introduction: the basics of PHP on a Unix server

Updated November 2026

PHP is the language behind a large share of the web, including WordPress, Drupal, MediaWiki and Nextcloud. It runs on the server, produces HTML, and is easy to start with on any Linux machine.

Versions

PHP 8 is the current major version, with a new minor release every November. Each release gets two years of bug fixes and two more years of security fixes. Check the supported versions page and do not run a release that no longer receives security updates; PHP 7 and older have been unsupported for years. Debian 13 ships PHP 8.4.

Install and try it

sudo apt install php-cli php-mbstring php-mysql   # interpreter plus the extensions used below
php -v
php -r 'echo "Hello from PHP " . PHP_VERSION . "\n";'

# a built-in web server for development (never for production)
mkdir site && cd site
echo '<?php phpinfo();' > index.php
php -S 127.0.0.1:8000

Open http://127.0.0.1:8000/ to see the page. For a real server, follow setting up a LAMP server.

The basics

PHP code goes between <?php and ?> inside an otherwise normal file. Everything outside those tags is sent to the browser unchanged.

<?php
declare(strict_types=1);

$name = "Ann";                         // variables start with $
$count = 3;
$users = ["ann", "bob", "eve"];        // a list
$uid = ["ann" => 1001, "bob" => 1002]; // an associative array

echo "Hello, $name. You have $count messages.\n";

foreach ($users as $u) {
    echo "user: $u\n";
}

function greet(string $who, string $greeting = "Hello"): string {
    return "$greeting, $who!";
}
echo greet("Bob"), "\n";

$status = match (true) {
    $count === 0 => "no messages",
    $count < 10   => "a few messages",
    default       => "many messages",
};

Use === (same value and type) rather than ==, which converts types in surprising ways.

Handling a form

<form method="post">
  <label>Your name <input name="name"></label>
  <button>Send</button>
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $name = trim($_POST['name'] ?? '');
    if ($name === '' || mb_strlen($name) > 100) {
        echo "<p>Please enter a name.</p>";
    } else {
        echo "<p>Hello, " . htmlspecialchars($name) . "!</p>";
    }
}

htmlspecialchars() is essential: it stops visitors from injecting HTML and JavaScript into your page.

Talking to a database safely

Use PDO with prepared statements. Never build SQL by gluing user input into a string; that is how SQL injection happens.

<?php
$pdo = new PDO(
    'mysql:host=localhost;dbname=site;charset=utf8mb4',
    'site', getenv('DB_PASSWORD'),
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

$stmt = $pdo->prepare('SELECT id, title FROM articles WHERE author = ? ORDER BY id DESC LIMIT 10');
$stmt->execute([$_GET['author'] ?? '']);
foreach ($stmt as $row) {
    echo htmlspecialchars($row['title']), "<br>\n";
}

Keep passwords out of the code: read them from the environment or from a configuration file outside the web root.

Composer and libraries

Composer installs PHP libraries and loads them automatically. Most modern PHP projects and frameworks (Laravel, Symfony) use it.

sudo apt install composer
composer require monolog/monolog
# in your code:
require __DIR__ . '/vendor/autoload.php';

Security checklist

Learn more