appvs_php
PHP 8.0
Данный файл представляет собой конспект по изучению PHP, на базе книги PHP 8.0 Полное руководство. Так же доступен репозиторий данного проекта, с исходным кодом.
Наименование ветки , например .
В каждой ветке содержится свой README.MD файл с конспектом к материалу главы.
Оглавление
Часть I. Принцип работы интернета
Часть II. Основы языка PHP
- Характеристика языка PHP
- Переменные и типы данных
- Классы и объекты
- Константы
- Операторы
- Условия
- Циклы
- Массивы
- Функции и области видимости
- Функции. Часть 2
- Методы класса
- Генераторы
Часть III. Обработка текста и языка разметки HTML
- Строковые функции
- Язык разметки HTML
- Работа с данными формы
- Загрузка файлов на сервер
- Суперглобальные массивы
- Фильтрация и проверка данных
Часть IV. Стандартные функции PHP
- Математические функции
- Работа с файлами
- Работа с каталогами
- Права доступа и атрибуты файлов
- Запуск внешних программ
- Работа с датой и временем
- Основы регулярных выражений
- Разные функции
Часть V. Основы ООП
- Наследование
- Интерфейсы
- Трейты
- Перечисления
- Исключения
- Обработка ошибок
- Пространство имен
- Шаблоны проектирования
- Итераторы
- Отражения
Часть VI. Расширения PHP
- Подключение и настройка расширений
- Работа с PostgreSQL
- Расширения PDO
- Работа с изображениями
- Работа с сетью
- NoSQL-база данныз Redis
Часть VII. Компоненты
04. Характеристики
История
1994-1995: Зарождение
- Расмус Лердорф создал набор CGI-скриптов на Perl для отслеживания посещений своего онлайн-резюме
- Назвал его "Personal Home Page Tools" (Инструменты для персональной домашней страницы)
- 1995: Выпустил первую версию - PHP Tools 1.0 1995-1997: PHP/FI
- Переписал код на C и добавил больше функциональности
- Название сменилось на PHP/FI (Form Interpreter)
- Появились базовые возможности: работа с базами данных, переменные, встраивание в HTML 1997-1998: Рождение PHP 3
- Зив Сураски и Энди Гутманс переписали ядро
- Появился современный синтаксис и расширяемая архитектура
- Название сменилось на рекурсивный акроним: PHP: Hypertext Preprocessor
- Быстро набрал популярность 2000: PHP 4 - Zend Engine
- Новый движок Zend Engine (от Zeev и Andi)
- Улучшенная производительность
- Поддержка сессий, буферизация вывода
- Стал одним из самых популярных языков для веб-разработки 2004: PHP 5
- Полностью переработанная объектная модель
- Поддержка ООП с классами, наследованием, интерфейсами
- Встроенная поддержка MySQLi, SQLite
- Пространства имен, трейты (позже) 2015: Революция - PHP 7
- Новый движок Zend Engine 3
- Значительный прирост производительности (в 2 раза быстрее PHP 5.6)
- Скалярные типы, возвращаемые типы
- Оператор объединения с null (??) 2020: PHP 8
- JIT-компилятор (Just-In-Time)
- Атрибуты (аннотации)
- Match expression, named arguments
- Union types Ключевые факты:
- Создан для веб-разработки
- Прошел путь от простых скриптов до полноценного языка
- Остается одним из самых популярных языков для веба
- Используется в Wikipedia, Facebook, WordPress PHP эволюционировал от простого инструмента для "персональных домашних страниц" до мощного языка enterprise-уровня.
Характеристики
PHP-код может располагаться "вперемешку" с HTML-кодом. Для того чтобы интерпретатор мог различать HTML-код и PHP-код, последний обязательно обрамляется тегами . Далее в примерах кода теги будут опускаться во избежании экономии места, но помните, что без них программа на PHP работать не будет! Если PHP-код не прерывается, то закрывающий тег можно опустить. Совокупность конструкций ЯП, который завершается называется выражением. Например:
Как и большинство ЯП PHP поддерживает комментарии:
Комментарии игнорируются интерпретатором и нужны, как правило для обяъяснения сложной логики в коде.
PHP-файлы можно "включать" в другие PHP-файлы с помощью конструкций и .
05. Переменные и типы данных
Основные сведения
В PHP, как и в любом ЯП используются переменные. Отличие от других ЯП состоит в том, что названия переменных должны начинаться со знака - это необходимо интерпретатору PHP для быстрого определения переменной.
Ниже представлен пример объявления переменной. Этот процесс подразумевает сохранение значения переменной (справа от ) в ОЗУ компьютера, имя переменной - это идентификатор, по которому мы можем обращаться к ОЗУ для получения значения.
Переменные могут вычисляться при объявлении (присвоении значений)
Типы данных
- целое число
- число с плавающей точкой
- логический тип, принимает только и - строковый тип, хранит строки
- массив, те объединение нескольких значений под одним типом
- объект
- дескриптор, позволяющий оперировать ресурсом (как правило различные файлы, БД, динамические изображения)
- специаьный тип, который обозначает отсутствие значений
- функции обратного вызова
- отсутствие типа, используется для обозначения, что функция не возвращает значения
- используется для обозначения перечисляемого параметра или вовзращаемого значения
- любой тип (PHP 8.0)
- обозначение прерывания выполнения функции или исключения
Базовые типы: , , , ,
Составные типы: , ,
Псевдотипы: , , , ,
integer
Целое число. Принимает минимальное и максимальное значения в зависимости от разрядности ОС:
- 32-битная: от -2_147_483_648 до 2_147_483_647
- 64-битная: от -9_223_372_036_854_775_807 до 9_223_372_036_854_775_807
В случае переполнения целого числа автоматически будет использоваться тип double
double
Записывается в виде числа с плавающей точкой или экспоненциальной форме
Вычисления с подобными числами могут приводить к ошибкам, так как треть в представлении =
При переполнении используется констнта (бесконечность)
Так же в PHP ализована константа которая обозначает недопустимое число
boolean
Принимает только два значения: (истина) и (ложь)
0, пустая строка так же означают , в то время как ненулевое число и непустая строка -
Переменные логического типа активно используются с операторами сравнения
string
Строки предназначены для хранения текстовой информации. Ранее были ограничены в размере 2Гб, с PHP 8.0 это ограничение было снято.
В строках могут использоваться двойные и одинарные кавычки, различие заключается в том, что в двойные есть возможность вставлять переменные PHP (интерполяция строки).
Обратные кавычки рассматриваются как системная команда
Для экранирования символов внутри строки используется
Спец символы:
Для указания границ переменной внутри строки используются фигурные скобки
Оператор <<< - оператор "встроенный документ", используется для объявления строки (не прибегая к кавычкам). Сразу после оператора необходимо использовать маркер (метку):
Строки представляют собой последовательность символов, которые нумеруются, начиная с 0. Для обращения к символу строки используется конструкция с указанием индекса
array
Массив (ассциативный массив) = это набор из пар ключ => значение. Доступ к отдельным элементам массива, как и у строк, осуществляется c помощью указания ключа (индекса) в . В случае когда ключи не указываются, используется нумерация, начиная с 0.
object
Объекты - сложные структуры, которые могут слдержать в себе переменные и функции. Объект похож на ассоциативный массив, за исключением, что к свойствам и методам объекта обращение идет через . Объекты будут подробно рассмотрены далее в главах 06, 14, 30-39.
resource
Значением переменной этого типа является ссылка на внешний ресурс (например файл, соединение с БД, изображение)
null
Этот тип предназначен для неинициализированной переменной (отсутствие какого-либо значения). Следует учесть, что ОЗУ для значения null не выделяется, однако имя переменной записывается во внутренние таблицы интерпретатора PHP.
Действия с переменными
Присвоение значения
Значения для переменных можно присвоить или переопределить с помощью оператора . Исключение составляют объекты, которые инициализируются ключевым словом .
Уничтожение
Переменная уничтожается с помощью конструкции
Чаще всего конструкция применяется для удаления элемента из массива.
Проверка существования
Для предупреждения ошибки об отсутствии переменной (в примерах выше) существует конструкция , которая проверяет существование переменных.
Стоит обратить внимание, что проверяет именно наличие переменной. Для проверки значения переменной используется конструкция :
Определение типа переменной
Для определения типа используется ряд функций:
Приведение типов
В PHP существует неявное приведение типов - когда вычисляется выражение и типы автоматически "подстраиваются" под операнды выражения
Так же есть возможность явно приводить типы с помощью конструкций описанных ниже:
Явно преобразовать тип переменной можно с помощью фукции
Еще один способ преобразования - пользоваться следующими функциями:
Ссылки
Вспомним что переменные - это именованные области памяти. Имя переменной указывает на определенное значение в ОЗУ. Если две переменные будут указывать на одно и тоже место в памяти, то при изменении одной переменной, измениться и вторая. Жесткая ссылка - переменная, которая является синонимом другой переменной. Создается с помощью .
Ссылаться можно не только на переменные, но и на элементы массива. Однако в случае, если ссылаются на несуществующий элеент массива, то этот элемент будет добавлен в массив со значением .
Сбор мусора
Алгоритм сбора мусора заключается в том, что будут удаляться связи между объектом в памяти и ссылкой на него. Сам объект удалится из памяти только тогда, когда на него никто не будем ссылаться.
Символические ссылки
Это строковые переменные, которые хранят имя другой переменной. Для получения значения символический ссылки используется конструкция
Ссылки на объекты
Копируя объекты мы не создаем новые, а создаем ссылки. Это наглядно показано в примере ниже. Данное поведение объясняется тем, что копируется не объект а ссылка на него.
Отладочные функции
Для отладки в PHP существует несколько функций:
Теги позволяют форматировать вывод данных в более удобочитаемый формат. отличается от тем, что во второй указываются типы элементов. При выводе обратите внимание, что так же был выведен обратный слеш - эта функция выводит именно исполняеыц PHP-код.
06. Классы и объекты
Классы и объекты необходимы для упрощения восприятия программируемой логики. Вместо понятий память, процесс и прочие используются абстрактные понятия в виде классов и объектов. Класс всегда только один, объектов на основе класса может быть сколько угодно.
Класс подразумевает наличие объекта со своими свойствами (переменными) и функциями (методами).
В PHP поддерживаются обе парадигмы разработки ПО - функциональная и ООП (Объекто ориентируемое программирование). Помимо упрощения кода ООП обеспечивает безопасность использования - нельзя (по крайней мере очень затруднительно) взять объект кода и сложить его со каким-либо свойством объекта человека.
Использование готовых классов
В PHP есть множество встроенных классов. Например . Объект класса создается с использованием конструкции . Обращение к свойствам и вызов методов класса происходит с помощью конструкции
Если с помощью функции запросить тип переменной то увидим тип . Чтобы проверить на основании какого класса создался объект следует использовать функцию или воспользоваться вариантом, который появился в PHP 8.0:
Создание классов
Собственные классы создаются при помощи ключего слова и . В теле класса объявляются свойства (переменные) и методы (функции) для этого класса.
Перед названием свойства или метода пишется модификатор доступа: , , который управляет доступностью свойства или метода. Модификатор означает, что свойство может быть использлвано напрямую объектом. Свойство напротив, означает,что свойство доступно исключительно внутри класса. Обращение к приватному свойству через объект класса вызовет ошибку. Подробности обо всех модификаторах доступа будут далее.
Объект класса (как и в примере со встроенными классами PHP) объявляется с помощью , обращения к свойствам\методам с помощью . Обратите внимание, что при обращении к свойствам класса у названия свойства опускается .
Обратите внимание, что весь код класса обязательно должен находится внутри одной конструкции . То есть нельзя прерывать описание класса, вставить HTML- разметку, а после продолжить - в таком случае возникнет ошибка интерпретатора PHP. По этой же причине не получится разбить код класса на части и подключать с помощью и .
Объект класса существует до конца времени выполнения скрипта, либо пока его не уничтожат функцией .
Области видимости
Свойства объявленные в классе не доступны за его пределами
Типы переменных класса
Начиная с версии PHP 7.4 свойствам класса можно назвачать свой тип. Это называется "строгая типизация" и необходимо для ограничений взаимодействий со свойствами класса. Ниже представлен пример без указания типов и к каким ошибкам это может привести и исправленная версия.
Исправленная версия:
Конечно это все равно не убережет от ошибки, однако большинство редакторов кода будет информировать о недопустимости присвоения типу число значение строку, а так же другие разработчики будут понимать, что данное свойство исключительно целочисленное,что в итоге поможет избежать ошибок и недопониманий. Сейчас мы заменили одну ошибку другой, однако текущая ошибка явно говорит, что не так с кодом, когда как предыдущая просто сообщала о невозможности определенного действия с типами (непонятно почему такие типы были назначены).
Начиная с PHP 8.0 можно объявлять у переменных несколько типов свойств через знак . Такая конструкция называется объединенные типы.
Неиницилизораванным переменным задается тип null, его можно указать явно (рекомендуется) либо поставить перед типом знак .
readonly
Свойства класса можно помечать специальным модификатором . Он пишется после мидификатора доступа и перед типом свойства. Меня его значение снаружи невозможно, компилятор PHP выдаст ошибку. Так же ошибкой будет попытаться прочитать еще не инициализированное -свойство.
Для инициализации небоходимо либо создать собственный метод внутри класса либо воспользоваться встроенным методом .
В первом случае, перед обращением к -свойству необходимо сначала обратиться к нашему методу. Во втором случае - инициализация произойдет при создании объекта класса - так работает метод .
Внутри класса, для обращения к свойствам\методам используется специальная конструкция , которая указывает на текущий объект класса (соответсвенно у каждого объекта класса есть свой который указывает на себя). Обращение происходит с использованием .
Дамп объекта
Для того чтобы посмотреть на объект в виде отладки, можно пользоваться отладочными функциями, о которых говорилось выше. Дамп объекта будет содержать в том числе и закрытые свойства.
static-свойства
Статические свойства (переменные) это инициализированные свойства на уровне класса. Объявляются с помощью ключевого слова .
К таким свойствам можно обращаться без создания объекта, используя
Клонирование объектов
Как было сказано в 05. Переменные и типы данных мы не можем клонировать объекты так же как примитивные типы. При использовании оператора создадуться два объекта, каждый из которых будет ссылаться на одну и ту же область памяти.
Для создания полноценной независимой копии объекта используется конструкция
07. Константы
Предопределенные константы
В PHP существует множество предопределенных констант. Их список можно посмотреть с помощью следующей функции:
Особое внимание из этого списка можно уделить часто используемой константе - вне зависимости от используемой ОС она добавляет перенос строки.
Магические константы
Магические константы обрамляются символами двойного нижнего подчеркивания - . Далее представлен список магических констант и примеры из использования.
Из данного списка наиболее часто используется константа - она определяет текущее местоположение файла и за счет этого позволяет гибко управлять различными путями в проекте (например путем до файла, который находится на директорию выше). Ниже в примере используется функция - она проверяет существование указанного в скобках файла (путь до файла).
Создание констант
Константы создаются двумя способами - в файле используется функция , а внутри класса ключевое слово . Константы внутри класса так же имеют стандартные модификаторы доступа. Вызываются константы класса с помощью оператора разрешения области видимости .
08. Операторы
Операторы ; . ,
Оператор используется для обозначений конца выражения. В PHP практически все является выражением. Если выражение одно то оператор можно опустить, однако этого не рекомендуется делать. Возможна ситуация, когда код будет дополняться и про точку с запятой изначальной строки просто забудут, что вызовет ошибку.
Оператор используется для конкатенации (сложения) строк.
Оператор обычно используется в различных перечислениях (массивах), однако еще может быть использован в конструкции .
Арифметические операторы
Арифметические оперторы работают так же, как и в математике, с теми же приоритетами. Вручную задавать приоритеты можно с помощью скобок.
Так же к арифметическим относятся операторы инкремента и декремента . Они работают только с переменными (запись 1++ вызовет ошибку) и существуют в двух вариантах - префиксный и постфиксный. Отличие их заключается в том, что префиксный сразу же возвращает измененное значение, постфиксный - в следующем выражении(при использовании измененной переменной).
Операторы сравнения
Операторы сравнения уникальны тем, что всегда возвращают одно из двух значений - или . Стоит обратить внимание на операторы равенства и эквивалентности . При использовании оператора равенства PHP самостоятельно приводит типы, при использовании эквивалентности - сравниваются так же типы операндов. Так же сравниваются массивы и объекты (но нужно быть осторожным). При использовании массивы и объекты сравниваются "поверхностно".
Битовые операторы
Несколько сложны для понимания. Могут использоваться для кодирования иформации в двоичной системе счисления
Для примера - кодирвоание геометрических фигур и их цвета:
Приоритет операторов
Так как с каждой версией PHP возможно обновление приоритетов, то их лучше проверять в актуальной документации
09. Условия
Условия есть в каждом современном ЯП. Они необходимы для ветвления программы.
if
Конструкция предназначена для выполнения блока кода в зависимости от переданного условия. Условие представляет собой boolean тип.
Конструкция выполняется последовательно - сначала проверяется условие в блоке , затем во всех , и только если ни одно из уловий не является истинным, выполнится блок .
Конструкция поддерживает альтернативный синтаксис:
Логические операторы
Представляют собой набор конструкций, которые позволяют объединять boolean-выражения. Используются для проверки нескольких условий. Оператор работает тогда и только тогда, когда оба операнда истины. Оператор работает тогда, когда истин хотя бы один из операндов. Есть так же альтернативный синтаксис в виде и .
Логически операторы можно инвертировать - то есть проверять обратное значение:
Тернарный оператор
Представляет собой сокращенную запись для . Имеет сокращенный вариант записи в виде , который проверяет отличие переменной от , , , , однако обратите внимание, что в условии должны быть инициализированные переменные!
Оператор ??
Оператор проверки на (а означает неинициализированную переменную) решает проблему оператора при неинициализированной переменной. Он проверяет сразу существует ли значение,и если нет, то присваивает переменной значение справа от себя. Имеет сокращенную запись
switch
Оператор представляет собой аналог , однако при множестве условий выглядит более читаемым. В передается выражение, которое проверяется на истиность в блоках . Конструкция служит для прерывания дальнейшего выполнения. Конструкция - аналог , когда ни одно из переданных условий не является истинным.
Работает это таким образом: ВЫРАЖЕНИЕ В СКОБКАХ == БЛОК case. Если - выполняется код полсе .
Стоит обратить внимание, что подразумевает не строгое равенство .
Так же поддерживает альтернативный синтаксис (обратите внимание на условие, это пример как можно использовать для проверки большого количества boolean-выражений):
match
Оператор появился в PHP 8.0, в отличие от он сравнивает с помощью и возвращает значение,поэтому его можно присвоить переменной.
Для не предусмотренно значения по умолчанию ( или ).
10. Циклы
В PHP существуют несколько циклов - , , . Последний будет рассмотрен в следующем разделе.
Цикл позволяет выполнять блок инструкций несколько раз.
Цикл while, управление циклами
Цикл выполняется пока условие выполнения истино. Обратите внимание, что необходимо задавать условия для выхода из цикла, иначе он станет бесконечным и программа зависнет.
Циклы могут быть вложенными
С помощью конструкции можно прервать цикл
С помощью конструкции можно пропустить итерацию
Конструкция может прерывать внешние циклы с помощью указания цифры: 1 - текущий цикл, 2 - родительский, 3 - родитель родителя и т.д.
Цикл - это с постусловием, означает, что он выполнится хотя бы один раз
for
Цикл - самый популярный цикл в ЯП. Представляет собой конструкцию, где указывается переменная, условие выполнения цикла и операция для выполнения условия вызода их цикла.
Любую из конструкций можно пропустить. Но следите за тем, чтобы цикл не стал бесконечным!
Так же как и поддерживет конструкции (пример выше) и
11. Массивы
Общие сведения
Массивы - это наборы (последовательности) элементов. У каждого элемента массива есть свой уникальный индекс (порядковый номер). Посмотреть массив можно при помощи функции (для отладки). Нумерация индексов массивов начинается с 0. В документе представленны функции для работы с массивами, однако это далеко не полный их перечень.
Индекс можно задавать самому, в таком случае автоматическая индесация начнется с указанного вами индекса. Чтобы добавить элемент в конец массива используется конструкция .
Приведение строки к массиву:
array_fill
Чтобы заполнить массив одинаковыми значениями используется функция
range
Для заполнения массива числами по порядку можно использовать функцию . Обратите внимание на 3 параметр функции - она отвечает за шаг заполнения.
Ассоциативные массивы
Ассоциативные массивы в качестве ключа принимают строку
Их очеь удобно использовать для создания многомерных массивов
При интерполяции строк с элементами массивов можно опускать кавычки для обращения по ключу. Однако рекомендуется оборачивать элемент массива в - это сократит шансы получения ошибки
list
Функция используется для получения значений массива в виде переменных. Функция работает только с массивами, индексы которых числа, начинающиеся с 0!
Обход массива
Для охода массивов используются циклы (предыдущий раздел). Здесь так же будет рассмотрена работа цикла
Цикл подразумевается для обхода ассоциативных ассивов (никто не мешает использовать его для обычного массива). Конструкция цикла выглядит так: (массив as ключ => значение)
Обход многомерных массивов:
array_slice и array_splice
Функции и используются для изменения части массива.
Объединение массивов
Для объекдинения можно использовать оператор
Однако если в массивах будут одинаковые ключи, то они будут проигнорированны и взят первый попавшийся
Во избежание подобных ситуаций, для объекдинения массивов обычно используется функция
Сравнение массивов
Для сравнения массивов можно так же использовать оператор сравнения и оператор эквивалентности
При обоих вариантах сравнения массивов не учитываются типы данных ключей
array_diff
Функция сравнивает переданные массивы и возвращает элементы, которые есть в первом переданном массиве, но нет в остальных. Функция игнорирует ключи и опирается только на значения элементов массива.
array_intersect
, напротив, ищет элементы, которые присутствуют в каждом переданном массиве
isset
С помощью можно проверить наличие элемента в массиве
is_array
С помощью этой функции можно проверять, является ли переменная массивом
in_array
Данная функция проверяет наличие элемента в массиве. По умолчанию использует оператор сравнения, но можно передать третьим параметром тогда функция будет использовать строгое сравнение
array_key_exists
проверяет наличе переданного ключа в массиве
array_search
Функция ищет элемент в массиве по значение и передает его ключ
Индексы строки
В PHP строки тоже являются последовательностью, соответсвенно к каждому символу строки можно обратиться по индексу
count
функция, которая возвращает количество элементов массива
Функция может подсчитывать количетсво элементов рекурсиво, если,например, используется многомерный массив. Для этого нужно передать соответствующий флаг. Однако обратите внимание на пример ниже - будут подсчитанны именно ВСЕ элементы, то есть два массива и их элементы.
array_count_values
- функция, которая выбирает все уникальные значения из массива. Обратите внимание, что она возвращает массив, у которого ключи - это уникальные значения, а значения массива - количество этих вхождений в массив
array_sum
Функция позволяет сложить все значения в массиве. Соответственно ожидается, что значениями будут цифры.
rand & array_rand
- функция которая возвращает случайное число в указанном дианазоне.
- именно эту функцию рекомендуется использовать, если нужен случайный элемент массива (так как работает только с индексированными массивами). Возвращает случайный ключ указанного массива.
shuffle
Функция перемешивает элементы массива в случайном порядке
sort & rsort
Функция сортирует указанный массив по возрастанию. - по убыванию. Обратите внимание, что функция не возвращает новый массив - она сортирует переданный.
asort, arsort, ksort, krsort
и - функции которые сортирую ассоцитивные массивы по значениям. и - сортируют ассоциативные массивы по ключам.
natsort
- функция, так называемой "натуральной" сортировки. Как она работает хорошо показывает пример ниже.
unset
Функция "уничтожает" переданное ей значение. Это может быть и элемент массива и массив и любое другое значение
array_pad
Функция добавляет размерность массива - то есть увеличивает его длинну, заполняя новые элементы указанным значением
array_push
Добавляет указанное значение в конец массива
array_pop
Удаляет последний элемент в массиве
array_unshift
Добавляет указанный элемент в начало массива
array_shift
Удаляет первый элемент массива и возвращает его значение
array_change_key_case
Функция изменяет регистр ключей массива (по умолчанию в нижний). Возвращает новый массив.
array_values
- возвращает массив значений (ключи заменяются индексами)
array_flip
Функция меняет местами ключи и значения
array_keys
Возвращает массив ключей. В качестве необзятельного аргумента принимает значение, ключи которого неободимо вернуть
12. Функции и области видимости
Введение
Функция представляет собой именованный набор инструкций. В PHP есть множество встроенных функций и методов, но можно создавать и свои
Функцию можно вызывать ДО ее объявления
return
Обратите внимание, что используется return type declaration - то есть мы после указываем какой тип данных возвращает функция. В примере выше указан - означает что функция не возвращает ничего. В примере ниже - указывается возвращаемое значение. Эта конструкция будет рассмотрена далее. Термин вернуть - означает, что функция "отдаст" какое то значение наружу.
Если же функция ничего не возвращает () тогда по умолчанию она вернет
Параметры и аргументы
В можно указывать параметры функции. Значения, которые передаются функции снаружи называются аргументами.
В PHP 8.1 добавили возможность оставлять оператор запятая после последнего параметра функции:
Параметры по умолчанию
В параметр можно передавать значение по умолчанию (используется если аргумент не был передан). Параметры со значением по умолчанию должны объявляться только в конце списка параметров!
Начиная с PHP 8 в качестве параметров со значением по умолчанию можно передавать объекты и массивы
В примере ниже используется
- об этой конструкции будет рассказано в дальнейших разделах. Здесь можно только уточнить, что он гарантирует реализацию методаinterfaceв классахsize
Неопределенное число параметров
Бывают случаи, когда неисзвестно заранее количество передаваемых аргументов в функцию. Например конструкция . Но мы так же можем обозначить, что в нашй функции будет любое количество аргументов. Обратите внимание, что такая конструкция воспринимается как массив параметров.
Можно так же комбинировать определенные аргументы с неопределенными. В этом случае, после определенных аргументов будет выделен массив их неопределенных.
С помощью данной констркуции можно так же передавать массив в качестве аргумента и работать с отдельными параметрами
Именованные аргументы
Когда функция имеет множество параметров очень легко запутаться, какой аргумент к какому параметру относится. Для решения этой проблемы существуют именованные аргументы
Типы аргументов и возвращаемые значения
Хорошим тоном считаеся указывать тип параметров и тип возвращаемого значения функции.
Если аргумент может быть не передан или передано значение , то можно обозначить это с помощью двух типов конструкций
Если функция ничего не возвращет, то указывается тип (на самом деле функция все равно вернет ). Так же есть тип , которые обазначет, что функция никогда не вернет значения - то есть не завершится
Параметр-ссылка
Так же в функцию можно передать аргумент по ссылке - значит что внутри функция может изменять аргумент переданный извне. В данном случае обязательно должна быть передана переменная.
Глобальные переменные
Функциям не доступны переменные извне (то есть за пределами ). Для решения этой проблемы есть супер глобальный массив а так же ключевое слово . Такой подход рекомендуется использовать крайне редко и ни в коем случае не злоупотреблять им, так как это делает код уязвимым для ошибок и менее читаемым и поддерживаемым. Обратите внимание на закомментированный код - по сути означает передачу по ссылке значение из
static
Статичные переменные, объявленные внутри функции, запоминают свое предыдущее значение (значение, которое было присвоено предыдущим вызовом функции). Если в примере ниже убрать , то при каждом вызове функция будет инициализировать заново и присваивать ей .
13. Функции. Часть 2
Рекурсия
Рекурсия - понятие, когда функция вызывает сама себя. Важно чтобы у функции было условие остановки вызова, иначе рекурсия быстро заполнит всю ОЗУ.
Функция внутри функции
При объявлении функции внутри другой функции, дочерняя (внутренняя) будет не доступна, пока не вызвана родительская. Так же стоит учесть, что родительская может быть вызвана только один раз. В противном случае интепретатор решит, что вы хотите переопределить дочернюю функцию.
Функция-переменная
Имя функции можно назначить переменной, а после вызывать эту переменную как функцию с использованием . Однако в таких случая высока вероятность ошибки, что обычную переменную попытаются вызвать как функцию. Чтобы избежать таких ошибок следует проверить переменную - является она типом или нет.
Функции-аргументы и анонимные функции
Довольно часто функция может быть использована в качестве передаваемого параметра другой функции. Например в функции первым параметром передается функция, код которой применяется ко всем элементам переданного вторым параметром массива.
array_filter
Функция возвращает отфильтрованный массив, с помощью передаваемой аргументом функции
array_reduce
Так, жу как и предыдущие, функция выполняет какое либо действие с элементами переданного массива. Однако аргументом функция принимает другую функцию, которая, в свою очередь, имеет в качестве аргументов текущий элемент массива и следующий. Обратите внимание, что третьим параметром функция принимает начальное состояние массива.
Анонимные функции
Как следует из названия - функции без имени.
Их можно передавать в качестве аргументов, как в примерах выше, но не писать отдельную функцию-аргумент
Замыкания
Активация замыкания происходит с помощью конструкции - это механизм, который позволяет запомнить состояние окружения в момент создания.
Стрелочные функции
По сути - анонимные функции, но записанные более компактным способом.
14. Методы класса
Функция, объявленная в классе, называется методом. Вызов метода у объекта класса:
Обращение к методам класса
Ниже представлен класс Pointer, у которого есть два приватных свойства. Хорошим тоном считается обращаться к приватным своствам через специальные метода - геттеры и сеттеры, для чтения и назначения значений свойствам. Сокрытие свойств называется инкапсуляцией (о ней будет рассказано в одном из следующих разделов).
method_exists
Для безопасного обращения к методам класса существует функция . Если обратить к несуществующему методу класса - PHP выдаст ошибку.
Посмотреть доступные методы класса можно с помощью .
property_exists
Для проверки обращения к свойствам метода используется . Если обратиться к несуществующему свойству - интерпретатор PHP выдаст предупреждение. Обратите внимание - начиная с PHP 8.2 нельзя динамически создавать новые свойства для класса.
Так же как и с методами, существует возможность посмотреть доступные свойства класса с помощью .
Однако "снаружи" класса приватные свойства не будут видны.
__construct
В PHP, при использовании классов, существуют магические методы. Их магия заключается в том, что они вызываются в определенное время при работе с классом. Первым рассмотрим метод - он вызывается при создании объекта класса. Как правило, конструктор неявно вызывается при создании объекта, однако есть возможность вызвать его явно - обратите внимание на метод в примере ниже. Так же при вызове конструктора есть возможность задать значения приватным свойствам - передав эти значения в параметры метода . Таким образом можно избавиться от сеттеров (если нет нужды изменять значения на более поздних этапах использования объекта).
В конструкторе есть возможность задавать модификаторы видимости для аргументов - таким образов свойства класса создадуться без их явного объявления
__destruct
Метод вызывается, в основном, сборщиком мусора, во время уничтожения объекта класса.
Методы аксессоры
Методы аксессоры подразумевают применение геттеров и сеттеров, о которых упоминалось выше, но используя магические методы и .
В примере ниже мы получем результат расчетов метода , однако сам метод внутри класса не объявляли. Расчет происходит благодаря геттеру и переданому ключу внутрь геттера, который и определяет дистанцию.
В данном примере отлично заменяет объявление каждого свойства отдельно и отдельно каждого геттера для свойства.
Далее идет пример кода, где показано, что начиная с PHP 8.2 просто объявлять новые свойства у объекта класса не выйдет - вы получите предупреждение.
Теперь же представлена работа сеттера. Свойства записываются в отдельную переменную и после этого к ним можно получить доступ.
Статичные методы
Статичные методы можно вызывать без объявления объекта класса.
Внутри класса к статичным свойствам и методам можно обращаться с помощью ключевого слова вместо . Это связано с тем, что указывает именно на экземпляр (объект) класса, а - непосредственно на сам класс.
Как и вне класса, статичные свойства и методы запоминают предыдущее состояние:
__call
В классах можно использовать динамические методы с помощью магического метода - нечто похожее было в примере с и
__toString
Данный метод используется для интерполяции объекта класса в строку - иными словами, задает поведение, когда объект класса пытаются вывести в виде строки.
callable
Тип в основном подразумевает функции, которые передаются в качестве аргумента другой функции. Однако у нас есть возможность передавать как обычные, как и статические методы в виде функций. В первом примере представлена обычная стрелочная функция, которая возвращает объекты класса - для того чтобы вы вспомнили что такое тип , а так же функция - для той же цели.
Далее представлены примеры, где в качестве аргумента передается метод и статичный метод класса
Оператор ?->
Оператор используется для безопасного вызова метода или обращения к свойству. При обращении к несуществующему свойству\методу в PHP мы получаем ошибку, однако данный оператор позволяет избежать ошибки и продолжить выполнение кода. Был введен в PHP 8.0
15. Генераторы
Для простоты понимания - генератор это функция, которая вместо использует ключевое слово . Однако это не единственное различие.
Генератора, как правило, намного более происзводительные, особенно в работе с простыми данными.
Ниже представлен простой пример генератора.
Суть примера в том, что генератор не вычисляет весь массив и не хранит его в памяти - он запоминает последнюю итерацию и при надобности возвращается к ней.
С помощью генераторов так же можно описывать свои функции обратного вызова - на манер или
Для того, чтобы вызвать генератор внутри генератора используется ключевое слово - этот процесс называется делегированием.
Ниже представлен наглядный пример, насколько меньше памяти (в байтах) использует генератор при одинаковой функциональности
16. Строковые функции
Ниже представлен обширный список (но далеко не весь!) строковых функцив PHP
17. Язык разметки HTML
HTML - HyperText Markup Language - язык разметки страниц. Предназначен для отображения страниц в браузере. Строится с помощью различных тегов. Обязательным считается тег , который указывает браузеру, что он будет работать с html-документом. HTML является декларативным языков, то есть браузер решает как будет обрабатывать написанный код, в то время как в других языках мы можем явно давать инструкции для железа - что именно ему следует делать (описываем алгоритм работы).
Для более подробной информации о HTML и CSS (Каскадные таблицы стилей) следует обратиться к другому руководству (книге), здесь же в файле представлен минимальный набор тегов для общего представления.
18. Работа с данными формы
$_GET
Суперглобальный массив (доступен во всем проекте PHP) $_GET содержит данные GET-запроса. Вручную запрос можно сформировать в адресной строке сайта: добавить в эту строку и далее необходимые данные в формате ключ=значение. Можно добавить несколько пар ключ=значение разделяя их символом . Для добавление массива в запрос можно воспользоваться символами , обратите внимание, что по умолчанию массив пронумерован, но можно добавлять и свои индексы.
urlencode
Для корректного добавления параметров URL-адрес использую функцию
parse_url
Функция позволяет представить URL в виде ассоциативного массива, что очень удобно при работе с отдельными частями URL. Так же можно передать отдельно каждое значение, указав второй аргумент.
HTML-форма
Формы необходимы для передачи данных на сервер и последующей обработки этих данных. Каждая форма
обязательно имеет атрибуты и . Метод принимает значения или (по умолчанию, если не указан атрибут , он примет значение ). Атрибут принимает URL - куда отправлять данные.
В примере ниже атрибут у отвечает за ключ в массиве (обратите внимание, что у формы явно указан способ передачи запроса - ).
Выше мы передаем данные формы в файл , который лежит рядом в проекте, однако можно передавать данные в тот же файл, где расположена форма.
Преимущество данного подхода в том, что мы сообщаем пользвоателю об возможных ошибках уже в файле с формой, то есть ему, в случае ошибки, не нужно возвращаться на предыдущую страницу. Так же обратите внимание как задается для поля ввода текста - там присутствует проверка на то, что данный элемент в массиве присутствует.
Ввод текста
Основные теги для ввода текста это и . Основные возможности тегов представленны в примере ниже. Для передачи данных у тега обязательно должен присутствовать атрибут , который представляет собой ключ суперглобального массива, атрибут - это значение ключа.
Флаг
предназначен для передачи на сервер выбранных вариантов. На сервер по умолчанию передается значение , его можно изменить с помощью атрибута .
Выпадающий список
Тег немного отличается. указывается у самого тега , а вот значения указываются в .
Переключатель
Их еще называют радио-кнопками. Работают по аналогии с , но можно выбрать только одно значение. Группируются по атрибуту .
Переадресация
Средствами PHP передаресация достигается с помощью метода . Он управляет HTTP-заголовками, которые сревер принимает от клиента. Это работает следующим образом: клиент отправляет серверу HTTP-документ, который состоит из заголовков и тела запроса (тело может быть пустым). В зависимости от полученной информации, сервер может реагировать по разному. Например смотреть на поле, переданное из формы и, если это поле есть, перенаправлять клиента на другой сайт\страницу. Ниже в примере есть ссылка, которая показывает возможность редиректа (переадресации), а так же форма, которая обрабатывается скриптом PHP и редиректит пользователя на сторонний сайт.
19. Загрузка файлов на сервер
Загрузка файлов отличается от передачи данных в полях. Во первых форме необходимо указать атрибут .
Передача осуществляется с помощью с типом . На стороне сервера для работы с файлами используется суперглобальный массив . В примере ниже так же показан максимальный размер загружаемых файлов - 2 мегабайта. Настраивается в ini файле.
Более полная версия файла upload.php
Фотоальбом
Ниже представлена первая версия фотоальбома - попробуйте разобраться в коде и улучшить его.
Сложные имена полей
Вам могут быть переданы сложные имена полей, например в таком виде, как в примере ниже. Запустите код и посмотрите, что в итоге пришло в .
20. Суперглобальные массивы
- данные переданные get-запросом$_GET- данные переданные post-запросом$_POST- переданные файлы$_FILES- куки, хранящиеся на стороне клиента$_COOKIE- сессия хранится на стороне сервера, клиент присылает идентификатор сессии$_SESSION- все параметры с$_REQUEST,$_GETи$_POST$_COOKIE- переменные из env-файла$_ENV- информация о сервере, на котором работает скрипт$_SERVER- все переменные из глобальной области видимости, включая$GLOBALS,$_GET,$_POSTи$_COOKIE$_FILES
Cookie
cookie - небольшие файлы с информацией, которые храняться на стороне клиента. Для того, что начать использовать куки в PHP используется функция . У нее есть несколько аргументов, мы рассмотрим 4 в примере ниже. Функцию необходимо вызвать ДО любого вывода клиенту.
Значение может увеличиваться на два, вместо одного - это может быть связано с, например, запросом к favicon.
Сессии
Сессии похожи на куки, однако они хранятся на стороне сервера. Доступ осуществляется с помощью суперглобального массива . Сессию запускает функция , так же как и с куками - ее необходимо вызвать до любого вывода в браузер. Так же, для доступа к массиву сессии, необходимо вызывать ее в каждом файле, где планируется использовать данные сессии. Для обнуления сесси можно использовать конструкцию , для удаления сессии функцию .
Переменные окружения
Как правило задаются в файле . Используются для хранения различныз данных в формате ключ=значение. Как правило хранят ссылки, пароли к АПИ, базам данных.
$_SERVER
Данный суперглобальный массив хранит информацию о сервере, с которого запускается скрипт
21. Фильтрация и проверка данных
Так как преимущественно PHP является ЯП для веб-разработки в него встроены некоторые функции фильтрации и очистки. Это необходимо чтобы отлавливать потенциально опасные данные от злоумышленников, а так же для предотвращения ошибок ввода от пользователя. Простейшим примером можно считать функцию .
Процесс, в примере выше называется очисткой (sanitize).
filter_var
Функция используется для встроенной и кастомной фильтрации получаемых данных. Содержит определенное количество констант (второй параметр), которые отвечают за фильтрацию передаваемых данных.
Как видно из примера выше, email отлично валидируется. Можно так же провалидировать boolean-значение, оно интересно тем, что распознает не только и . Подробнее обо всех встроенных фильтрах можно узнать в документации.
Функция так же принимает третий параметр - обратите внимание на его написание, на примере фильтрации целых чисел
filter_var_array
По аналогии с предыдущей функцией, но проверяет сразу несколько значений. Обратите внимание, что фильтры так же передаются массивом и ключи обоих массивов должны быть идентичными.
Фильтры очистки (SANITIZE)
По аналогии с так же есть константы для очистки данных - . Обратите внимание на последний пример - в нем наглядно показано, почему необходимо быть осторожным в использовании фильтров и очистки.
Так же существует константа - она говорит функции, что мы будем использовать собственную функцию для очистки\фильтра. В примере передаются готовые функции и , однако никто не мешает вам описывать собственные кастомные функции и передвать их так же по имени или использовать анонимные функции или стрелочные.
filter_input
Функция служит для проверки значений в суперглобальных массивах. Первым аргументов принимает массив, в котором необходимо проводить валидацию, вторым - ключ суперглобального массива.
По аналогии есть так же функция .
22. Математические функции
В PHP встроено множество математических функций и констант.
abs
Модуль числа
Функции округления
- округляет по математическим правилам. Вторым аргументом можно указать до какого знака производить округление.
- всегда округляет в БОЛЬШУЮ сторону
- всегда округляет в меньшую сторону
Псевдослучайные числа
Довольно часто требуется получить рандомное число. Для этого есть несколько функций:
Функции конвертирования
Обычно не особо пользуются популярностью, но иногда может понадобиться переводить биты в различные форматы:
min и max
Функции выбирают минимальное или максимальное значение из переданных аргументов. Обратите внимание, что если аргумент один - он должен быть массивом.
is_nan
Есть так же ряд функций для проверки является ли переданное выражение не числом или бесконечностью.
Степени и геометрические
Различные функции для алгебраических и геометрических вычислений. Помните, что это далеко не все доступные функции! Их гораздо больше, за подробностями или поиском определенных специфичных функций стоит обращаться к документации.
23. Работа с файлами
Работа с файлами является важной частью практически любого програмного продукта. В PHP существует множество функций для работы с файлами и каталогами.
Основная работа
В основном приходится открывать, читать, редактировать и закрывать файлы. В PHP для этого есть ряд функций: - открывает файл, - закрывает (рекомендуется всегда вручную закрывать файл во избежание утечки памяти), - чиатет файл ДО указанного количства байт, - записывает в файл переданный текст.
Обратите внимание на режим открытия файла, указанный вторым аргументом. За таблицей и пояснием к каждому режиму стоит обратиться к документации
fgets и fputs
Так же существует возможность читать файл построчно
Однако пример выше вернет нам только первую строку. Чтобы прочесть весь файл можно использовать функцию которая отвечает за конец файла
fseek
Вам может потребоваться прочесть файл не сначала, а с указанной позиции. Для этого используется функция . Попробуйте разобрать, что делает код, приведенный выше
CSV
Таблицы Excel достаточно популярны и в PHP есть специальные функции для работы с ними
Работа с путями
Есть несколько достаточно удобных функций, которые позволяют быстро работать с путями и файлами. Например чтобы получить имя файла из строки его местоположения:
Функция , наоборот, отдает нам путь каталогов до файла (можно указать уровень вложенности вторым аргументом)
Для получения абсолютного пути до файла используется функция :
Копирование, перемещение, удаление
Функция копирует указанный файла в указанное место с новым именем. Обратите внимание, что все каталоги во втором аргументе должны быть доступны. Функция перемещает или переименовывает файл. Функция удаляет файл.
Чтение и запись целого файла
До этого момента мы видели отдельную работу функций для открытия-чтения-записи файла. Для более удобной работы существует ряд функций, например - функция открывает указанный файл и возвращает его строки в виде массива, где каждый элемент - это и есть отдельная строка файла. Посмотрите пример ниже - такой код гораздо более удобочитаем.
Функция считывает файл и возвращает содержимое в виде одной строки:
Функция по умолчанию перезаписывает файла указанным контентом. Для того, чтобы дозаписать данные в файл используется флаг .
INI
INI-файл - файл, разделенный секциями, в каждой секции, как правило, определены пары ключ=значение. PHP позволяет получить ассоциативный массив INI-файла:
Блокировка файла
Бывают ситуации, когда одновременно несколько пользователей хотят внести изменения в один и тот же файл. Для решения этой ситуации существует блокировка файла - функция . Блокировка, по сути, говорит пользователю, что он должен дождаться своей очереди для записи в файл данных.
Режимы блокировки (второй аргумент ):
- разделяемая блокировкаLOCK_SH- исключительная блокировкаLOCK_EX- снять блокировкуLOCK_UN- прибавляемая константа (LOCK_NB), для избежания подвисания программы в ожидании своей очереди на доступ к файлуLOCK_EX + LOCK_NB
24. Работа с каталогами
Работа с каталогами во многом схожа с работой с файлами, так как каталог - это файл со ссылкой на другие файлы. Именно это свойство позволяет строить древовидные структуры каталогов.
getcwd
Для просмотра текущей рабочей директории используется функция
chdir
Для смены директории используют функцию , куда в качестве аргумента передают строку с указанием пути до нужного каталога.
Если в какой либо части пути указан несуществующий каталог - будет выдано предупреждение.
mkdir
Для создания новой директории используется , где в качестве аргументов используются название директории и права доступа (0777 по умолчанию). В качестве первого аргумента можно передавать полный или частичный путь, но необходимо, чтобы каждый каталог в этом пути существовал. Однако принимает еще один аргумент, который позволяет создавать нужные каталоги, если они отсутствуют.
rmdir
Функция удаляет указанный каталог
opendir
Как и с файлами существуюь функции открытия, закрытия дескриптора каталога, а так же чтения содержимого - это функции , ,
25. Права доступа и атрибуты файлов
В данной ветке больше рассматривается устройство ОС UNIX, однако представлены некоторые функции PHP, которые на практике используются не так часто, но могут помочь вам в определенных ситуациях.
Каждый процесс в ОС должен быть обозначен пользователем, который этот процесс инициировал. Для этого существует уникальный идентификатор пользователя в системе - UID - User ID.
Каждый пользователь должен принадлежать группе - Group ID. Как правило GID соответсвует UID.
Так же существует владелец системы - пользователь, у него всегда UID и GID = 0.
В UNIX системах мы можем сметреть и изменять права пользователя, владельца и группу - все это применимо и к файлам и к каталогам.
Для вывода этой информации воспользуемся следующей функцией:
Права доступа
- обозначение прав, разделенных в группы по три: , , . Каждая группа имеет три вариации права доступа:
- разрешено чтениеr- разрешена записьw- разрешено исполнение В примере выше, получается следующая ситуция: текущему пользователю разрешено чтение-запись файла, группе и остальным разрешено чтение файла.x
Права доступа так же имеют числовое представление - как правило администраторами используется именно оно
= (41 + 20 + 1*0) = 4r--= (41 + 20 + 1*1) = 5r-x= (41 + 21 + 1*1) = 7rwx
Обратите внимание, что для числового представления прав используется восмиричная система счисление, в связи с этим в PHP обязательно, при указании прав, необходимо
предварять их 0, то есть не , а .
Функции PHP
PHP предоставляет функции для работы с файлами, каталогами и их правами, группами, владельцами. В листинге этой ветки представлены некоторые функции, запустите их и посмотрите вывод.
Вывод
PHP предоставляет некоторую возможность влиять на файлы и систему, в которой он запущен. Однако чаще этим занимаются администраторы сервера. За более подробной информацией об ОС и их управлении следует обратиться к соответствующим руководствам.
26. Запуск внешних программ
Так как внешние программы приходится запускать крайне редко, в ветке представлен только один пример. Код ниже пытается отправить email на указанный адрес используя внешнюю программу отправки самой ОС. Однако имейте ввиду, что при запуске через Docker мы можете столкнуться с ошибкой - по умолчанию в контейнере отсутсвует программа отправки писем.
27. Работа с датой и временем
PHP имеет множество встроенных функций и классов для работы с датой и временем. Разберем сначала функции, затем классы. Именно классы рекомендуется использовать в современном коде PHP.
time
Функция представляет собой UNIX метку - количество секунд прошедших с 1 января 1970 года. - предоставляет более точные вычисления. Если передать параметр - функция вернет массив, состоящий из секунд и дробной части.
очень удобно использовать для замера времени работы определенной части кода:
date
Функция принимает два параметра - формат вывода данных и метку времени. Доступные форматы можно посмотреть в документации
mktime
позволяет наоборот - перевести дату в timestamp. Однако из за обилия аргументов ее предпочитают не использовать.
strtotime
Делает то же, что и , однако предлагает более удобный синтаксис
getdate
Возвращает массив со множеством значений даты
Часовые пояса
По умолчанию PHP использует часовой пояс сервера, на котором он запущен. Есть возможности вручную изменить часовой пояс, однако обычно эти функции не удобно использовать. Поэтому можно хранить часовой пояс пользователя например в куках или в БД, получив его (часовой пояс) от клиента при авторизации (например).
Ниже приведены примеры для работы с часовыми поясами:
Классы для работы с датой и временем
Как говорилось выше - классы использовать предпочтительнее в современном коде. Они предоставляют все те же инструменты, что и вышеуказанные функции.
28. Основы регулярных выражений
Регулярные выражения представляют собой сложные конструкции символов. Для проверки, а так же просмотра различных регулярок рекомендуется пользоваться сайтом
В PHP чаще всего для работы с регулярными выражениями используются две функции: и .
Первая создает массив совпадений, вторая меняет найденную часть строки.
29. Различные функции
В коде представлены различные функции, которые есть в PHP.
- вывод информации о текущей используемой версии PHP
Прерывание кода
или служат для прерывания выполнения кода
eval
Используется крайне редко и служит для выполнения кода, переданного как строка
password_hash и password_verify
В PHP есть довольно удобные функции аутентификации. Одна из функций генерирует хеш пароля, вторая проверяет его. Их рекомендуется использовать, но только если у вас актуальная версия PHP.
highlight_string
Служит для подсветки синтаксиса PHP
30. Наследование
Наследование является одним из столповы ООП. Его можно описать как расширение функциональности родительского класса. Дочерний класс наследуется от родительского (базового) с помощью ключевого слова .
Наследование подразумевает, что ВСЕ не методы и свойства базового класса доступны в дочернем.
Переопределение
Обратите внимание на метод - мы его переопределили. Но так же в нем вызвали тот же метод, но базового класса, с помощью ключевого слова и оператора . Для того, чтобы запретить переопределение метода перед необходимо проставить модификатор . При попытке переопределить -метод компилятор PHP выдаст ошибку.
Запрет наследованияы
Так же доступна возможность запретить наследование, с помощью все того же модификатора .
__CLASS__ и __METHOD__
Константы, соответственно, возвращают имя класса и метода.
Позднее статическое связывание
В примере ниже существует проблема - ключевое слово , при вызове вернет название базового класса, а не того, в котором метод был вызван, даже несмотря на переопределение метода внутри .
Этот эффект называет поздним статическим связыванием. Исправляется он довольно просто - необходимо заменить на . Так же стоит упомянуть почему так происходит - во время компиляции ссылается на класс, где метод был определен, в то время как ссылается на класс из которого метод был вызван.
Анонимные классы
Так же как и с анонимными функциями, в PHP есть возможность создавать анонимные классы.
Полиморфизм
Полиморфизм - это способность классов предоставлять единый программный интерфейс при различной реализации.
Для примера - есть сайт, у которого есть страницы "Главная", "Личный кабинет", "Товары", "Контакты". Все эти страницы должны содержать и - значит эти две переменные логичнее задать в базовом классе и дальше использовать в дочерних классах (тут стоит посчитать сколько кода мы сэкономим - задать эти переменные в базовом классе это примерно 2 строки кода. Задать в каждом - 2 * 4 = 8). Так же все классы должны реализовывать метод, с помощью которого контент выводиться на страницу и опять же - это легче всего сделать в базовом классе , затем, если необходимо переопределить методы в нужным классах.
Далее задача усложняется - по сколько все страницы кроме "Личного кабинета" содержат +- статичный контент, то логичнее было бы использовать - NoSQL БД для хранения кеша. Создаем класс , который наследуется от . Обратите внимание, что были переопределены методы получения и - теперь они гарантировано будут возвращать значение из кеша, если оно там есть, а так же дочерним классам нельзя будет их переопределять.
Это и есть полиморфизм - единый интерфейс, который определяется в и переопределяется в , но используется по сути одинаково
для каждого класса страницы.
Виртуальные методы
Виртуальным называют методы, которые могут переопределяться в производном классе. Например методы и - виртуальные. И, как увидим далее, метод - в базовом классе он ничего не делает, просто прерывает выполнение кода, тогда как в каждом производном классе он должен будет формировать уникальный id страницы для хранение в NoSQL-хранилище.
Виртуальные методы базового класса, которые необходимо переопределять (так как вызывать их "ванильную" версию бессмысленно) так же называют абстрактными - это методы, требующие дальнейшего уточнения, то есть реализации в классах-потомках. Абстрактный метод в базовом классе говорит нам, что в в производном классе необходимо описать его реализацию, иначе компилятор не сможет интерпретировать такой код.
Обратите внимание, что часть кода была закомментирована для нормальной работы (так как мы еще не подключали Redis и PDO). Рассмотретите код в файлах , , и .
Если внимательно изучить все представленные файлы, то можно сделать вывод - добавлять новые страницы теперь стало неимоверно просто. Достаточно описать класс, который наследуется от или - в этом и есть сида наследования.
Абстрактные классы и методы
Выше уже упоминалась абстракция. Абстрактные классы - это те классы, на основе которых нельзя (или не имеет смысла) создать объект. В нашем примере абстрактными являются классы Page и Cached, так как создание на основе этих классов объектов было бы бессмысленно. Чтобы обозначить класс (и метод) как абстрактный используется ключевое слово . Любой класс, который имеет абстрактный метод так же является абстрактным.
Обратите внимание как теперь описан метод - теперь в базовом классе нет необходимости описывать тело метода, достаточно указать модификаторы, имя, аргументы и тип возвращаемого значения. Теперь любой класс, который наследуется от потребует реализацию метода . В противном случае интерпретатор выдаст ошибку.
Совместимость родственных типов
Это правило говорит о том, что мы можем использовать как , но не наоборот. У вас не получится использовать как .
Уточнение типа в функциях
В качестве аргумента функции мы можем передавать объекты классов, указав имя класса как тип. Обратите внимание на пример ниже - мы указали что ждем объект , а передаем - такой вариант допустим. Однако если бы мы использовали в качестве аргумента , то передать ,например, уже не смогли бы
instanceof
Оператор проверки типа - позволяет добавлять проверку на совместимость. Это может быть необходимо, так как транслятор PHP выполняет эту проверку во время выполнения, а не во время трансляции кода. Обратите внимание - мы можем передать имя класса переменной и поставить справа от оператора - данный способ будет работать корректно.
31. Интерфейсы
Так как в PHP отсутствует механизм множественного наследования, используются другие технологии. Одна из них - интерфейсы. Интерфейс представляет собой описание класса и его методов. Все методы интерфейса обязательны для определения в имплементируемом классе, в противном случае интерпретатор выдаст ошибку.
Для примера использования мы можем представить структуру сайта, где есть два типа пользователей - и . Фронт - это пользователь сайта, бэкюзер включает в себя модератора, редактора и администратора. Так как у каждого пользователя есть имя, фамилия, емейл и пароль - логично наследовать фронт и бек пользователей от общего класса . Далее пользователям, которые непосредственно ходят на сайт (фронт и моератор) необходим аватар. Мы могли бы добавить методы загрузки и получения аватара базовому классу , однако это не совсем корректно, так как в таком случае все бекенд пользователи получат методы, которые не будут использоваться в классах и (а если сделать класс абстрактным, то станет еще хуже - эти два класса должны будут реализовать неиспользуемые методы). Тут на помощь и приходит интерфейс - обратите внимание на реализацию, в примерах ниже используется ключевое слово для подключения интерфейса к классу.
- user.php - базовый класс
- avatar.php - интерфейс
- frontUser.php
- backendUser.php
- moderator.php
Теперь только объекты классов и получили возможность загружать и отдавать свой аватар, при этом не были затронуты базовые классы.
Наследование интерфейсов
Так как на сайте могут быть статьи и раздел новостей, в которых используются изображения, то логичнее было бы создать некий базовый интерфейс , который описывает методы получения и загрузки изображения. А интерфейсы и (изображения для новостей и статей) уже будут наследоваться от .
Теперь можно реализовать классы новостей и статей, которые будут наследовать от базового класса . Обратите внимание на наследуемые свойства класса, а так на добавленные в класс - у новостей не может быть авторов, в отличие от статей. Просто еще один пример силы наследования и полиморфизма.
Реализация нескольких интерфейсов
Несколько интерфейсов реализуются так же с помощью и просто перечисляются через запятую. Обратите внимание на измененный класс .
- Файлы новых интерфейсов
- Файл article.php
32. Трейты
Трейты похожи на интерфейсы, однако позволяют реализовывать методы, а не только их описывать. Используются трейты с помощью ключевого слова .
Трейты и наследование
Интересно, что трейты переопределяют методы базового класса, НО методы класса куда включен трейт ПЕРЕЗАПИСЫВАЮТ методы трейта. В примере ниже, класс наследуется от класса , а так же использует трейт. Обратите внимание, что при вызове метода у объекта класса , вызовется именно метод, который определен в трейте, а не наследуемый от класса .
Конфликты
Случается такое, что разные трейты использует один класс, а в этих трейтах реализуются методы с одинаковым названием. В таком случае, для разрешения конфликтов, используется ключевое слово , которое выполняет следующие действия: конструкция слева от должна быть использована, в то время как конструкция справа проигнорирована. Так же лучше всего добавлять конструкцию , которая задает псевдоним для указанного элемента (метода в данном случае).
Вложенные трейты
Трейты можно вкладывать друг в друга (реализуя некую наследуемость) так с помощью ключевого слова .
33. Перечисления
Доступны, начиная с версии PHP 8.1.
Перечисления в PHP представляют собой особый тип данных, напоминающий класс. Исходя из самого названия, перечисления - это коллекция неких объектов. Объявляется с помощью ключевого слова , объекты для перечисления с помощью . Для простоты понимания - в PHP есть тип данных , который как раз очень похож на перечисление, так как принимает только два заведомо известных значения.
По умолчанию для перечисления доступен метод , который возвращает имя объекта. Обратите внимание, что метод вызывается уже у выбранного перечисляемого объекта, а не просто у объекта на основании самого перечисления. Так же есть возможность вызывать объекты перечисления с помощью .
Каждый объект перечисления может вызывать метод , который вернет ассоциативный массив всех доступных объектов перечисления. Однако это выглядит не совсем логично, так как отдельный объект возвращает остальные объекты перечисления. Но можно использовать - это делает код более читаемым.
Типизация
Типизированные перечисления - это те, у которых указан тип перечисляемых объектов. Обратите внимание, что значения объектов необходимо задавать сразу же, иначе получите ошибку. Помимо , у типизированных перечислениях появляется свойство .
Типизированные интерфейсы реализуют интерфейс и, соответственно, его методы и . Данные методы позволяют получить перечисляемый объект по его значению. Отличие в том, что метод вызовет ошибку, если объекта с таким значением нет, а вернет в этом случае .
Сравнение
Два значения, которые принимают один и тот же считаются равными.
Перечисления как классы
В перечислениях действуют несколько ограничений при работе:
- Запрещено использовать магические методы кроме
,__call,__callStatic__invoke - Не поддерживается наследование
- Запрещено заводить свойства объекта и статические свойства перечисления
- Не допускается клонирование объектов перечисления
Допускается реализация методов, интерфейсов, статичных методов, трейтов.
Константы
Допускается использование констант, особенно популярно создавать константы-синонимы
34. Исключения
try-throw-catch
Данные конструкции предназначены для генерирования () и перехвата () исключений. Исключения - это ошибки в коде, которые прерывают выполнение программы. Так же исключения являются отдельным классом в PHP. Для того чтобы сгенерировать исключение используется ключевое слово внутри конструкции . Посмотрите на пример ниже, а затем будет объяснение, что именно происходит в коде.
В примере выше есть строка, которая генерирует исключение, прерывая выполнение программы - это стандартное поведение интерпретатора PHP на любую ошибку. Чтобы избежать этого и позволить программе выполняться существует конструкция . В блоке пишется логика (можно сказать по другому - код в котором возможна ошибка), код блока выполняется в том случае, если в блоке произошла ошибка. В вы можете проанализировать ошибку, записать логи, ответить пользователю, в общем любой код, которые посчитаете нужным. При этом выполнение программы продолжится (если только вы сами не прервете ее). Блок принимает аргумент с типом исключения - из этого аргумента вы можете извлечь полезную информацию - текст исключения, строку, на которой произошла ошибка и т.д. Конструкция похожа на и - прерывает выполнение кода и передает в работу объект исключения.
Исключения и деструкторы
Особенностью конструкции является то, что она "подчищает" код после генерации исключения - например уничтожает все более не используемые объекты класса. Обратите внимание на код ниже - деструкторы вызваны уже после того, как выполнилась . Грамотное использование генерации исключения позволяет держать вашу программу "в чистоте".
Интерфейс Throwable
Класс реализует интерфейс . Нам нет необходимости что то менять в данном классе (у нас и не получится), однако полезно знать что именно происходит внутри. Конструктор класса принимает в качестве аргументов тест исключения, код ошибки, а так же предыдущие исключения. Так же внутри класса запрещено клонировать исключения. К тому же класс реализует несколько -методов (методы недоступны для переопределения). По названию методов понятно что именно они делают, потому детального описания не требуется.
Генерирование исключений внутри класса
Генерация исключения оказывается весьма полезна внутри логики классов. В примере ниже исключение генерируется при попытке изменить значение несуществующего свойства класса. И теперь, в любой части кода, достаточно обернуть нужный блок в чтобы увидеть исключение.
Создание собственных исключений
Создание своего исключение - это просто создание класса, который наследуется от .
При использовании и генерации исключений обратите внимание, что базовый в блоке перехватывает все типы исключений, однако вы можете указать явно какое именно исключение хотите перехватить. Так же есть возможность перечислять перехватываемые исключения: .
finally
Блок выполняется всегда - даже есть программа была прервана вбрасыванием исключение, перед выходом (из программы)
блок все равно выполнится.
35. Обработка ошибок
Ошибки, как правило, делятка на несколько типов:
- Ошибочная ситуация - семантические или синтаксические ошибки в коде
- Внутреннее сообщение об ошибке - ошибки, которые выдает PHP в ответ на различные действия (обращение к несуществующей переменной или к файлу и прочее)
- Пользовательское сообщение об ошибке - ошибки, обрабатываемые самой программой - например "Неверный пароль"
Так как первый тип ошибки большинство разработчиков отловит на этапе написания кода, мы сосредоточимся на втором и третьем типе. Как правило они работают в связке - если произошла внутренняя ошибка и программа не реагирует должным образом, то нужно уведомить об этом пользователя и разработчика. Делается это уведомление по разному. Чтобы уведомить разработчика, необходимо записать лог ошибки в журнал - для этого используются директивы , и функция . Для того, чтобы уведомить пользователя необходимо сгенерировать человекочитаемый текст, где важно сообщить о проблеме и посоветовать дальнейшие действия для пользователя.
В прошлой главе мы говорили о перехвате исключений для нормальной работоспособности кода. Однако ошибки и исключения - это разные вещи. Обратите внимание на код ниже - несмотря на конструкцию выполнение программы прервется сообщением интерпретатора .
При возникновении ошибки генерируется исключение класса , который не наследуется от . Однако, как можно догодаться, его так же можно перехватить передав соответствующий параметр.
Оператор подавления ошибок
Существует оператор подавления ошибок - . Однако его следует использовать крайне осторожно - вы можете лишить себя внятного сообщения о состоянии программы. Попробуйте убрать оператор из примера ниже и вы увидите сначала предупреждение, а затем уже вывод оператора . Это связано с тем, что есть ошибки, которые прерывают программу, а есть те, которые позволяют продолжать выполнение кода, но предупреждают вас о том, что что то не так.
Перехват ошибок
Мы можем самостоятельно перехватывать ошибки с помощью функции . Однако ее использование так же зависит от настроек PHP (файл php.ini). Функция принимает callback-функцию-обработчик ошибок в качестве аргумента. Однако кастомный обработчик перехватывает не все типы ошибок (например E_PARSE или E_ERROR), так же не перехватываются функции и .
И еще один момент - когда вызывается , то предыдущее имя пользовательской функции запоминается во внутреннем стеке PHP. Чтобы получить это имя и установить в качестве обработчика необходимо вызвать функцию . Это может быть немного сложным для понимания, однако в примере ниже все становится ясно - если вы не будете вызывать , то обработчиком останется ваша анонимная функция. Если же вызвать - то обработчиком вновь станет стандартный обработчик PHP и вы получите предупреждение.
Полезные функции
Есть ряд функций, который позволяет создавать собственные обработчики (однако в большинстве современных продуктов используется фреймворк, в котором все это уже есть). Ниже в коде представленны функции - генерирует кастомную ошибку, - записывает ошибки в журнал, - позволяет проследить цепь вызовов функций (полезно чтобы узнать где именно была вызвана ошибка).
36. Пространство имен
Общие сведения
Пространства имен решают проблему уникальности и наименования (например разработчик может написать свою функцию и PHP необходимо будет определить какую именно следует вызвать). Объявляется пространство имен с помощью ключевого слова - перед объявление пространства имен недопустимы никакие другие конструкции кода и верстка (за исключением ).
Обратите внимание, в примере выше мы обращаемся к конструкциям пространства имен через .
Так же есть возможность (однако так делать не рекомендуется!) объявлять несколько пространств имен в рамках одного файла.
Иерархия пространства имен
При объявлении пространства имен у нас появляется возможность сокращаться длинные констркуции (по аналогии с ссылками на файлы в файловой системе)
Текущее пространство имен
Как было сказано в самом начале, мы можем явно указывать из какого пространства имен хотим использовать конструкцию (например функцию).
Импортирование
Испортирование используется с помощью ключевого слова и позволяет писать более удобочитаемый код. Так же при импорте доступно создание псевдонимов.
Автозагрузка классов
Как правило каждый класс пишется в отдельном файле и для его подключения используется функция . При разрастании проекта и у вас получится целая "стопка" . К счастью PHP предоставляет механизм автозагрузка классов. Ниже представлен пример без применения автозаугрузки (файлы трейтов и классов в каталоге appvs_php_0).
Для автозагрузки PHP предоставляет нам функцию , которая по умолчанию решает больштнство проблем. Ниэе представлен пример с использованием стандартной функции, а так как же с передачей анонимной функции для нашей кастомной логики.
37. Шаблоны проектирования
Singleton
Шаблон одиночки необходим в случаях, когда на основании класса необходимо создать только один объект. Например объект класса подключения к БД. В PHP для этого необходимо выполнить несколько манипуляций - во первых сделать конструктор класса приватным, во вторых - запретить клонирование.
Factory
Фабричный метод сложнее для понимания, однако с его помощью можно создать, например, роутинг. Для начала необходимо ознакомиться с примером, крайне внимательно. Затом попытайтесь описать что именно происходит в коде.
- Router.php
- Collection.php
- Users.php и Pages.php
- User.php и Page.php
- index.php
Итак, наша фабрика представляет собой простой роутер - она может либо вернуть коллекции по урлу или или конкретную сущность пользователя или страницы () если указать условный айди. Классы и наследуются от (они должны реализовать абстрактный метод ) и представляют собой отдельную сущность - при объявлении объекта класса необходио указать имя, фамилию, почту по желанию. В методах так же ничего примечательного нет.
Далее рассмотри класс - он намного интереснее. Его единственным свойством является массив пользователей или страниц (в зависимости от того, что запрашиваем). Внутри себя реализует пару методов: приватный возвращает массив строк, однако строки в этом массиве формируются методом , который вызывается у или . А так же метод , который возвращает массив в виде строки. Классы и наследуются от .
Базовый класс Router является абстрактным и реализовывает единственный метод (метод скорее предсталвяет собой элемент интерфейса). принимает в качетсве аргумента url вида или . При обращении к мы получаем массив из одного элемента users, далее создаем переменную класса, при этом задаем первую букву элемента заглавной. Далее идет проверка на id - это был бы второй элемент массива и создается новый объект класса, в данном случае класса . Метод возвращает полученный объект класса и далее в мы вызываем у метод .
В случае с переданным id происходит почти все тоже самое, отличается только возвращаемый объект. В этом случае вернется один из элементов коллекции.
MVC (Model-View-Controller)
Паттерн Модель-Представление-Контроллер один из самыз популярных моделей проектирования. Его задача состоит в разделении содержимого документов (модель), их обработку (контроллер) и их отображение (представление).
Класс модели предоставляет данные - это как правило класс, который взаимодействует с БД или API-сервисами. Класс представления отвечает за генерацию представления. Класс контроллера же является координатором - запрашивает данные с БД, принимает информацию от пользователя, запрашивает представление для генерации и последующей передачи клиенту.
Обращение напряму к БД из представления или хранение его в БД не допускается!
Пример может быть сложен для понимая, однако не стоит торопиться и важно проследить все, от точки входа в приложение () до конечных представлений. Ниже представлен код, начиная с точки входа в приложение (фрагменты кода разбиты по их каталогам)
- MVC/index.php
- MVC/Controllers
- MVC\Decorators
- MVC\Views
- MVC\Models
38. Итераторы
Итераторы - это объекты-коллекции, которые можно обходить в цикле .
Так как PHP не планировался как ООП-язык, поведение не всегда может быть очевидным. Например он позволяет перебирать публичные свойства объектов класса. Это связано с тем, что объекты добавлялись в язык как надстройка над массивами. Тут как раз вступает в игру итератор - это объект, который подставляет в цикл конструкции так, как если бы мы перебирали ассоциативный массив.
Interator
Итератором может считаться любой объект, класс которого реализует интерфейс (наследуется от ). Итератор можно назвать "представителем" итерируемого объекта. Можно сказать, что объект передает полномочия отобразить что то в цикле своему представителю. Собственные итераторы требуюь реализации определенных в интерфейсе методов.
Из примера не совсем очевидно преимущество нашего итератора. Однако мы можем добавлять различные проверки, а так же вывод нашего текущего элемента.
39. Отражения (reflection)
Отражения являются достаточно узкоспециализированной вещью в PHP и служат в основном для анализа кода, а так же при разработке фреймворков. Ниже представленны примеры кода отражений, чтобы было общее представление что это такое. При запуске вы увидите данные о том, или ином запрашиваемом участке кода.
40. Подключение и настройка расширений
Расширения - это подключаемые библиотеки, со своими классами, функциями, константами и тд. Множество библиотек со временем были включены в ядро интерпретатора PHP, поэтому их не нужно подключать явно (например - функция одной из таких библиотек). Нативно PHP содержит множество библиотек, которые подключаются при установке и настраиваются в файле . В данной ветке приложен архив PHP, если его распаковать и перейти в каталог вы увидите множество подкаталогов - это и есть расширения. Данный архив так же доступен по ссылке
php.ini
Для того чтобы посмотреть где находится конфигурационный файл можно использовать - вам необходима строка - в ней указывается расположение файла. Если вы работаете из под докера - файл следует искать внутри вашего докер-контейнера! В указанном каталоге можно увидеть два типа файла - для разработки и продакшена. Это автоматические сгенерированные настройки для разных окружений.
Сама структура файла представляет собой блоки, обозначающиеся , а так же директивы и их значения ()
Точка с запятой в начале строк - это комментарии. Соответсвенно, чтобы включить\отключить какую либо директиву необходимо ее раскомментировать\закомментировать.
Как говорилось выше - можно узнать расположение файла с помощью , однако можно указать путь до вашего кастомного с помощью аргумента . Обычно это делается для отладки, при запуске php локально. Полная команда выглядит так:
Параметры
Ниже приведены наиболее часто используемые параметры
- по умолчаниюengine, так как позволяет выполняется самим скриптам PHPOn- задает количество знаков после запятойprecision- включить\отключить использование коротких теговshort_open_tag- максимальное количество процессорного времени (в секундах) на выполнение скриптаmax_execution_time- максимальное количество процессорного времени (в секундах) отводимого на разбор гет и пост данных (в том числе файлов). По умолчаниюmax_input_time, что означает неограниченное время (в жтом случае будет использована предыдущая настройка)-1- максимальное количество выделяемой ОЗУ под выполнение скриптаmemory_limit- разрешает загрузку файловfile_uploads- задает каталог для хранения временных файловupload_tmp_dir- максимально допустимый ращмер загружаемых файловupload_max_filesize- максималный размер пост данныхpost_max_size
Расширения
Расширений в PHP огромное количество, но ниже представленны одни из самых востребованных
,BS Math- для работы с большими числамиGMP- низкоуровневые сетевые операцииCURL,DBA- работа с "плоскими" файламиdBase- доступ по протоколу FTPFTP- определение страны, города, широты и долготы по IP-адресуGeoIP,GD- преобразование и обработка изображенийGmagick- преобразование кодировокiconv- почтовый протокол IMAPIMAP- доступ к иерархическим LDAP-базам данныхLDAP,Libxml- работа с таблицами XMLSimpleXML,Memcache- обеспечение доступа к NoSQL БД Memcached (полностью располагаеься в ОЗУ)Memcached- обеспечение доступа к NoSQL БД MongoDBMongoDB- работа с PDF файламиPDF- обчеспечение доступа к реляционным БД (MySQL, PostgreSQL)PDO- среверная интерпретация JS кодаV8js- работа с YAML-файламиYaml,Rar,Zip- сжатие данныхZlib
41. Работа с PostgreSQL
PostgreSQL является реляционной БД с открытым исходным кодом.
Установка (ALT Linux) и основные команды
Ниже представлены команды, которые следует вводить последовательно. Это всего лиш первоначальная установка сервера БД.
В PG есть возможности администрирования, по умолчанию создается суперпользователь postgres. Это может быть не совсем
удобно, пожтому лучше создать нового пользователя. Команда ниже буквально означает: Запустить утилиту под
пользователем . - это утилита для доступа к серверу БД.
После запуска утилиты выполните следующие команды:
Далее мы создадим БД для текущего пользователя
После этого можно зайти на сервер БД и посмотреть текущего пользователя:
СУБД и SQL
(, , и т.д.) - это система управления базами данных. Так как сами базы данных это просто файлы с записями на сервере - они не представляют особого интереса. СУБД же напротив - она позволяет выполнять все низкоуровневые операции с данными из файлов, предлагая при этом удобный синтаксис (Не путать! - - это именно язык запросов к БД).
Возможности SQL:
- Выборка данных - извлечение из БД информации
- Организация данных - определение структуры БД и установление отношений между ее элементами
- Обработка данных - создание, изменение, удаление
- Управление доступом - ограничение возможностей ряда пользователей на доступ к данным, защита от несанкционированного доступа
- Обеспечение целостности данных - защита БД от разрушения
- Управление состоянием СУБД
Важно помнить что не является ЯП в привычном понимании - с его помощью невозможно создать программу, а выполняется он только в специализированных средах выполнения или с помощью различных библиотек.
Так как PG является реляционной БД будет не лишним указать общие особенности подобных баз:
- Данные хранятся в таблицах, состоящих из столбцов и строк
- На пересечении каждого столбца и каждой строки может находится только одно значение
- У каждого столбца есть имя и все значения столбца имеют один тип
- Столбцы располагаются в определенном порядке, который задается при создании таблицы
- Запросы к БД возвращают результат в виде таблиц, которые могут выступать как объект запросов
Более подробно управление БД и различные нюансы будут рассмотрены в рамках другого репозитория. Однако ниже будут представлены необходимые запросы и команды для про продолжения практики.
Создание и редактирование таблиц и данных
Вам необходимо использовать утилиту , затем выполнить команды. Посмотреть список созданных БД можно с помощью команды . Обратите внимание, так как мы работаем в терминале, необходимо указывать после запроса.
Детальную информацию о таблице можно посмотреть с помощью команды c указанием имени таблицы, например .
Для изменения таблицы используется команда
Для добавления значений в таблицу испоьзуется команда . Синтаксис должен быть интуитивно понятен, но мы все равно его разберем: Указывается таблица в которую необзходимо внести данные , далее указываем в скобках поле , последняя часть запроса задает значение для указанного поля - обратите внимание, что тут важен порядок написания; поля и значения должны соответствовать.
42. Расширение PDO
PDO представляет собой единый интерфейс для работы с различным БД (раньше были отделньые функции для разных БД).
Работа из под Docker
Необходимо установить некоторые расширения для нормальной работы. Посмотрите на измененный
Установка соединения
Установка соединения с БД основывается на создании объекта класса . В качестве аргументов конструктор класса принимает - источник данных, содержащий название драйвера, адрес сервера и имя БД. Вторым параметром идет имя пользователя (), третьим пароль (). Последний - задает дополнительные параметры .
Чтобы проверить, что соединение установленно корректно (помимо блока ) мы можем извлечь версию сервера БД.
Для выполнения запроса мы используем объект и его функцию , которая возвращает объект класса . Этот класс представляет собой интерфейс для доступа к результирующей таблице. Саму таблицу можно посмотреть с помощью . Мы же сразу обращаемся к значению по ключу 'version'.
Выполнение запросов
Для выполнения запросов, которые не требуют вывода результата в виде таблицы (создание таблицы, добавление полей и т.д.) лучше всего воспользоваться методом класса . Он возвращает количество затронутый запросом строк или, в случае неудачи, .
Обработка ошибок
Как и в остальном коде обрабатывать ошибки запросов лучше всего в . Обратите внимание, что мы обрабатываем . В данном случае ошибка скажет нам о том, что функции не существует.
В расширении предусмотрено несколько режимов обработки ошибок. Обычно используется режим по умолчанию, который представлен выше - это генерация исключений(). Так же есть тихий режим и режим предупреждений . Настраиваеются они в параметре при создании объекта .
Извлечение данных
Для извлечения данных нам, для начала, необходимо заполнить таблицу. Обратите внимание, что это учебный запрос! Более правильный подход будет рассмотрен позднее, сейчас же скажем, что передавать переменную напрямую в запрос - небезопасно! Так же стоит отметить, что запрос необходимо выполнить единожды - так как при каждой перезагрузке страницы данные будут добавляться снова и снова в таблицу.
Теперь пора извлечь данные из нашей таблицы. Обратите внимание на логику работы данного скрипта. Повторим еще раз: мы получаем объект результирующей таблицы с помощью (передав соответствующий запрос), далее до тех пор пока метод возвращает нам что то осмысленное (стору результирующей таблицы). Как только вернет - а это случиться когда все строки таблицы будут возвращены поочередно - мы выйдем из цикла .
Для простоты понимания - мы можем последовательно вызывать метод , каждый раз он вернет нам следующую строку результирующей таблицы:
Если вырадаться более правильно, то возвращает ассоциативный массив, где ключи - имена столбцов таблицы в БД, а значения - собственно значения ячеек этих столбцов. Но это поведение по умолчанию и его можно изменить передав параметр . Обратите внимание как поменяется вывод:
Так же есть возможность извлечь данные сразу в виде массива с помощью метода . Метод так же может принимать в качестве аргумента константы, которые рассмотрели выше.
Параметризация SQL-запросов
Чтобы извлеч определенные данные, их необзодимо отфильтровать - это делается с помощью команды (в запросе). Однако передавать данные для фильтра в сам запрос (переменные) считается небезопасным и плохим тоном. Для того, чтобы обезопасить себя от SQL-инъекций существуют параметризированные запросы. Они проходят несколько стадий: подготовка, связывание с переменными и выполнение.
Запросы из примера выше называют подготовленными (параметры в запросе указываются с помощью . Такие запросы передают методу . Параметры данного запроса подготавливаются в методе . Данному методу передается ассоциативный массив с именами параметров (без двоеточия) и необходимым значением. Стоит так же упомянуть, что параметры могут быть безымянными - в таком случае они обозначаются как , а в передается массив. Так же обратите внимание на закомментированную строку - это просто пример, что мы можем получить запрос от клиента, извлечь из него данные и эти данные использовать для получения записи из БД.
Заполнение связанных таблиц
Обратите внимание на следующую форму - мы связали две таблицы с помощью . И только после записи в мы пишем данные в .
43. Работа с изображениями
Обратите внимание! В данной ветке был изменен - подключена новая библиотека для работы с
изображениями - .
getimagesize
Данная функция используется наиболее часто при работе с изображениями. Принимает путь до нужного файла и возвращает ассоциативный массив с данными по файлу.
Пример создания изображения
Ниже представлены несколько функций библиотеки . Код представляет собой пример вывода изображения с текстом, который мы указываем сами
Создание изображения
Функции и используются для создания изображений. Первая обычно используется для создания GIF и PNG изображений, вторая для JPEG. Это связано с тем, что JPEG - это полноцветный формат изображения. Обе функции возвращают идентификатор созданного изображения (по аналогии с работой с файлами - дескриптор).
Функции , , загружают указанные изображения в память и возвращают их идентификатор. Данные функции могут работать так же с URL-адресом изображения.
Для определения параметров изображения используются функции и - возвращают, соответственно, горизонтальный и вертикальный размеры изображения в пикселях. Функцию обычно применяют при работе с GIF и PNG. позволяет определить является ли изображение полноцветным.
Функции , и используются для сохранения изображения или для вывода в браузере (как в файле ).
Вы так же можете преобразовать изображение в палитровое с помощью .
возвращает идентификатор цвета (в формате RBG). Обратите внимание, что первым параметром она принимает идентификатор GD изображения.
Графические примитивы
Вы так же можете "рисовать" самостоятельно с помощью ряда функций. В качестве примера приведем прямоугольник, при острой надобности все возможности работы с изображениями можно найти в документации
44. Работа с сетью
Потоки
Рассмотренные до этого функции для работы с файлами имеют интересную особенность - они способны работать с внешними HTTP-адресами.
Вы так же можете обращаться по FTP протоколу с помощью . Так же следует помнить, что за возможность подключаться таким образом отвечает настройка в php.ini .
Поскольку тема потоков очень обширна, рекомендуется обратиться к документации в случае, когда вам понадобиться подобный механизм.
Вам так же может встретиться понятие "контекст потока" - это набор опций, который принимают некоторые функции. Например, функция третьим параметром. Однако стоит учесть, что такой параметр ждет функцию , которая уже принимает в качестве своего параметра массив с настройками. Обратите внимание, поскольку вы можете задавать сетевые настройки, вы так же можете передать данные, например методом , правильно указав все настройки в массиве.
Сокеты
Сокеты - это интерфейсы для сетевых обращений. Обратите внимание, в примере ниже мы устанавливаем соединение с главной страницей Гугл, указав URL и порт. Функция так же принимает езе три параметра - код ошибки, текст ошибки и время соединения (время, которое мы готовы ждать ответ от указанного host). Символы обозначают конец строки в протоколе HTTP. Так стоит упомянуть, что функция возвращает файловый дескриптом (или ). Именно поэтому мы можем читать данные как файл в цикле.
Работа с DNS и IP
Как известно, для адресации машин в Интеренете используются два способа: указание IP-адреса хоста или его доменного имени. Каждому домену может соответствовать несколько IP-адресов и наоборот, каждому IP-адресу может соответствовать несколько доменов.
Преобразованием доменных имен в адреса (и наоборот) занимаются специальные DNS-серверы, которые распределены по всему миру. Их задача состоит в том, чтобы получить от клиента адрес (имя) и отдать клиенту имя (адрес).
В PHP есть несколько функций, которые позволяют работать с адресами:
CURL
Данная библиотека позволяет устанавливать соединение с удаленными сервисами (сайтами). Доступны к отправке GET и POST запросы. Пример GET-запроса:
устанавливает соединение с указанным адресом, позволяет указывать различные опции для подключения и передачи контента. отдает результат запроса. Функция отмечена к удалению в PHP 8.5, так что закрывать соединение не требуется. Однако если это необходимо то можно использовать функцию .
Ниже представлены возможные опции для :
- при true устанавливает HTTP-заголовок Referer автоматическиCURLOPT_AUTOREFERER- при true UNIX-переводы строк преобразуются к \r\nCURLOPT_CRLF- при true в ответе отдаются HTTP-заголовкиCURLOPT_HEADER- при true не включает в ответ документCURLOPT_NOBODY- отправляет POST-запросCURLOPT_POST- отправляет PUT-запросCURLOPT_PUT- при true возвращает результат, а не выводитCURLOPT_RETURNTRANSFER- при true происходит закачка файла на удаленный серверCURLOPT_UPLOAD- версия HTTP-протоколаCURLOPT_HTTP_VERSION- методы HTTP-аутентификацииCURLOPT_HTTPAUTH- размер файла при его загрузкеCURLOPT_INFILESIZE- содержимое HTTP-заголовка CookieCURLOPT_COOKIE- имя cookie-файлаCURLOPT_COOKIEFILE- имя файла, в котором сохраняются несессионные cookieCURLOPT_COOKIEJAR- координаты фрагмента загружаемого файлаCURLOPT_RANGE- значение HTTP-заголовка RefererCURLOPT_REFERER- URL, с которым производится операцияCURLOPT_URL- значение HTTP-заголовка User-AgentCURLOPT_USERAGENT- Строка с именем пользователя в виде [username]:[password]CURLOPT_USERPWD- массив HTTP-заголовковCURLOPT_HTTPHEADER
45. NoSQL-БД Redis
NoSQL-БД приобрели популярность за счет того, что обращение к ним занимает намного меньше времени, чем к реляционным БД. Это связано с тем, что NoSQL-БД расположены прямо в оперативной памяти, в то время как обычные БД чаще всего на SSD или, в худшем случае, на жестком диске. Прототипом для современных NoSQL решений была . Однако сейчас появилось множество БД, превосходящих ее: , , и другие.
В этой ветке будет рассмотрена , как одно из самых популярных решений.
- быстрый однопоточный сервер для хранения данных в ОЗУ. Данные могут храниться в разных видах: в виде пар ключ=значение, строк, массивов, хешей, множеств.
Установка
Для установки в ОС Alt Linux используются следующие команды:
Для проверки, что сервер Redis запущен и работает, можете ввести команду:
Введите команду и получите ответ . Так же, можете ввести команду и увидите информацию о сервере.
redis-cli
является консольным клиентом сервера. Он важен при отладке, поэтому приведем здесь базовые команды. Сама команда является сокращенной записью . Как можно догадаться - это запуск сервера на локальной машине на стандартном порту (для Redis) 6379.
Ключевое слово HELP позволяет вам получить справочную информацию по определенным командам. Например:
Закомментированный код представляет собой вывод команды. - краткое описание назначения команды, - версия , в которой появилась команда, - группа, в которую входит команда.
Вы можете посмотреть список команд для указанной группы с помощью специального символа и названия группы:
Группы после можно перебирать с помощью . Ниже представлен полный список групп:
- общие команды@generic- работа со строками@string- работа со списками@list- работа с множествами@set- работа с сортированными множествами@sorted_set- работа с хешами@hash- организация подписчиков@pubsub- команды транзакций@transactions- соединение с сервером@connection- управление сервером@server- автоматизация обработки данных@scripting- команды для работы с алгоритмом подсчета уникальных элементов@hyperloglog- обслуживание redis-серверов@cluster- работа с координатами@geo- обслуживание потоковых структур@stream
Добавление, изменение и удаление пар
Команды SET и GET добавляют и получают значение. Команда SET пишется с двумя аргументами - ключ и значение, причем аргументы просто отделяются пробелом. Команды MSET и MGET используются для вставки нескольких значений, одно за другим.
Чтобы обновить значение можно использовать так же команду SET. Обратите внимание, что имя ключа заключено в кавычки, но это необязательно - их можно опустить.
Существуют и другие команды для изменения значений: - добавляет строку к существующей, увеличивает целочисленное значение на 1, - уменьшает.
Для удаления пары ключ=значение используется команда .
Управление ключами
Важно всегда знать, какие именно ключи хранятся у вас в БД. Для просмотра списка ключей используйте команду .
в данном случае означает все, вы можете фильтровать таким образом вывод, например означает "Покажи все ключи, начинающиеся с f". Для изменения имени ключа используется команда с двумя аргументами - старым и новым именами.
Для управления временем жизни ключей используйте команду с указанием ключа и времени его жизни в секундах. Вы так же можете использовать команду - в этом случае время жизни задается в формате . Для проверки оставшегося срока жизни ключа используется команда .
Ограничение на срок хранения ключа можно отменить командой :
Типы данных
поддерживает два типа данных:
- Скалярные - к ним относятся строки и числа.
- Коллекции - списки, хеши, множества, отсортированные множества.
Проверить тип можно с помощью команды
Хеш
Создается командой , которая принимает ключ хеша, далее пару ключ-значение. Для создания сразу нескольких пар ключ-значения используется команда , с передачей ключа хеша и перечисления пар (как в примере с ). Получить конкретное значение ключа в хеше можно с помощью команды с указанием ключа хеша и ключа, чье значение вы хотите получить.
Если вы хотите посмотреть все ключи или все их значения используйте и
Проверить существование поля в хеше можно с помощью :
Команда отдаст все одержимое хеша:
И, наконец, узнать длину хеша поможет команда :
Множество
Множество - это неупорядоченная коллекция уникальных элементов. Дублирующие элементы отбрасываются автоматически. Добавить элемент в множество можно с помощью команды , первым аргументом идет имя множества вторым уникальное значение. Обратите внимание, что дублирующие значения просто не будут добавлены. Так же можно добавлять несколько значений через пробел. Чтобы посмотреть значения множества, используется команда .
Так же можно посмотреть количество элементов в множестве с помощью .
Удалить элемент из множества можно с помощью команды
отдает случайный элемент множества
Одной из главных фич множества является возможность поиска, объединения и пересечения нескольких множеств. Поиск происходит по общим электронным адресам с помощью команды
Для поиска элементов, не входящих в другое множество используется
Множества можно объединять с помощью команды , при этом дублирующие элементы будут отброшены. Команда позволяет сохранить результат объединения в новую коллекцию.
Команда SMOVE перемещается элемент одного множества в другое
Отсортированное множество
Представляет собой гибрид всех вышеперечисленных типов. Хранит в себе пару ключ-значение, однако ключом является числовой индекс. Не допускает дублей. Обратите внимание на синтаксис добавления - вам необходимо указывать числовые ключи иначе добавить элемент не получится. Команда выводит множество в указанном диапазоне. Чтобы вывести от первого (0) до последнего элемента используйте конструкцию . покажет сколько всего элементов в множестве.
Для удаления используйте команды и . Первая удаляет элементы в указанном диапазоне, вторая указанный элемент.
Базы данных и производительность
Для того чтобы замерить производительность у него имеется встроенная утилита
Так же в есть БД, по умолчанию запускается БД 0, чтобы ее изменить можно использовать команду .
Работа с Redis в PHP
Все команды, которые мы рассматривали выше доступны в PHP в виде методов объекта класса . Однако вам необходимо установить расширение php-redis. Посмотрите на измененный
Ниже представлены примеры команд для работы с :
Сессия в Redis
Для того чтобы хранить сессию клиента (смотри ветку chapter_20) в Redis необходимо внести изменения в файл или воспользоваться функцией . Обратите внимание, что данные настройки необходимо прописать до любого вывода в браузер. В результате вы получите ключ сессии .
Кеширование данных
В примере представлена имитация сложных вычислений\получения данных. Попробуйте, разберите его самостоятельно, так как ничего сложного в данном примере нет.
46. Управление компонентами
Для начала работы вам необходимо установить Composer и некоторые системные зависимости. Для ALT Linux:
Подразумевается, что у вас уже установлен PHP. Если версии отличаются - замените версию на вашу. Далее, следуйте инструкция с официального сайта Composer. Проверьте что Composer доступен:
Для работы в докере измените :
Компоненты
Компоненты по сути являются библиотеками - коллекцией связанных классов, интерфейсов и трейтов, призванных решать определенную задачу. Так как компонентов есть огромное множество, а некоторые из них требуют другие компоненты для своей работы, встает задача - как найти компонент и все его зависимости. Эту задачу призван решать . Он чем то похож на npm в Node.JS или pip в Python.
Когда вы установили Composer (инструкция выше), то встает следующий вопрос - где искать компоненты? Вот тут. Если сайт недоступен в РФ, то следует поискать обходные пути.
Для установки компонента в ваше приложение используется команда . Имя пакета вы найдете на сайте выше, оно представляет собой . Например .
Если вы работаете под докером, то устанавливать компоненты следует в php-контейнере!
После установки вы должны увидеть каталог и два файла: и . Каталог рекомендуется внести в .
Файл является конфигурационным, в нем содержаться используемые в проекте компоненты и их версии. Для установки этих компонентов используется команда - тут стоит пояснить, что сам код и все зависимости компонентов находятся в каталоге , однако его мы добавили в . Когда вы скачаете репозиторий проекта - там не будет каталога компонентов, следовательно, их надо установить. Именно это и делает.
Файл содержит в себе дерево зависимостей пакетов и источники загрузки, а так же версии установленных пакетов.
Для обновления версий компонентов используется команда - она обновляет сразу все подключенные библиотеки. Для обновления конкретной необходимо указать ее имя: .
Использование компонента
Composer предоставляет свой механизм автозагрузки классов - файл , который расположен в . Пример использования компонента :
47. PSR стандарты
PSR - PHP Standards Recommendations - рекомендуемые правила написания кода на ЯП PHP.Современные IDE уже обучены следовать PSR стандартам, например PHPStorm или VSCode (с плагином). Здесь же мы приведем ссылку на документацию, с которой вы можете ознакомиться при желании.
48. Документирование
На момент написания конспекта, вышел PHP8.5, однако нужная библиотека его не поддерживала. В связи с чем был изменен
Здесь будет показано документирование на примере использования PHPStorm.
Обратите внимание на . Слова начинающиеся с этого символа, называются теги. При документировании доступны несколько тегов:
- @api
- @author
- @category
- @copyright
- @deprecated
- @example
- @filesource
- @global
- @ignore
- @internal
- @license
- @link
- @method
- @package
- @param
- @property
- @property-read
- @property-write
- @return
- @see
- @since
- @source
- @suboackage
- @throws
- @todo
- @uses
- @var
- @version
49. Атрибуты
Атрибуты - это механизм, включенный в PHP 8.0 для добавления метаданных элементам программы (в других ЯП может называться аннотации).
Примеры использования атрибутов:
- Документирование
- Разгрузка логики классов
- Пометка окружения для успешного тестирования
- Фреймворки используют атрибуты для реализации скрытым подсистем
Синтаксис
Синтаксис атрибута достаточно просто - . Внутри вы размещаете название атрибута. Добраться до атрибутов можно с помощью отражений - .
Вы так же можете назначать несколько атрибутов
Как было показано выше - для доступа к атрибутам используются отражения. Так как атрибуты можно добавлять к классам, функциям, свойствам, методам и константам, для доступа к атрибуту придется использовать конкретный класс отражения:
- ReflectionConstant
- ReflectionFunction
- ReflectionParameter
- ReflectionClass
- ReflectionProperty
- ReflectionMethod
- ReflectionClassConstant
Посмотрите как можно получить атрибуты методов класса:
Класс атрибута
Если классу добавили атрибут и при этом этот класс находится в пространстве имен, то механизм отражений добавит пространство имен к имени атрибута:
Так происходит потому что механизм атрибутов предполагает, что в качестве имени атрибута будет выступать класс. Обратите внимание на пример ниже - там представлены два класса, класс помечен атрибутом , а класс атрибутом . Здесь атрибут класса сам является классом, и его необходимо пометить атрибутом . С помощью метода мы получаем новый экземпляр класса, в котором нам доступны методы класса .
Стоит так же упомянуть об аргументах атрибутов - они доступны только если класс атрибута принимает их в качестве параметров. Ниже приведен пример, с которым вы скорее всего столкнетесь при использовании Symfony или Laravel. Так же обратите внимание на то что атрибуты принимают и именованные аргументы и позиционные.