Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 148 · С нуля → справочник

Проверка символов: полный справочник Ctype

Одиннадцать функций: цифры, буквы, регистр, пробелы, управляющие и HEX-символы. От одной строки до правил импорта и полей формы, с разбором Unicode и нестрокового входа.

Проверить текст кода, а не превратить его в число

Наглядная модель

Код 0041 проходит проверку, сохраняя ведущие нули

Задача первой программы — проверить состав кода посылки. Внутри остаётся строка, арифметического преобразования нет.

  1. $code = "0041"

    Четыре текстовых символа: 0, 0, 4, 1.

  2. ctype_digit($code)

    Каждая позиция — цифра, поэтому функция возвращает true.

  3. var_dump(...)

    Показывает bool(true), ответ проверки.

  4. echo $code

    Выводит исходные 0041. Нули остались на своих местах.

При "00A1" проверка даст false. Это модель последовательной проверки условия, а не изображение расположения байтов в памяти. Существование посылки в базе проверяется отдельно.

На наклейке посылки написано 0041. Это код из четырёх цифр: ведущие нули должны сохраниться. Прежде чем искать посылку, сайт проверяет, что посетитель ввёл только цифры. Семейство ctype отвечает именно на вопросы о составе строки. Оно не превращает код в число, не исправляет его и не ищет посылку в базе.

Проверка кода 0041
  1. В переменную $code помещена строка "0041".
  2. ctype_digit($code): 0 — цифра; 0 — цифра; 4 — цифра; 1 — цифра.
  3. Все позиции подходят → результат true.
  4. var_dump показывает ответ проверки. echo отдельно показывает неизменившийся код 0041.
Первый вызов: проверить одну строкуСамостоятельный пример
<?php
$code = "0041";
var_dump(ctype_digit($code));
echo $code;
Ожидаемый результат
bool(true)
0041

$ обозначает переменную; = сохраняет строку; кавычки сохраняют нули как часть текста. Скобки после имени функции передают значение на проверку. true означает «да». var_dump выводит тип bool и результат; echo печатает сам код. Точка с запятой завершает инструкцию. Циклы и регулярные выражения для этого вызова не нужны.

Теперь измените один символ на букву: "00A1" даст false. Даже три правильные цифры не компенсируют одну неподходящую букву. Перед продолжением полезно понимать переменную и вызов функции и её результат.

Один договор у всех одиннадцати функций

Передаём строку, получаем true или false. Проверяется каждый её байт: все должны относиться к выбранной группе. ctype_alpha("Ab") разрешает смесь регистров; ctype_lower("Ab") — нет. Ни одна функция семейства не считает пустую строку подходящей. Ответ false не сообщает позицию ошибки — при необходимости её находят отдельным проходом.

Пустота и один пробел
  1. Вход "": нет символов → digit=false и space=false.
  2. Вход " ": один пробел → space=true.
  3. Проверка обязательности поля отдельно объединяет нужные случаи.
Пустое значение и строка с пробелом — разные случаиСамостоятельный пример
<?php
var_dump(ctype_digit(""));
var_dump(ctype_space(""));
var_dump(ctype_space(" "));
Ожидаемый результат
bool(false)
bool(false)
bool(true)

В первых двух строках нет символов для проверки: результат false. В третьей строке есть один пробел, поэтому ctype_space возвращает true. Проверка обязательного поля должна отдельно решить, что делать с пустой строкой.

LC_CTYPE — настройка локали для классификации символов. В локали C буквами являются A–Z и a–z. В других однобайтовых локалях группы могут отличаться. UTF-8 хранит многие буквы несколькими байтами; ctype не собирает их в символ Unicode. Для русских имён, диакритики и разных письменностей выберите Unicode-правило, а не случайно подходящую серверную локаль.

В PHP 8.1+ любой нестроковый аргумент устарел. Особенность старого режима: int от −128 до 255 трактуется как код одного байта; к отрицательному прибавляется 256. Другие int проверяются как десятичная строка. Поэтому ctype_digit(48) исторически проверяет символ "0", а не текст "48". Не полагайтесь на эту неоднозначность. Если по договору нужен текст числа, явно создайте (string) $number; если символ по коду — chr($number). Для данных формы сначала is_string, а не безусловное приведение массива в строку.

Один int может означать текст числа или код символаСамостоятельный пример
<?php
$number = 65;
var_dump(ctype_alpha((string) $number));
var_dump(ctype_alpha(chr($number)));
Ожидаемый результат
bool(false)
bool(true)

(string) 65 создаёт "65": это цифры, не буквы. chr(65) создаёт ASCII-букву A. Оба аргумента уже строки, предупреждения об устаревшем нестроковом входе нет. Это объяснение старого поведения, а не совет преобразовывать любые входные данные без проверки.

