Переменные, типы и строки
В PHP переменные начинаются со знака $. Не потому что язык любит деньги, а потому что так исторически сложилось.
Переменные
<?php
$name = 'Иван';
$age = 25;
$price = 99.99;
$isStudent = true;
Пиши имена переменных понятно. $x допустимо только если ты математик или очень спешишь.
Базовые типы
<ComparisonTable data={ headers: ["Тип", "Что это", "Пример"], rows: [ ["int", "Целое число", "42"], ["float", "Дробное число (IEEE 754)", "3.14"], ["string", "Строка байтов", ""Hello""], ["bool", "Логический тип", "true / false"], ["array", "Массив (список или словарь)", "[1, 2, 3]"], ["null", "Отсутствие значения", "null"], ["object", "Экземпляр класса", "new User()"] ], } />
Узнать тип значения в рантайме помогает get_debug_type() (PHP 8+) - он точнее старого gettype() и для объектов вернёт полное имя класса:
<?php
echo get_debug_type(42); // int
echo get_debug_type(3.14); // float
echo get_debug_type('hello'); // string
echo get_debug_type([1, 2]); // array
echo get_debug_type(new \DateTime); // DateTime
Строки
Есть два популярных вида кавычек:
<?php
$name = 'Иван';
// Двойные кавычки - интерполяция
echo "Привет, $name!";
// Одинарные - как есть
echo 'Привет, $name!';
Если видишь в выводе $name, а не имя - ты выбрал одинарные кавычки.
Для многострочных шаблонов есть heredoc (с интерполяцией) и nowdoc (без):
<?php
$user = 'Иван';
$letter = <<<TXT
Здравствуйте, $user!
Спасибо за регистрацию.
TXT;
$config = <<<'NOWDOC'
Это $сырая строка - $name не подставится.
NOWDOC;
Конкатенация vs интерполяция vs sprintf
<?php
$first = 'Back';
$second = 'end';
echo $first . $second; // через точку
echo "{$first}{$second}"; // интерполяция
echo sprintf('%s%s', $first, $second); // форматированный вывод
sprintf уместен, когда нужно форматирование (%05d, %.2f) или язык шаблонов отделён от подстановки.
Приведение типов (type casting)
Явное приведение - через (int), (string), (bool), (array):
<?php
$x = '10';
$sum = (int)$x + 5; // 15
$count = 0;
if (!$count) {
echo 'пусто'; // bool(false) при касте 0 → false
}
PHP охотно приводит типы и сам - это называется type juggling:
<?php
var_dump('10' == 10); // bool(true) - строка превращается в число
var_dump('0' == false); // bool(true) - оба «пустые»
var_dump(null == 0); // bool(true) - null приводится к 0
Это поведение - главный источник багов в старом PHP-коде.
strict-сравнение и strict_types
Чтобы не зависеть от юглинга, сравнивай через === (учитывает тип):
<?php
var_dump('10' === 10); // bool(false) - разные типы
var_dump(0 === false); // bool(false)
var_dump('hello' === 'hello'); // bool(true)
В начале файла можно объявить строгий режим, и тогда PHP перестанет молча кастовать аргументы функций:
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
add(2, 3); // 5
add('2', '3'); // TypeError - строки не примутся
В современных проектах declare(strict_types=1) ставят в каждом файле как стандарт.
Область видимости (scope)
Переменная, объявленная вне функции, не видна внутри неё - это спасает от случайных мутаций глобального состояния:
<?php
$name = 'Иван';
function greet() {
echo "Привет, $name"; // $name == null, warning о неопределённой переменной
}
Чтобы протащить значение - передавай его как аргумент. Ключевое слово global существует, но в нормальном коде его избегают:
<?php
function counter() {
static $n = 0; // переменная переживёт вызовы функции
return ++$n;
}
echo counter(); // 1
echo counter(); // 2
echo counter(); // 3
static внутри функции - это «локальная переменная с памятью между вызовами», часто встречается в кешах и счётчиках.
Инструменты отладки
| Функция | Когда применять |
|---|---|
var_dump($x) | Подробно: тип + значение, для массивов - рекурсивно |
print_r($x) | Человекочитаемо, без типов; подойдёт для логов |
var_export($x) | Возвращает строку, которую можно вставить обратно в код |
get_debug_type($x) | Тип одной переменной (включая имя класса для объектов) |
В Symfony есть удобный helper dump($x) из symfony/var-dumper - он рисует значения с подсветкой и сворачивает большие структуры.
Типичные ошибки
- Сравнение через
==."0abc" == 0→true,"" == null→true. Используй===, если не уверен. - Случайные опечатки в именах. PHP молча создаст новую переменную и присвоит
null. Включиerror_reporting(E_ALL)в dev - будет warning. - Касты вместо валидации.
(int)$_GET['id']спрячет невалидный ввод вместо того, чтобы вернуть 400. Для пользовательского ввода -filter_varили Symfony Validator. - Глобальное состояние через
global. Делает функции непредсказуемыми и нетестируемыми. Передавай параметры явно. - Магические числа и строки.
if ($status == 1)- что такое 1? Замени на константу или enum (PHP 8.1+); подробнее про сравнение - в уроке про условия.
Best practices
- В каждом новом файле -
declare(strict_types=1);. - Имена переменных на английском, в
camelCase:$userEmail, не$user_emailи не$e. - Для сравнений -
===и!==по умолчанию. - Для типов в API -
mixed,?T(nullable) и unionT|U(PHP 8) точнее, чем безтиповая сигнатура. - Не превращай числа в строки преждевременно: формат - это задача вывода, а не модели.
Мини-задание
- Объяви три переменные разных типов, выведи их через
var_dumpиget_debug_type. - Собери строку приветствия тремя способами: интерполяция, конкатенация,
sprintf. - Поставь
declare(strict_types=1);в файл и попробуй передать в типизированную функцию строку вместо числа - получи и прочитай TypeError.