Introdução ao PHP
PHP для начинающих: язык который работает на 78% сайтов
Когда открываешь любимый сайт, нажимаешь «Войти» и страница обновляется с твоим именем — за этим почти наверняка стоит PHP. Этот язык незаметен, но вездесущ: на нём работает 78% всех сайтов.
История PHP
В 1993 году датский программист Расмус Лердорф (Rasmus Lerdorf) работал в США и хотел отслеживать, кто просматривает его онлайн-резюме. Он написал скрипты на Perl. В 1994 году переписал на C и назвал PHP/FI — «Personal Home Page / Forms Interpreter».
Расмус опубликовал код — «вдруг кому пригодится». Пригодилось очень многим. В 1997 году Зеев Сураски и Энди Гутманс создали Zend Engine — движок PHP. С тех пор PHP расшифровывается рекурсивно: PHP: Hypertext Preprocessor.
| Год | Событие |
|---|---|
| 1994 | Расмус Лердорф создаёт PHP/FI для своего резюме |
| 1997 | Zend Engine — полная переработка |
| 2004 | PHP 5 — полноценное ООП, PDO |
| 2015 | PHP 7 — скорость выросла в 2 раза! |
| 2020 | PHP 8 — JIT, match, named arguments |
| 2022–2024 | PHP 8.1/8.2/8.3 — enums, readonly, fibres |
PHP — «клей» интернета
PHP специально создан для веба: обрабатывает HTTP-запросы, работает с формами, сессиями, куками — всё встроено. PHP называют «клеем интернета»: соединяет базы данных, HTML, файловую систему, внешние API.
WordPress — самая популярная CMS (43% всех сайтов) написана на PHP. Facebook изначально был на PHP. Wikipedia, Etsy, Tumblr, Shopify — всё PHP.
Крупнейшие фреймворки: Laravel (самый популярный), Symfony, CodeIgniter, Yii.
Установка: XAMPP или MAMP
PHP — серверный язык. Код выполняется на сервере, браузер получает готовый HTML. Для локальной разработки нужен сервер на своём компьютере.
# XAMPP (Windows/Linux/macOS): https://www.apachefriends.org
# 1. Скачай и установи
# 2. Запусти Apache и MySQL
# 3. Помести файлы в C:\xampp\htdocs\
# 4. Открой: http://localhost/файл.php
# Или онлайн без установки:
# replit.com, phpsandbox.io, 3v4l.org
Первый PHP-скрипт
<?php
// Простейший скрипт
echo "Hello, World!";
?>
<?php— открывающий тег. Всё между<?phpи?>— PHP-код.echo— оператор вывода. Отправляет текст в браузер.;— обязательна в конце каждой инструкции.
PHP внутри HTML — суперсила!
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="UTF-8"><title>Мой PHP-сайт</title></head>
<body>
<h1>Привет от PHP! 🐘</h1>
<?php
$name = "Вася";
$age = 12;
echo "<p>Меня зовут $name, мне $age лет.</p>";
?>
<p>Время: <?= date('H:i:s') ?></p>
<p>Дата: <?= date('d.m.Y') ?></p>
<?php
for ($i = 1; $i <= 5; $i++) {
echo "<p>Строка $i</p>\n";
}
?>
</body>
</html>
<?= ... ?> — сокращение для <?php echo ...; ?>
echo, print и форматирование
<?php
// echo — самый частый способ
echo "Привет, мир!<br>";
echo "Число: ", 42; // echo принимает несколько аргументов!
// Переменные вставляются автоматически в двойных кавычках
$x = 42;
$name = "Алиса";
echo "Имя: $name, число: $x<br>";
// Конкатенация через точку .
echo "Имя: " . $name . ", число: " . $x . "<br>";
// sprintf — форматированная строка
$price = 1234.56;
echo sprintf("Цена: %.2f руб.<br>", $price); // 1234.56
// printf — сразу выводит
printf("%-10s %5.1f\n", "Алиса", 4.8);
// Heredoc — многострочный текст с интерполяцией
$text = <<<EOT
Это многострочный текст.
Переменная $name вставляется автоматически.
EOT;
echo $text;
?>
Важные встроенные функции
<?php
// Информация о системе
echo "PHP версия: " . phpversion() . "\n";
echo "ОС: " . PHP_OS . "\n";
echo "Максимальное int: " . PHP_INT_MAX . "\n";
echo "Точность float: " . PHP_FLOAT_EPSILON . "\n";
// Дата и время
echo date("Y-m-d H:i:s") . "\n"; // 2024-01-15 14:30:00
echo date("d.m.Y") . "\n"; // 15.01.2024
$ts = time(); // UNIX timestamp
echo $ts . "\n";
// Математика
echo abs(-7) . "\n"; // 7
echo ceil(4.1) . "\n"; // 5
echo floor(4.9) . "\n"; // 4
echo round(4.567, 2) . "\n"; // 4.57
echo max(3, 1, 4, 1, 5) . "\n"; // 5
echo rand(1, 100) . "\n"; // случайное от 1 до 100
echo pow(2, 10) . "\n"; // 1024
echo sqrt(144) . "\n"; // 12
?>
Отладочные инструменты
<?php
$name = "Вася";
$age = 12;
$grades = [4, 5, 3, 5];
$nothing = null;
// var_dump — показывает тип И значение
var_dump($name); // string(4) "Вася"
var_dump($age); // int(12)
var_dump($nothing); // NULL
// print_r — красивый вывод массивов
print_r($grades);
// Array ( [0] => 4 [1] => 5 [2] => 3 [3] => 5 )
// var_export — вывод как PHP-код
var_export($grades);
// В HTML используем <pre> для читаемости
echo "<pre>";
print_r($grades);
echo "</pre>";
?>
Полный пример: страница «О себе»
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="UTF-8"><title>Обо мне</title>
<style>
body { font-family: Arial; max-width: 600px; margin: 20px auto; }
.card { background: #f5f5f5; padding: 20px; border-radius: 8px; }
</style>
</head>
<body>
<?php
$name = "Алиса Петрова";
$age = 12;
$grade = "6А";
$hobbies = ["программирование", "рисование", "чтение"];
$gpa = 4.8;
$year = date('Y');
$rating = $gpa >= 4.5 ? "Отличник 🌟" : ($gpa >= 3.5 ? "Хорошист" : "Троечник");
?>
<div class="card">
<h1>Привет! Я <?= $name ?></h1>
<p>Возраст: <?= $age ?> лет</p>
<p>Класс: <?= $grade ?></p>
<p>Средний балл: <?= $gpa ?> (<?= $rating ?>)</p>
<p>Хобби:</p>
<ul>
<?php foreach ($hobbies as $h): ?>
<li><?= $h ?></li>
<?php endforeach; ?>
</ul>
<p>Страница открыта: <?= date('d.m.Y H:i') ?></p>
</div>
</body></html>
Типичные ошибки
❌ Забыл ; в конце инструкции
echo "Hello" // Parse error: syntax error, unexpected end
echo "Hello"; // ✅
❌ Неправильный тег
<? echo "hello"; ?> // Может не работать (short_open_tag)
<?php echo "hello"; ?> // ✅ всегда работает
❌ Смешение строк с разными кавычками
$name = 'Вася';
echo 'Привет, $name!'; // выведет буквально $name
echo "Привет, $name!"; // ✅ подставит значение
Итого
PHP создан Расмусом Лердорфом в 1994 году. На нём работает 78% сайтов. Встроен в HTML через теги <?php ... ?>. echo — основной вывод. print_r, var_dump — для отладки. Установка: XAMPP (Windows/macOS/Linux).
Дополнительные примеры и задачи
Пример 1: Работа с датами и временем
<?php
// PHP имеет богатые встроенные функции для работы с датами
$now = new DateTime();
echo $now->format('d.m.Y H:i:s') . "\n";
// Создание конкретной даты
$birthday = new DateTime('2012-03-15');
$today = new DateTime();
$diff = $today->diff($birthday);
echo "Прошло {$diff->y} лет {$diff->m} месяцев {$diff->d} дней\n";
// Добавление/вычитание времени
$next_week = new DateTime();
$next_week->modify('+7 days');
echo "Через неделю: " . $next_week->format('d.m.Y') . "\n";
$past = new DateTime();
$past->modify('-30 days');
echo "Месяц назад: " . $past->format('d.m.Y') . "\n";
// Форматы даты
$date = new DateTime('2024-01-15 14:30:00');
echo $date->format('d MMMM Y') . "\n"; // нет: это ICU формат
echo $date->format('j F Y') . "\n"; // 15 January 2024
echo $date->format('U') . "\n"; // Unix timestamp
// strtotime — удобное создание дат
$ts = strtotime('next Monday');
echo date('d.m.Y', $ts) . "\n";
$ts2 = strtotime('+2 months');
echo date('d.m.Y', $ts2) . "\n";
?>
Пример 2: Работа с файлами
<?php
// Запись в файл
$data = "Привет, PHP!\nВторая строка\n";
file_put_contents('/tmp/test.txt', $data);
echo "Записано: " . strlen($data) . " байт\n";
// Добавление к файлу
file_put_contents('/tmp/test.txt', "Третья строка\n", FILE_APPEND);
// Чтение файла
$content = file_get_contents('/tmp/test.txt');
echo $content;
// Чтение построчно
$lines = file('/tmp/test.txt', FILE_IGNORE_NEW_LINES);
foreach ($lines as $i => $line) {
echo "$i: $line\n";
}
// Проверка существования
if (file_exists('/tmp/test.txt')) {
echo "Файл существует\n";
echo "Размер: " . filesize('/tmp/test.txt') . " байт\n";
}
// Удаление
unlink('/tmp/test.txt');
echo "Файл удалён\n";
?>
Пример 3: Регулярные выражения
<?php
// Валидация email
function validateEmail(string $email): bool {
return (bool) preg_match('/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/', $email);
}
$emails = ["user@example.com", "invalid-email", "test@test.ru", "no_at_sign"];
foreach ($emails as $email) {
echo "$email: " . (validateEmail($email) ? "✅" : "❌") . "\n";
}
// Извлечение данных
$text = "Телефоны: +7(495)123-45-67 и 8-800-555-35-35";
preg_match_all('/[+7|8][\d\s\-()]+/', $text, $matches);
print_r($matches[0]);
// Замена
$html = "<p>Hello <b>World</b></p>";
$clean = preg_replace('/<[^>]+>/', '', $html);
echo $clean . "\n"; // Hello World
// Разбивка по паттерну
$str = "яблоко, банан;вишня дыня";
$fruits = preg_split('/[,;\s]+/', trim($str));
print_r(array_filter($fruits));
?>
Практическое задание: калькулятор оценок
<?php
class GradeCalculator {
private array $subjects = [];
public function addGrade(string $subject, float $grade): void {
if ($grade < 1 || $grade > 5) {
throw new InvalidArgumentException("Оценка должна быть от 1 до 5");
}
$this->subjects[$subject][] = $grade;
}
public function getAverage(string $subject): float {
if (!isset($this->subjects[$subject])) {
throw new RuntimeException("Предмет не найден: $subject");
}
return array_sum($this->subjects[$subject]) / count($this->subjects[$subject]);
}
public function getOverallAverage(): float {
$all = [];
foreach ($this->subjects as $grades) {
$all = array_merge($all, $grades);
}
return empty($all) ? 0.0 : array_sum($all) / count($all);
}
public function getReport(): string {
$lines = ["=== Отчёт об успеваемости ==="];
foreach ($this->subjects as $subject => $grades) {
$avg = $this->getAverage($subject);
$lines[] = sprintf("%-15s: %.2f (оценок: %d)", $subject, $avg, count($grades));
}
$lines[] = str_repeat("-", 35);
$lines[] = sprintf("%-15s: %.2f", "ИТОГО", $this->getOverallAverage());
return implode("\n", $lines);
}
}
$calc = new GradeCalculator();
$calc->addGrade("Математика", 5);
$calc->addGrade("Математика", 4);
$calc->addGrade("Математика", 5);
$calc->addGrade("Русский язык", 4);
$calc->addGrade("Русский язык", 5);
$calc->addGrade("Английский", 3);
$calc->addGrade("Английский", 4);
echo $calc->getReport() . "\n";
?>
Полезные PHP-паттерны
Паттерн Repository (хранилище данных)
<?php
interface UserRepositoryInterface {
public function findById(int $id): ?array;
public function findAll(): array;
public function save(array $user): int;
public function delete(int $id): bool;
}
class InMemoryUserRepository implements UserRepositoryInterface {
private array $users = [];
private int $nextId = 1;
public function findById(int $id): ?array {
return $this->users[$id] ?? null;
}
public function findAll(): array {
return array_values($this->users);
}
public function save(array $user): int {
$id = $user['id'] ?? $this->nextId++;
$this->users[$id] = array_merge($user, ['id' => $id]);
return $id;
}
public function delete(int $id): bool {
if (!isset($this->users[$id])) return false;
unset($this->users[$id]);
return true;
}
}
$repo = new InMemoryUserRepository();
$id1 = $repo->save(['name' => 'Алиса', 'email' => 'alice@test.com']);
$id2 = $repo->save(['name' => 'Боря', 'email' => 'bob@test.com']);
print_r($repo->findAll());
print_r($repo->findById($id1));
$repo->delete($id2);
echo "Осталось: " . count($repo->findAll()) . "\n";
?>
Ещё практики: функции для задач из реальной жизни
Работа с JSON
<?php
// json_encode — PHP → JSON
$data = [
"name" => "Алиса",
"age" => 12,
"hobbies" => ["программирование", "чтение"],
"address" => ["city" => "Москва", "zip" => "123456"],
];
$json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
echo $json . "\n";
// json_decode — JSON → PHP
$json_str = '{"name":"Боря","score":95,"active":true}';
$obj = json_decode($json_str); // объект
$arr = json_decode($json_str, true); // массив (флаг true)
echo $obj->name . ": " . $obj->score . "\n";
echo $arr["name"] . ": " . $arr["score"] . "\n";
// Проверка ошибок
$bad = json_decode("{invalid json}", true);
if (json_last_error() !== JSON_ERROR_NONE) {
echo "Ошибка JSON: " . json_last_error_msg() . "\n";
}
// Сохранение/чтение конфига
$config = ["debug" => true, "db_host" => "localhost", "max_users" => 100];
file_put_contents('/tmp/config.json', json_encode($config));
$loaded = json_decode(file_get_contents('/tmp/config.json'), true);
echo "Debug: " . ($loaded['debug'] ? 'on' : 'off') . "\n";
?>
Работа с сессиями и куками
<?php
// Сессии — данные хранятся на сервере
// session_start() должен быть ПЕРЕД любым выводом
// session_start();
// $_SESSION['user_id'] = 42;
// $_SESSION['user_name'] = "Алиса";
// $_SESSION['logged_in'] = true;
// // На другой странице:
// session_start();
// if ($_SESSION['logged_in'] ?? false) {
// echo "Добро пожаловать, " . $_SESSION['user_name'] . "!";
// } else {
// header('Location: /login.php');
// }
// Куки — данные хранятся в браузере
// setcookie('theme', 'dark', time() + 86400 * 30); // на 30 дней
// $theme = $_COOKIE['theme'] ?? 'light';
// echo "Тема: $theme";
// Симуляция (без HTTP)
$session = ['user_id' => 42, 'name' => 'Алиса', 'role' => 'student'];
echo "Пользователь: {$session['name']} (роль: {$session['role']})\n";
echo "ID сессии: " . uniqid() . "\n";
?>
Обработка форм
<!DOCTYPE html>
<html lang="ru">
<head><meta charset="UTF-8"><title>Форма</title></head>
<body>
<?php
// Обработка отправленной формы
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$age = (int)($_POST['age'] ?? 0);
$errors = [];
if (empty($name)) $errors[] = "Имя обязательно";
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Неверный email";
}
if ($age < 5 || $age > 120) $errors[] = "Неверный возраст";
if (empty($errors)) {
$name = htmlspecialchars($name); // защита от XSS!
$email = htmlspecialchars($email);
echo "<p style='color:green'>✅ Привет, $name! Email: $email, Возраст: $age</p>";
} else {
foreach ($errors as $err) {
echo "<p style='color:red'>❌ $err</p>";
}
}
}
?>
<form method="POST">
<label>Имя: <input name="name" type="text"></label><br>
<label>Email: <input name="email" type="email"></label><br>
<label>Возраст: <input name="age" type="number"></label><br>
<button type="submit">Отправить</button>
</form>
</body></html>
Подключение к MySQL через PDO
<?php
// PDO — современный способ работы с БД
try {
$pdo = new PDO(
"mysql:host=localhost;dbname=school;charset=utf8mb4",
"username",
"password",
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// Создание таблицы
$pdo->exec("CREATE TABLE IF NOT EXISTS students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
age INT,
gpa DECIMAL(3,2)
)");
// Вставка данных (prepared statement — защита от SQL-инъекций!)
$stmt = $pdo->prepare("INSERT INTO students (name, age, gpa) VALUES (:name, :age, :gpa)");
$students = [
["Алиса", 12, 4.8],
["Боря", 13, 3.9],
["Вера", 12, 4.5],
];
foreach ($students as [$name, $age, $gpa]) {
$stmt->execute([':name' => $name, ':age' => $age, ':gpa' => $gpa]);
}
// Выборка
$rows = $pdo->query("SELECT * FROM students ORDER BY gpa DESC")->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo "{$row['name']}: GPA {$row['gpa']}\n";
}
// Параметрический запрос
$stmt = $pdo->prepare("SELECT * FROM students WHERE age = :age");
$stmt->execute([':age' => 12]);
$twelveyear = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo "\n12-летних: " . count($twelveyear) . "\n";
} catch (PDOException $e) {
echo "Ошибка БД: " . $e->getMessage() . "\n";
}
?>