Требования, установка и проверка окружения

Ctype использует стандартную библиотеку C и не требует сторонней библиотеки для классификации. В обычной сборке расширение включено по умолчанию; при сборке PHP его можно отключить флагом --disable-ctype. В стандартной Windows-сборке поддержка встроена: добавлять строку extension=ctype ради неё не требуется. Состав пакета дистрибутива или контейнера всё равно проверяют в том PHP, который обслуживает приложение.

Две проверки доступности в одном процессе
  1. Запущенный PHP имеет свой список расширений.
  2. extension_loaded("ctype") ищет расширение.
  3. function_exists("ctype_digit") ищет доступную функцию.
  4. true и true в примере подтверждают возможность перейти к проверкам символов.
Убедиться, что расширение и функция доступныСамостоятельный пример
<?php
var_dump(extension_loaded("ctype"));
var_dump(function_exists("ctype_digit"));
Ожидаемый результат
bool(true)
bool(true)

Ожидаемый результат указан для окружения примеров с ctype. Если получается false, сначала уточните сборку, пакет и конфигурацию; CLI и сервер сайта могут запускать разные PHP. Composer-библиотека не включает отсутствующее нативное расширение сама.

Как сравнить CLI и веб-сервер, разобрано в настройке PHP. Здесь нет собственной группы директив ctype: поведение классификации зависит от локали. Не ставьте LC_ALL ради одной проверки — этим можно затронуть формат чисел и другие категории локали.

ASCII, Unicode и границы проверки

Следующий опыт меняет настройку, поэтому сначала разберём его каркас. if проверяет, удалось ли прочитать и установить локаль. === false сравнивает именно с признаком неудачи, а || означает «хотя бы одна проверка неуспешна». throw останавливает обычный путь, передавая ошибку вызывающему коду. В try находится сам опыт; finally возвращает прежнюю локаль при обычном завершении блока или передаче исключения. Эти конструкции подробно объясняются в условиях и границах выполнения и обработке ошибок. Здесь они нужны, чтобы демонстрация не оставила после себя изменённую настройку.

Одинаковая строка, разные правила классификации
  1. Сохранить прежнюю локаль → установить LC_CTYPE=C.
  2. Анна как UTF-8-байты → ctype_alpha=false.
  3. Анна как Unicode-буквы в PCRE → совпадение, true.
  4. U+00A0 не ASCII-пробел → ctype_space=false; finally восстанавливает настройку.
Явно проверить байтовый режим и Unicode-альтернативуСамостоятельный пример
<?php
$previous = setlocale(LC_CTYPE, 0);
if ($previous === false || setlocale(LC_CTYPE, "C") === false) {
    throw new RuntimeException("Не удалось настроить локаль примера");
}
try {
    var_dump(ctype_alpha("Анна"));
    var_dump(preg_match('/\A\p{L}+\z/u', "Анна") === 1);
    var_dump(ctype_space("\u{00A0}"));
} finally {
    setlocale(LC_CTYPE, $previous);
}
Ожидаемый результат
bool(false)
bool(true)
bool(false)

Это следующий, более сложный опыт: setlocale с 0 читает настройку, C задаёт известный режим; finally восстанавливает прежний. preg_match проверяет Unicode-буквы: \A и \z ограничивают всю строку, \p{L} обозначает буквы, + требует одну или больше, u включает UTF-8. Неразрывный пробел U+00A0 не совпал с байтовой ctype_space. Сложные имена могут включать составные знаки, дефисы и пробелы; правило «только буквы» — не готовая проверка ФИО.

Локаль — состояние окружения, а не параметр конкретного вызова ctype. В многопоточном окружении setlocale может затронуть соседние потоки; начиная с PHP 7.0.5 на Windows информация локали поддерживается на уровне потока. Восстановление через finally полезно, но не устраняет гонку в окружении с общей локалью. В библиотеке предпочтительнее явно заданный ASCII/Unicode-шаблон без смены локали.

Разбор шаблонов и трёх исходов preg_match (1, 0, false) — регулярные выражения. Для отдельной кодовой точки Unicode есть методы IntlChar; обычная многобайтовая строка и одна кодовая точка — разные входы.

Выбрать проверку по задаче

Нужно проверитьПодходитНужно дополнительно
Код посылки содержит только цифрыctype_digitДлина, допустимость нулей, существование кода и права на просмотр.
Артикул из букв и цифрctype_alnumЛокаль, длина; дефис и подчёркивание сюда не входят.
Однобайтовая буквенная командаctype_alphaСписок разрешённых команд; буквы не означают право выполнить действие.
HEX-цвет без #ctype_xdigitРазрешённая длина 3/4/6/8 по своему контракту.
Пустой по смыслу ASCII-текстctype_spaceОтдельно пустая строка; Unicode-пробелы требуют другого правила.
Весь текст состоит из управляющих байтовctype_cntrlДля поиска хотя бы одного управляющего байта нужен отдельный проход.
Все символы печатные, пробел допустимctype_printЭто не HTML-экранирование и не универсальная проверка Unicode.
Печатный текст без пробеловctype_graphЭто не проверка URL, имени файла или токена авторизации.

Каждая ctype-проверка в худшем случае просматривает всю строку: работа растёт с её длиной. Сначала ограничьте длину входа, затем выполняйте проверки. Не разбивайте весь файл в массив символов ради одной проверки. Обещание «всегда быстрее регулярного выражения» некорректно: сравнивать нужно одинаковые правила и реальные данные.

Проверить свой выбор на реальных требованиях

  • Поле quantity="0007": ctype_digit вернёт true, но разрешение ведущих нулей и диапазон количества — отдельное правило. Не используйте такой ответ как автоматическое разрешение заказа.
  • Поле name="Анна-Мария": ctype_alpha не подходит для такого Unicode-имени. Сначала определите допустимую модель имени, затем выберите проверку.
  • Пустая строка в списке через |: используйте $item !== "" и !ctype_space($item), чтобы не отбрасывать полезный текст "0".
  • Поле code[]=123: это массив, а не строка. is_string должен остановить проверку до ctype.
  • Строка id="12e3": is_numeric допускает числовую экспоненту, ctype_digit — нет. Выберите формат по договору API.

Серверная функция проверяет уже пришедший запрос. Она не блокирует клавиши в браузере. HTML-атрибуты помогают вводу, но серверная проверка остаётся обязательной: поле формы → POST → проверка.

Все функции Ctype

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

ctype_alnumПроверить, что короткий технический код состоит из букв и цифр.

PHP 4.0.4+ · ctype

ctype_alnum(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый символ — буква либо цифра. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "SKU42" → S,K,U — буквы; 4,2 — цифры → true.
  2. "SKU_42" → _ не буква и не цифра → false.
Буквы и цифры можно смешивать, подчёркивание нельзяСамостоятельный пример
<?php
var_dump(ctype_alnum("SKU42"));
var_dump(ctype_alnum("SKU_42"));
var_dump(ctype_alnum(""));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

alnum объединяет alphabetic и numeric. Наличие букв не обязательно: "42" тоже подходит. Проверяется состав, а не формат артикула.

Отобрать короткие артикулы партнёраСамостоятельный пример
<?php
$codes = ["BR41", "BR-41", ["BR41"], "123456789"];
foreach ($codes as $code) {
    if (!is_string($code) || strlen($code) > 8 || !ctype_alnum($code)) {
        echo "Отклонён\n";
        continue;
    }
    echo "Код: ", $code, "\n";
}
Ожидаемый результат
Код: BR41
Отклонён
Отклонён
Отклонён

Массив моделирует строки импорта. foreach берёт следующий элемент. || прекращает вычисление после истинного условия, поэтому массив не попадёт в strlen/ctype. continue пропускает неподходящий элемент. Длина проверена до посимвольного прохода.

Не применяйте этот договор к произвольным именам людей. Для ASCII-артикулов с дефисом понадобится явный набор разрешённых символов; не удаляйте дефисы молча, иначе разные артикулы могут стать одинаковыми.

Рядом: ctype_alpha, ctype_digit, ctype_graph. Общие правила: тип входа, локаль и Unicode.

ctype_alphaПроверить буквенное поле технического протокола.

PHP 4.0.4+ · ctype

ctype_alpha(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если все символы — буквы текущей локали. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "Ready" → R,e,a,d,y подходят, регистр может различаться.
  2. "Ready2" → последняя позиция 2 не буква → false.
Буквы любого регистра, но без пробеловСамостоятельный пример
<?php
var_dump(ctype_alpha("Ready"));
var_dump(ctype_alpha("Ready now"));
var_dump(ctype_alpha("Ready2"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

Ready содержит только буквы. Второй ответ отрицательный из-за пробела, третий — из-за цифры. Проверка не меняет регистр.

Проверить форму команды и затем разрешённое действиеСамостоятельный пример
<?php
foreach (["ping", "delete", "ping2"] as $command) {
    if (strlen($command) > 12 || !ctype_alpha($command)) {
        echo "Неверная форма команды\n";
    } elseif (!in_array($command, ["ping", "status"], true)) {
        echo "Команда не разрешена\n";
    } else {
        echo "Разрешена: ", $command, "\n";
    }
}
Ожидаемый результат
Разрешена: ping
Команда не разрешена
Неверная форма команды

Сначала проверен состав короткой строки, затем белый список. Третий аргумент true у in_array включает строгое сравнение. Здесь ничего не отправляется и не выполняется: это модель выбора разрешённой команды.

Для всей строки ctype_alpha не равно ctype_upper(...) || ctype_lower(...): смешанный регистр допустим только первому. Для одного символа в C такое объединение совпадает. В Unicode встречаются буквы без верхнего/нижнего регистра; не расширяйте однобайтовую модель на них.

Рядом: ctype_alnum, ctype_lower, ctype_upper. Общие правила: тип входа, локаль и Unicode.

ctype_cntrlИсследовать управляющие байты в строке протокола или импорта.

PHP 4.0.4+ · ctype

ctype_cntrl(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если вся строка состоит из управляющих символов. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "ORD\n41" → проверка целой строки даёт false.
  2. Проверки отдельных позиций: O нет, R нет, D нет, перевод строки да.
  3. Вернуть позицию 3, не печатая скрытый управляющий байт.
Вся строка из управляющих байтов и один перевод строки внутри текстаСамостоятельный пример
<?php
var_dump(ctype_cntrl("\r\n\t"));
var_dump(ctype_cntrl("Order\n41"));
var_dump(ctype_cntrl(" "));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

В двойных кавычках \r, \n, \t обозначают возврат каретки, перевод строки и табуляцию. Обычный пробел не управляющий символ. false во втором случае не означает отсутствия управляющего байта: не все байты управляющие.

Найти перевод строки в техническом идентификатореСамостоятельный пример
<?php
function firstControlByte(string $text): ?int
{
    $length = strlen($text);
    for ($position = 0; $position < $length; $position++) {
        if (ctype_cntrl($text[$position])) {
            return $position;
        }
    }
    return null;
}
var_dump(firstControlByte("ORD\n41"));
var_dump(firstControlByte("ORD41"));
Ожидаемый результат
int(3)
NULL

Функция возвращает позицию первого управляющего байта либо null. Индексы строки начинаются с 0: O=0, R=1, D=2, перевод=3. for проверяет по одному байту, поэтому здесь вопрос «есть хотя бы один». Результат 0 был бы допустимой позицией; проверяйте !== null, а не if($position).

Отклонить ID с невидимым переводом строки и показать причинуСамостоятельный пример
<?php
$identifiers = ["ORD41", "ORD\n42"];
foreach ($identifiers as $identifier) {
    $badPosition = null;
    for ($position = 0; $position < strlen($identifier); $position++) {
        if (ctype_cntrl($identifier[$position])) {
            $badPosition = $position;
            break;
        }
    }
    if ($badPosition !== null) {
        echo "Строка импорта отклонена: управляющий байт на позиции ", $badPosition, "\n";
        continue;
    }
    echo "Можно искать заказ: ", $identifier, "\n";
}
Ожидаемый результат
Можно искать заказ: ORD41
Строка импорта отклонена: управляющий байт на позиции 3

Партнёр выгрузил ID заказов; в один попал невидимый перевод строки. Если незаметно убрать его, значение изменится и может совпасть с чужим ID. Поэтому импорт отклоняет строку и сообщает позицию. break завершает внутренний поиск после первого сбоя, continue переходит к следующему ID. !== null сохраняет правильную обработку ошибки на позиции 0. Вывод здесь консольный: в HTML сообщения экранируют. Остальные правила ID и наличие заказа проверяются следующим шагом.

В C это байты 0–31 и 127. Проверка не находит все Unicode-управляющие знаки или форматирующие символы. Не считайте удаление этих байтов универсальной очисткой: иногда перевод строки допустим, иногда вход нужно отклонить и сообщить об ошибке, а не менять ID.

Рядом: ctype_print, ctype_graph, ctype_space. Общие правила: тип входа, локаль и Unicode.

ctype_digitПроверить код из десятичных цифр без знака, точки и пробелов.

PHP 4.0.4+ · ctype

ctype_digit(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый символ — десятичная цифра. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "0041" → четыре цифры → true.
  2. strlen("0041") → 4; оба требования формата выполнены.
  3. Код остаётся "0041", приведение к int не производится.
Цифровая строка не обязана быть обычным целым PHPСамостоятельный пример
<?php
var_dump(ctype_digit("007"));
var_dump(ctype_digit("-7"));
var_dump(ctype_digit("7.0"));
var_dump(ctype_digit("7e2"));
var_dump(ctype_digit("0"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)
bool(false)
bool(true)

Знак, точка и буква e не цифры. Ноль и ведущие нули допустимы для проверки символов. Большая строка цифр тоже может пройти, хотя её число не помещается в int.

Проверить формат четырёхзначного кода, сохранив нулиСамостоятельный пример
<?php
function hasFourDigits(mixed $value): bool
{
    return is_string($value) && strlen($value) === 4 && ctype_digit($value);
}
foreach (["0041", "41", "4e01", ["0041"], 41] as $value) {
    if (!hasFourDigits($value)) {
        echo "Введите код из четырёх цифр\n";
        continue;
    }
    $parcels = ["0041" => "Передана курьеру"];
    echo "Посылка ", $value, ": ", $parcels[$value] ?? "не найдена", "\n";
}
Ожидаемый результат
Посылка 0041: Передана курьеру
Введите код из четырёх цифр
Введите код из четырёх цифр
Введите код из четырёх цифр
Введите код из четырёх цифр

mixed разрешает функции принять любой PHP-тип и самой вернуть отказ. && означает «все условия верны» и останавливается при первом false. Сначала функция отвечает на маленький вопрос о формате. Вызывающий код использует ответ: при ошибке выводит подсказку, при успехе ищет посылку в учебном массиве. Код 0041 остаётся строкой с нулями. Добавьте в список 9999: формат правильный, но посылка не найдена. Нативный int 41 сознательно не принимаем: по договору поле должно быть текстом. Это не проверка подлинности секретного PIN: срок действия, доступ и ограничение попыток потребовали бы отдельной логики.

Для формы с quantity сначала проверяют строку и длину, затем допустимый диапазон перед приведением к int. Если требуется математическое число со знаком/дробью/экспонентой, посмотрите is_numeric. Если требуется сам тип int — is_int. Преобразование intval не является проверкой корректности исходной строки.

Не применяйте empty к результату ввода до этой проверки, если "0" допустим. Для телефона цифры — только часть формата: код страны, длина, международный знак + и подтверждение владения требуют отдельного договора.

Рядом: ctype_alnum, ctype_xdigit, ctype_space. Общие правила: тип входа, локаль и Unicode.

ctype_graphПроверить печатное поле без пробельных символов.

PHP 4.0.4+ · ctype

ctype_graph(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если все байты печатные и не пробельные. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "ORD-41" → буквы, дефис, цифры → true.
  2. "ORD 41" → позиция с пробелом нарушает условие → false.
Печатный текст без пробеловСамостоятельный пример
<?php
var_dump(ctype_graph("ORD-41"));
var_dump(ctype_graph("ORD 41"));
var_dump(ctype_graph("ORD\t41"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

Дефис разрешён как печатный символ; обычный пробел и табуляция не проходят. graph — не сокращение от графика: речь о видимых печатных символах.

Отобрать непробельные части учебной строки протоколаСамостоятельный пример
<?php
$parts = explode(" ", "SEND  ORD-41");
foreach ($parts as $part) {
    if (ctype_graph($part)) {
        echo $part, "\n";
    }
}
Ожидаемый результат
SEND
ORD-41

explode разделяет по каждому обычному пробелу. Два пробела создают пустую часть: ctype_graph её отклоняет. Такой разбор подходит только простому договору без кавычек и вложенных значений; полноценному языку нужен его парсер.

Знаки /, <, > и кавычки тоже могут пройти. Поэтому результат не делает текст безопасным путём файла, HTML или SQL. Для вывода по-прежнему нужен соответствующий контексту способ защиты.

Рядом: ctype_print, ctype_alnum, ctype_punct. Общие правила: тип входа, локаль и Unicode.

ctype_lowerПроверить буквенное слово в нижнем регистре.

PHP 4.0.4+ · ctype

ctype_lower(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый символ — строчная буква текущей локали. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "draft" → пять строчных букв → true.
  2. "draft2" → 2 не строчная буква → false.
Все символы должны быть именно строчными буквамиСамостоятельный пример
<?php
var_dump(ctype_lower("draft"));
var_dump(ctype_lower("draft2"));
var_dump(ctype_lower("Draft"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

Цифра 2 не является строчной буквой, хотя не имеет верхнего регистра. Поэтому ctype_lower и «нет заглавных букв» — разные условия.

Вынести правило простого имени раздела в функциюСамостоятельный пример
<?php
function isSectionWord(string $name): bool
{
    return strlen($name) <= 20 && ctype_lower($name);
}
foreach (["catalog", "my-catalog", "Catalog", ""] as $name) {
    if (!isSectionWord($name)) {
        echo "Имя раздела не подходит\n";
        continue;
    }
    $pages = ["catalog" => "Каталог товаров", "contacts" => "Контакты"];
    echo $pages[$name] ?? "Раздел не найден", "\n";
}
Ожидаемый результат
Каталог товаров
Имя раздела не подходит
Имя раздела не подходит
Имя раздела не подходит

Этот договор разрешает только короткое слово из строчных букв. После проверки вызывающий код выбирает заголовок из известного списка; catalog открывает каталог. Добавьте news: строка допустима, но раздел не найден. PHP-файлы по пользовательскому пути здесь не подключаются. Если проекту нужны дефисы или цифры, меняют правило осознанно; слепое удаление знаков может столкнуть разные имена. Для UTF-8-названий ctype_lower не подходит.

Функция не приводит текст к нижнему регистру. Сравнение strtolower($text) === $text имеет другой смысл: например, цифры не изменяются и тоже пройдут сравнение. Для UTF-8 нужен подходящий Unicode-инструмент, а для допустимого идентификатора — полный договор его символов.

Рядом: ctype_upper, ctype_alpha, ctype_alnum. Общие правила: тип входа, локаль и Unicode.

ctype_printПроверить однострочное печатное поле, в котором допустим пробел.

PHP 4.0.4+ · ctype

ctype_print(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый байт печатный, включая обычный пробел. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "Order 41" → пробел допустим → true.
  2. "Order\n41" → управляющий перевод строки → false.
  3. " " → print=true, space=true; прикладное правило может отклонить.
Пробел печатный, перевод строки — нетСамостоятельный пример
<?php
var_dump(ctype_print("Order 41"));
var_dump(ctype_print("Order\n41"));
var_dump(ctype_print(" "));
Ожидаемый результат
bool(true)
bool(false)
bool(true)

print в названии означает группу печатных байтов: сама функция ничего не печатает. Печатает var_dump. Обычный пробел допустим, управляющий перевод строки нет.

Проверить ASCII-подпись для старого однострочного устройстваСамостоятельный пример
<?php
$labels = ["Order 41", "   ", "Order\n41"];
foreach ($labels as $label) {
    $valid = strlen($label) <= 24 && ctype_print($label) && !ctype_space($label);
    echo $valid ? "Можно передать\n" : "Исправьте подпись\n";
}
Ожидаемый результат
Можно передать
Исправьте подпись
Исправьте подпись

Условие моделирует устройство, которое принимает до 24 печатных ASCII-байтов в одной строке. Дополнительный !ctype_space отвергает подпись только из пробелов. Реального сетевого вызова нет. Перед поддержкой русского текста нужно изменить контракт устройства и кодировки, а не просто убрать проверку.

ctype_print не означает «текст хорошо отобразится в браузере». Управляющие последовательности, кодировка и HTML-контекст — разные вопросы. Проверка также не гарантирует, что в строке есть содержательное слово или что она подходит принтеру конкретной модели.

Рядом: ctype_graph, ctype_space, ctype_cntrl. Общие правила: тип входа, локаль и Unicode.

ctype_punctПроверить группу печатных небуквенных и нецифровых знаков.

PHP 4.0.4+ · ctype

ctype_punct(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый символ печатный и не относится к буквам, цифрам или пробелам. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "-_" → два знака пунктуации → true.
  2. "A!" → A не пунктуация → false.
  3. ";" → класс подходит, отдельный список разрешает разделитель.
Пунктуация включает технические знакиСамостоятельный пример
<?php
var_dump(ctype_punct("-_"));
var_dump(ctype_punct("!?"));
var_dump(ctype_punct("A!"));
var_dump(ctype_punct("! "));
Ожидаемый результат
bool(true)
bool(true)
bool(false)
bool(false)

В C сюда входят печатные знаки, которые не являются буквами, цифрами или пробелами. Подчёркивание — один из них. В A! одна буква, поэтому вся строка не состоит из пунктуации.

Проверить разделитель текстового отчётаСамостоятельный пример
<?php
function validReportSeparator(string $separator): bool
{
    return strlen($separator) === 1
        && ctype_punct($separator)
        && in_array($separator, [";", "|", ","], true);
}
foreach ([";", "||", "<", " "] as $separator) {
    if (!validReportSeparator($separator)) {
        echo "Этот разделитель не поддерживается\n";
        continue;
    }
    $output = fopen('php://output', 'w');
    fputcsv($output, ['Артикул', 'Цена'], $separator, '"', '');
    fputcsv($output, ['BR41', '250'], $separator, '"', '');
    fclose($output);
}
Ожидаемый результат
Артикул;Цена
BR41;250
Этот разделитель не поддерживается
Этот разделитель не поддерживается
Этот разделитель не поддерживается

Получили настоящий текст отчёта с выбранным разделителем. php://output направляет запись в вывод программы; для файла передают путь к файлу. fputcsv учитывает кавычки и разделители внутри полей, пятый аргумент отключает нестандартное экранирование обратной косой чертой. Длина оставляет один байт, ctype_punct проверяет его класс, белый список сужает возможности. В таком коротком списке ctype-проверка избыточна: в рабочем коде достаточно списка. Она оставлена здесь, чтобы различить класс символа и разрешённые настройки отчёта.

Это не способ обнаружить «любой спецсимвол» во всём тексте или проверить надёжность пароля. HTML-знаки тоже пунктуация; они не становятся безопасными для вставки в HTML. Unicode-категории пунктуации шире байтового Ctype.

Рядом: ctype_alnum, ctype_graph, ctype_print. Общие правила: тип входа, локаль и Unicode.

ctype_spaceУзнать, состоит ли всё значение из пробельных символов.

PHP 4.0.4+ · ctype

ctype_space(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если все символы относятся к пробельной группе. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. Разделение по | → "Поставка", " ", "0", "", "Монтаж".
  2. " " → space=true; "" → проверка длины; оба пропускаем.
  3. "0" → space=false; сохраняем полезное значение.
Все символы пробельные, а не просто где-то есть пробелСамостоятельный пример
<?php
var_dump(ctype_space(" \t\r\n"));
var_dump(ctype_space("A B"));
var_dump(ctype_space(""));
var_dump(ctype_space("0"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)
bool(false)

Кроме обычного пробела группа включает горизонтальную/вертикальную табуляцию, перевод строки, возврат каретки и перевод страницы. Пустая строка не пробельная строка. "0" — содержательный текст, его нельзя отбрасывать как пустой только из-за приведения к bool.

Не создавать пустые пункты отчёта и сохранить нулевой пунктСамостоятельный пример
<?php
$items = explode("|", "Поставка|   |0||Монтаж");
foreach ($items as $item) {
    if ($item === "" || ctype_space($item)) {
        continue;
    }
    echo $item, "\n";
}
Ожидаемый результат
Поставка
0
Монтаж

Отдельно исключили нулевую длину и строку только из ASCII-пробелов. В остальных элементах ничего не меняем. Кириллица в непустом пункте просто не пробельная; это не попытка классифицировать её буквы. Для скопированных Unicode-пробелов нужен другой явный договор.

trim($text) === "" и ctype_space($text) не полностью взаимозаменяемы: отличаются пустая строка и наборы байтов (например NUL). trim может ещё и изменить значение, если результат присвоить. Неразрывный пробел UTF-8 не становится обычным ASCII-пробелом от внешнего сходства.

Рядом: ctype_cntrl, ctype_print, ctype_graph. Общие правила: тип входа, локаль и Unicode.

ctype_upperПроверить буквенный технический код в верхнем регистре.

PHP 4.0.4+ · ctype

ctype_upper(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если каждый символ — заглавная буква текущей локали. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "USD" → три заглавные буквы → true.
  2. "ZZZ" тоже проходит класс символов; список магазина отклоняет.
  3. "US2" → цифра не заглавная буква → false.
Заглавные буквы без цифр и разделителейСамостоятельный пример
<?php
var_dump(ctype_upper("USD"));
var_dump(ctype_upper("US2"));
var_dump(ctype_upper("Usd"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)

U, S, D — заглавные буквы. Цифра и строчная d не удовлетворяют требованию. Это проверка, не преобразование регистра.

Формат кода валюты и поддержка оплаты проверяются отдельноСамостоятельный пример
<?php
foreach (["USD", "ZZZ", "US2"] as $currency) {
    if (strlen($currency) !== 3 || !ctype_upper($currency)) {
        echo "Неверный формат\n";
    } elseif (!in_array($currency, ["RUB", "USD", "EUR"], true)) {
        echo "Валюта не поддерживается магазином\n";
    } else {
        echo "Поддерживается: ", $currency, "\n";
    }
}
Ожидаемый результат
Поддерживается: USD
Валюта не поддерживается магазином
Неверный формат

Три заглавные буквы — проверка формы. Поддерживаемые валюты — настройка нашего учебного магазина, а не полный международный каталог и не гарантия работы платёжного провайдера. В коде нет платежей.

Не равнозначно strtoupper($text) === $text: знаки и цифры не изменяются при таком преобразовании. Для кода валюты/страны проверка регистра не заменяет справочник действительных кодов.

Рядом: ctype_lower, ctype_alpha, ctype_alnum. Общие правила: тип входа, локаль и Unicode.

ctype_xdigitПроверить HEX-строку перед цветовым значением или разбором байтов.

PHP 4.0.4+ · ctype

ctype_xdigit(mixed $text): bool
Часть вызоваПравило
textСтрока для проверки. Хотя историческая сигнатура содержит mixed, в новом коде передавайте string. Нестроковый вход deprecated с PHP 8.1.
Результат booltrue, если все символы принадлежат 0–9, A–F, a–f. Пустая строка всегда даёт false. Исходная строка не меняется.
ОкружениеРасширение ctype; байтовая классификация с учётом LC_CTYPE. Это не проверка букв Unicode. Здесь ASCII-примеры для локали C.
Как проверка получает ответ
  1. "A2B3C4" → шесть разрешённых символов → true.
  2. Правило RGB требует длину 6 → добавить # и получить #a2b3c4.
  3. Для "abc" ctype=true, но RGB-правило длины и правило пар байтов дают отказ.
HEX — цифры и буквы A–F, без префиксаСамостоятельный пример
<?php
var_dump(ctype_xdigit("1aF0"));
var_dump(ctype_xdigit("0x1a"));
var_dump(ctype_xdigit("1g"));
var_dump(ctype_xdigit("abc"));
Ожидаемый результат
bool(true)
bool(false)
bool(false)
bool(true)

Шестнадцатеричная запись использует 0–9 и A–F в обоих регистрах. Префикс 0x не проходит из-за x. Нечётное количество символов допустимо для ctype_xdigit, но может не подходить следующей операции.

Принять только полный RGB-цвет без #Самостоятельный пример
<?php
function readRgbColor(mixed $raw): ?string
{
    if (!is_string($raw) || strlen($raw) !== 6 || !ctype_xdigit($raw)) {
        return null;
    }
    return "#" . strtolower($raw);
}
foreach (["A2B3C4", "abc", "#a2b3c4", "zzzzzz", ["A2B3C4"]] as $raw) {
    echo readRgbColor($raw) ?? "Нужны 6 HEX-символов", "\n";
}
Ожидаемый результат
#a2b3c4
Нужны 6 HEX-символов
Нужны 6 HEX-символов
Нужны 6 HEX-символов
Нужны 6 HEX-символов

Наше поле принимает ровно шесть HEX-символов без #. Это сознательно более узкое правило, чем все CSS-цвета. После проверки добавили # и унифицировали регистр. null обозначает отказ; ?? выбирает сообщение. Если цвет передают в query string с #, символ кодируют как %23: неэкранированный фрагмент URL серверу не отправляется. $_GET уже декодирован PHP; повторный urldecode не нужен.

Показать покупателю образец выбранного цветаСамостоятельный пример
<?php
$rawColor = "A2B3C4";
if (strlen($rawColor) === 6 && ctype_xdigit($rawColor)) {
    $cssColor = '#' . strtolower($rawColor);
    echo '<p>Цвет товара: <span style="display:inline-block;width:3em;height:1em;border:1px solid #333;background:',
        $cssColor, '"></span> ', $cssColor, '</p>';
} else {
    echo '<p>Нужно ровно 6 HEX-символов, например A2B3C4.</p>';
}
Ожидаемый результат
<p>Цвет товара: <span style="display:inline-block;width:3em;height:1em;border:1px solid #333;background:#a2b3c4"></span> #a2b3c4</p>

Сохраните как example.php и откройте через локальный PHP-сервер: появится цветной прямоугольник с подписью. В консоли вы увидите тот же HTML как текст. Функция сама ничего не рисует: она разрешает только шесть HEX-символов; PHP добавляет # и выдаёт HTML, браузер окрашивает span. Замените значение на FF8800 — образец станет оранжевым; zz8800 даст сообщение. Строгий список допустимых символов не позволяет вставить произвольный CSS в этот конкретный атрибут. Если значение приходит из формы, перед strlen отдельно проверьте is_string, как в предыдущем примере.

Результат этого PHP-кода в браузере

Цвет товара: #a2b3c4

Для hex2bin отдельно нужна чётная длинаСамостоятельный пример
<?php
foreach (["4142", "abc", "41ZZ"] as $hex) {
    if (strlen($hex) > 64 || strlen($hex) % 2 !== 0 || !ctype_xdigit($hex)) {
        echo "Неверный HEX-пакет\n";
        continue;
    }
    $bytes = hex2bin($hex);
    if ($bytes === false) {
        throw new RuntimeException("Не удалось декодировать HEX");
    }
    echo bin2hex($bytes), "\n";
}
Ожидаемый результат
4142
Неверный HEX-пакет
Неверный HEX-пакет

% 2 вычисляет остаток деления длины: 0 означает пары символов. 41 и 42 — два байта; bin2hex показывает их безопасным текстом вместо произвольного двоичного вывода. Максимум 64 символа — правило нашего маленького пакета, не лимит PHP. Проверка не обещает, что пакет соответствует протоколу или подписи.

ctype_xdigit не преобразует строку в int и не проверяет подлинность хеша/токена. Для двоичного декодирования длина должна быть чётной. Пустой HEX может иметь смысл в вашем протоколе, но ctype_xdigit("") возвращает false: разрешение пустого значения задавайте отдельно.

Рядом: ctype_digit, ctype_alnum, ctype_graph. Общие правила: тип входа, локаль и Unicode.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.