[Webshake] Курс «PHP для начинающих» - Часть 1

Что Вы получите после прохождения курса

В ходе прохождения этого курса вы освоите основы программирования на PHP и изучите возможности этого языка. Данный курс по PHP предназначен для обучения начинающих и содержит подробные текстовые и видео-инструкции - выбирайте что вам больше по душе.

В курсе всё изучается очень подробно - начинается обучение с того, как вообще работает PHP. Рассказывается о современных инструментах и подходах. И, конечно же, даются домашние задания, которые я лично проверяю. Здесь мы с вами и установим локальный веб-сервер, и научимся работать в редакторе кода, и, конечно же, напишем свои первые программы на PHP.

Этот курс позволит освоить базовые принципы в программировании, без которых не обойтись ни одному будущему разработчику. Здесь вы получите необходимый фундамент, который позволит вам идти дальше, изучая более интересные и сложные темы в программировании.

Введение в курс по PHP

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

Поначалу я не мог определиться — заказать написание курса, или же сделать это самому. С одной стороны — простота для меня, но неизвестное качество продукта, а с другой — много труда, но гарантированное донесение моего видения до Вас.

В итоге, именно возникшая в моей голове цель — помочь вам стать крутыми PHP-разработчиками, побудила меня к созданию данного курса своими мозгами и руками.

Что касается моего видения языка - оно таково: современный PHP – это очень гибкий язык, в умелых руках позволяющий создавать поддерживаемые веб-приложения любой сложности. Facebook, Вконтакте, Badoo, Wikipedia – все эти гиганты используют PHP.

Производительность последних версий выросла в 2 раза по сравнению с PHP 5.6, сейчас этот язык находится в стадии очень бурного развития и улучшения.
На данный момент этот язык является самым востребованным у работодателей.

Помимо этого, у языка очень большое сообщество и качественная официальная документация, переведенная на многие языки, включая русский. В распоряжении разработчика есть менеджер пакетов Composer и репозиторий Packagist, содержащий более 120 тысяч пакетов. А в ноябре 2016 года из этого репозитория было произведено 219 миллионов установок пакетов!

А теперь о том, что именно Вы должны делать, чтобы получить максимум от этого курса и стать в дальнейшем профессионалом. На самом деле это всего одно действие: Вы должны самостоятельно пытаться делать домашние задания, которые будут прилагаться к урокам. У Вас не обязательно должно получаться, особенно поначалу. Но Вы должны пробовать сделать это самостоятельно. И со временем у Вас обязательно всё получится!

Готовы учиться по такой схеме? Тогда поехали!

Как работает PHP

Приветствую! В этом уроке мы разберём, что же из себя представляет PHP, как он работает и для чего он предназначен.

Начнём с того, что программа, написанная на языке PHP, во время своей работы представляет из себя не то стандартное окошко, которое мы привыкли видеть. В абсолютном большинстве случаев эта программа работает на сервере «невидимо». То есть мы не можем управлять ею во время выполнения, но на самом деле нам это и не нужно :slight_smile:

Дело в том, что эта программа должна принимать запрос от пользователя, сделать какие-то действия, отдать пользователю результат и после этого завершиться. И чем быстрее она отработает, тем лучше. В этом главное отличие программ на PHP от «стандартных» программ, которые постоянно висят в памяти, ждут действий пользователя и реагируют на них в режиме реального времени.

PHP не работает сам по себе. Для работы с пользователем он должен быть настроен в связке с веб-сервером, например, Nginx или Apache. Если по-простому, то пользователь отправляет запрос к веб-серверу по протоколу HTTP. Веб-сервер определяет, к какому типу файла было совершено обращение, и, если это файл с расширением .php, то веб-сервер передаёт запрос на обработку интерпретатором языка PHP, скрипт считывается, преобразуется в байт-код, выполняется и возвращает ответ веб-серверу. Веб-сервер передаёт сформированный результат пользователю. Этот результат, как правило, представляет собой динамически сгенерированную HTML-страничку.

Этот процесс можно значительно ускорить, подключив расширение-акселератор. Оно занимается тем, что кэширует получившийся байт-код, и пока файл остаётся неизменным сразу начинается его выполнение. Начиная с версии PHP 5.6 акселератор OPcache включён в дистрибутив по умолчанию.

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

Наверное, Вы уже успели подумать о том, что для того чтобы запустить программу на PHP, Вам придётся повозиться с настройкой, ведь нужно связать его с веб-сервером. К счастью, есть готовые решения, позволяющие запустить веб-сервер с PHP за несколько минут. А современные хостинги позволяют выкладывать и запускать проекты на PHP, вообще не задумываясь, как там всё устроено. И это хорошо, ведь Вы — программист, а не системный администратор. Прошу Вас это принять, это позволит расти как программисту гораздо быстрее. Разумеется, со временем Вам придётся вникнуть в эту область, но прошу Вас не делать этого сейчас — посвятите себя программированию.

Готовое решение в качестве сервера, которое я всем советую использовать, называется OpenServer . О том, как его установить и запустить, мы поговорим в следующем уроке.

Установка и настройка OpenServer

Ну что, чешутся руки установить веб-сервер и написать первую программу на PHP? Сейчас всё будет.

Первым делом идём на официальный сайт OpenServer и скачиваем программу. Я рекомендую скачать BASIC-комплектацию, для наших нужд её вполне хватит. Однако можете посмотреть список программ, которые включены в другие пакеты. Возможно, найдёте что-то полезное, будь то какой-нибудь редактор кода или GUI-клиент для СУБД MySQL.

Итак, приступим. Первым делом нужно скачать саму программу.

Так как на оф. сайте на сегодняшний день скачать его проблемно, советую качать отсюда.
Ссылка на оф. сайт: https://ospanel.io/

Установка

Запускаем установщик и задаём директорию для установки программы. Установка представляет собой простую распаковку.

После завершения установки окно молча закроется.

Настройка

Переходим в папку с распакованным ПО: C:\OpenServer.
Здесь мы видим файлы для запуска программы OpenServer для разных версий системы и 3 папки:

  • domains – папка, предназначенная для хранения Ваших сайтов. Внутри неё мы и будем создавать наши проекты, например: myproject.loc;
  • modules – папка, содержащая в себе исполняемые файлы модулей и необходимые для их работы библиотеки, дополнительные файлы;
  • userdata – папка, в которой находятся пользовательские данные СУБД, файлы кэша, логи, а также файлы конфигурации модулей.

Запустим один из exe-файлов в корне, в зависимости от разрядности вашей ОС. В моём случае это Open Server x64.exe .

Выбираем язык и соглашаемся с установкой необходимых библиотек:

Перезагружаем компьютер. После перезагрузки снова запускаем наш exe`шник. В трее появляется значок с красным флажком.

Жмём по нему правой кнопкой мыши и выбираем пункт “Настройки”. Откроется главное окно программы. Перейдём во вкладку “Модули” и выберем версию PHP: PHP 7.0 и версию Apache: Apache-PHP-7 .

Затем перейдём во вкладку “Домены”, выберем “автопоиск доменов” и в качестве корневой папки домена выберем пункт с наибольшим числом вариантов. Вы также можете дописать сюда свои варианты.

После чего нажимаем “Сохранить” и закрываем окно настроек.

Включение акселератора OPCache

Помните в прошлой статье я говорил об акселераторе? Давайте включим его. Это делается в файле php.ini. Для того, чтобы отредактировать его, щелкнем правой кнопкой мыши по флажку и выберем пункт Дополнительно > Конфигурация > PHP-7 . Здесь нужно убрать комментарии для строк:

zend_extension="%sprogdir%/modules/php/%phpdriver%/ext/php_opcache.dll"
opcache.enable=1

Должно получиться так:

Сохраняем файл. На этом конфигурация завершена.

Hello World

Перейдём в папку “domains” и создадим директорию для нашего проекта. Назовём его “myproject.loc”. Внутри создадим директорию “www”. А внутри неё файл “index.php”. Откроем его и впишем следующий код:

<?php
echo 'Hello world!';

Теперь можно запустить сервер и проверить работу скрипта.

Если при старте сервера появилась ошибка: Файл C:\Windows\system32\drivers\etc\hosts недоступен для записи - стоит закрыть программу и запустить её от имени администратора .

Флажок в трее должен стать зелёным.
Откроем браузер и перейдём по адресу http://myproject.loc/

Поздравляю! Ваша первая (или нет?) программа только что успешно отработала! Мы увидели результат её работы. И если мы сейчас откроем исходник страницы в браузере, то там не будет нашего исходного кода. Он выполнился, а веб-сервер отдал нам готовый результат. Пользователь никогда не увидит вашего кода на PHP. Вот так просто :wink:

На этом конфигурация завершена. В следующем уроке мы установим и настроим самую крутую IDE для PHP-разработчика – PHPStorm . А ещё узнаем о том, как можно пользоваться ей бесплатно.
До встречи!

Домашнее задание

Установите и настройте OpenServer согласно данному уроку.

Установка и настройка PHPStorm

Всем привет. В этом уроке мы рассмотрим крутейшую IDE для PHP-разработчика под названием PHPStorm. Эта IDE имеет отличную подсветку кода, кучу встроенных инструментов для рефакторинга, полезные подсказки, темы оформления на любой вкус и ещё гору всего. Стоит это добро для личного использования $89 в год. Однако, есть вариант использовать её совершенно бесплатно. Нет, речь не идёт о кряке/кейгене, сами авторы предлагают эту возможность. И именно с этого момента мы и начнём знакомство с этим ПО.

Варианты использования

Триал-версия

Всем желающим софт доступен в виде триал-версии на 30 дней - тыц. За это время Вы успеете определиться, нужно ли Вам приобретать данный софт или нет.

Покупка

Если Вас полностью удовлетворяет продукт и предлагаемый ценник не проблема – тогда стоит отблагодарить разработчиков и купить подписку. С каждым последующим годом цена продления уменьшается. Есть возможность и помесячной оплаты. Ссылка на страницу покупки - тыц

Early Access Programm (EAP)

Именно этот вариант я и выбрал. Если кратко – это бета-версия программы, в которой возможны баги, о которых будут извещаться разработчики ПО. Но в то же время, пользоваться ей можно абсолютно бесплатно. Скачать можно тут - тыц

Установка

Итак, скачиваем программу по ссылке и запускаем установщик. Установка проходит стандартно и как правило не требует никаких дополнительных телодвижений.
После установки запускаем программу и открываем созданный нами в прошлом уроке проект. Жмём File->Open и выбираем папку с проектом (C:\OpenServer\domains\myproject.loc) . Первым делом нужно задать правильную кодировку для всех файлов в проекте. Для этого идём в File->Settings .
Слева в меню разворачиваем пункт Editor , и выбираем вложенный пункт File Encodings . Задаём следующие настройки:

 Global Encoding: UTF-8
 Project Encoding: UTF-8
 Default encoding for properties files: UTF-8

И сохраняем изменения.

Теперь давайте удалим ранее созданные нами файлы, которые сейчас находятся в кодировке Windows-1251 . Да, кодировку всегда можно сменить в правом нижнем углу программы, смена производится для текущего открытого файла.

Теперь давайте создадим новый файл в нашем проекте с названием index.php . Для этого слева в структуре проекта щёлкаем правой кнопкой мыши по папке www , выбираем New->PHP File
Вводим имя и нажимаем Create .

Некоторые фишки PHPStorm`а, такие как автоматическое написание кода и быстрое форматирование с помощью сочетания CTRL+ALT+L я спалил в видео к этому уроку. Текстом это уж больно утомительно описывать =)

По ходу курса мы с Вами произведём ещё несколько настроек этой программы.
А на сегодня пока всё. Спасибо за прочтение. И не забудь подписаться на канал на YouTube.

Выражения в PHP

Всем привет! Сегодня поговорим о том, что же такое выражения в языке PHP.

Начнём с того, что выражение в языке PHP - это вообще любая строка, число, объект, массив, или что-то ещё, что представлено в явном виде или в виде каких-либо вычислений. Например:

'строка с пробелами'
7
2 + 2
5 / 2

Всё вышеперечисленное является выражениями. При этом выражение должно иметь какое-либо значение. Для примеров выше это, например, строка с текстом , целое число 7 , целое число 4 и, наконец, дробное число 2.5 .

Как вы понимаете, сами по себе выражения бесполезны, пока они не используются. Вся прелесть PHP в том что он может встраиваться в HTML .
Надеюсь, все знают, что такое HTML и умеют с ним работать. Если ещё нет - пройдите наш онлайн курс по основам HTML.

Так вот, PHP может быть встроен прямо в HTML .
Давайте отредактируем наш с вами файл index.php . Впишем в него следующий код:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Пример встраивания PHP в HTML</title>
</head>
<body>
<h1>Пример встраивания PHP в HTML</h1>
2 + 2 = <?php echo 2 + 2; ?>
</body>
</html>

и посмотрим на результат в браузере:
Пример встраивания PHP в HTML

Как мы видим, та часть кода, которая находилась внутри тегов <?php?> успешно выполнилась. Если мы сейчас в браузере посмотрим исходный код страницы, то увидим только получившийся результат.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Пример встраивания PHP в HTML</title>
</head>
<body>
<h1>Пример встраивания PHP в HTML</h1>
2 + 2 = 4
</body>
</html>

Ещё раз повторюсь, что код на PHP выполняется на стороне сервера. В браузер, клиенту, отдаётся только результат. Надеюсь, это понятно.

Давайте теперь разберемся, как же именно произошло то, что мы увидели. Веб-сервер видит, что был запрошен файл с расширением .php .
Он понимает, что здесь следует искать код на языке PHP, и он знает, что этот код расположен между тегами <?php?> и как только он их встречает,
то передаёт на выполнение этот код интерпретатору. Затем получает результат выполнения этого кода и просто отдаёт в браузер получившийся результат.
Если что-то сейчас непонятно - задайте вопрос в комментариях. Объясню более подробно.

Выражение, как мы уже успели сказать, может быть представлено в форме вычислений. Для вычислений, в свою очередь, могут использоваться несколько операторов.
Об этом мы поговорим в следующем уроке.

Переменные в PHP

Всем привет. Сегодня разговор пойдёт о переменных в языке PHP. О том, что это такое и как с этим работать читайте ниже.

Начнём с определения.
Переменная – это какое-то значение, которому соответствует определённое имя.
Как в математике, x = 2 – переменная x равна двум. Здесь x – имя переменной, 2 – её значение.

В PHP переменные начинаются со знака " $ ".
Например: $x .

Чтобы присвоить переменной значение, используется знак " = ", пример:

$x = 2;

Эта операция так и называется – присваивание переменной.

Помимо этого, переменную можно просто объявить, вот так:

$y;

Сейчас это выглядит довольно бессмысленно. Но позже мы обязательно рассмотрим, для чего это может применяться. Пока что просто запомните, что такое возможно, и это называется объявлением переменной.

Разумеется, переменной можно присвоить и результат целого выражения. Пример:

$sum = 5 + 10;

А затем использовать её:

echo $sum;

Также мы можем использовать переменные внутри других выражений:

$x = 2 + 3;
$y = ($x * 2) / ($x + 1);

echo $y;

Стоит обратить внимание, что имена переменных в PHP являются регистрозависимыми. То есть $x и $X – две разные переменные.

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

$subscriberEmail = ‘user@email.com’;
$catName = ‘Барсик’;
$dayOfWeek = ‘среда’;

Пример плохого имени:

$result = $b ** 2 - 4 * a * c; // более подходящее название - $discriminant

Кроме того, есть определённые правила, которые не влияют на работоспособность кода, но которых придерживаются все программисты на PHP. Это позволяет легко читать код других программистов, а это очень важно, так как над крупными проектами работает всегда несколько человек, и им обязательно приходится читать код друг друга. Повторюсь, эти правила чрезвычайно важны, потому что в будущем, когда Вы придёте работать на работу, Ваш код будут читать и изменять другие программисты, подумайте о них уже сейчас. Итак, перечислим эти правила.

  • Имя переменной должно состоять только из английских слов, и уж тем более только из букв английского алфавита.
    Никаких $imyaKota или тем более $имяКота , строго $catName
  • Имя переменной должно начинаться с маленькой буквы, а следующие слова, содержащиеся в её имени, должны начинаться с большой буквы. Этот стиль называется СamelCase, или “ВерблюжийРегистр”
    Никаких $catname или $CatName , только $catName .

Типы данных в PHP

Всем привет! Сегодня поговорим о типах данных в PHP. Говоря о типах, мы подразумеваем типы каких-либо значений.

В сравнении с другими языками программирования, (например, C/C++/Java), в PHP одной и той же переменной можно присваивать значения разных типов. Поэтому в PHP типы следует относить не к переменной, а к значению. И говорить, например, что в переменной $var находится значение типа integer. Это называется “динамическая типизация” – одна и та же переменная может хранить значения разных типов. Согласитесь, это очень круто.

Давайте рассмотрим следующий код:

<?php
$var = 123;
$var = 'string';
$var = 3.14;

Здесь переменная $var на каждой строке меняет своё значение, при этом у этих значений разные типы. В первом случае – целое число (integer), во втором – строка (string), в третьем – дробное число (float).

Строки могут быть определены с помощью двойных или одинарных кавычек. Но при этом есть разница – в двойных кавычках интерпретатор будет пытаться найти переменные, а внутри одинарных кавычек – нет.
Пример:

<?php
$var = 123;
echo "Значение переменной: $var";

Этот код выведет на экран строку:

Значение переменной: 123

И другой пример:

<?php
$var = 123;
echo 'Значение переменной: $var';

Выведет следующее:

Значение переменной: $var

Как мы видим, внутри одинарных кавычек не был выполнен поиск переменных и интерпретатор вернул нам текст ровно так, как он был определён.
Чтобы вывести значение переменной и при этом использовать одинарные кавычки, можно склеить строки. Этот приём называется конкатенацией строк (от англ. concatenation – сцепление, связывание). Для этого используется оператор " . " (точка) между двумя значениями, который отделён от них пробелами. Пример:

<?php
$var = 123;
echo 'Значение переменной: ' . $var;

Выведет строку:

Значение переменной: 123

Стоит отметить, что при использовании одинарных кавычек работа со строками будет происходить быстрее, так как не будет происходить поиск (или правильнее сказать парсинг) переменных внутри строки.

Давайте теперь рассмотрим код, похожий на тот, что мы только что написали:

<?php
$var = 123;
$string = 'Значение переменной: ' . $var;

В переменной $string сейчас хранится значение типа “строка”. Несмотря на то, что до этого в $var было целое число. Это произошло в результате использования оператора “точка” для конкатенации строк. В результате его использования всегда получится строка. И, как Вы уже, наверное, догадались, тип, который получится в результате какого-либо выражения, будет зависеть от оператора. То есть, при использовании плюса (оператора сложения), всегда будет получаться число.

Пример:

<?php
$x = 1;
echo $x + '2';

Выведет результат:

3

PHP достаточно умён, чтобы автоматически преобразовать строку ‘2’ к числу и выполнить сложение. Таким образом, в зависимости от оператора, операнды будут сначала приведены к нужному типу, а затем над ними будет выполнена операция. Это называется " приведение типов ".
Приведение типа можно сделать и самостоятельно. Делается это с помощью следующей конструкции:

(тип_к_которому_нужно_привести) значение

Например:

<?php
$string = '123';
$numeric = (int) $string;

В переменной $string сейчас строка, а в переменной $numeric – уже целое число. Пока что не будем на этом детально останавливаться, но знать, что это возможно, лишним не будет.

Давайте теперь пробежимся по типам, которые мы уже рассмотрели. Это числа (целые и дробные), строки. Помимо этих есть ещё несколько типов данных. Все мы их рассматривать сейчас не будем, но рассмотрим ещё один простейший тип – boolean (булево значение). У этого типа могут быть только два значения: true и false – “истина” и “ложь” (надеюсь, информатика у всех в школе была?). Этот тип используется для проверки различных условий и в следующем уроке мы рассмотрим его применение более детально. Это всё, что касается типов.

Операторы в PHP

Операторы - одна из важнейших и базовых тем. Почти все выражения так или иначе содержат их в себе. Без операторов в PHP не было бы возможности делать что-либо с данными вообще, так же, как, например, в математике. Поэтому отнеситесь к данной теме серьёзно, а в конце обязательно сделайте домашнее задание - только практика, только хардкор.

Но прежде чем перейти к изучению операторов, я предлагаю изучить функцию var_dump(). Она позволяет вывести тип и значение чего-либо.

Например, выражения:

<?php
var_dump(5/2);

Результат:

float 2.5

Или же переменной:

<?php
$result = 2 < 4;
var_dump($result);

Результат:

boolean true

2 меньше 4. Результат – истина. Всё верно.

Поздравляю, теперь мы в любой момент можем узнать, что находится в переменной, или же сразу узнать результат какого-либо выражения. Давайте теперь вернёмся к нашей основной теме урока.
Тема операторов очень плотно переплетается с темой типов данных. Как мы с вами уже говорили на прошлом уроке, тип данных, который получится в результате какого-либо выражения, будет зависеть от оператора. И, например, результатом сложения при использовании оператора плюса всегда будет число.

Приоритет операторов

Начнём с того, что операторы имеют разный приоритет. Как, например, в математике: оператор умножения будет более приоритетным по сравнению с оператором сложения:

<?php
$result = 2 + 2 * 2;
var_dump($result);

Результат:

int 6

Приоритетом можно управлять с помощью круглых скобок, например:

<?php
$result = (2 + 2) * 2;
var_dump($result);

Ну и тут думаю всё понятно:

int 8

В целом приоритеты операторов довольно предсказуемы.
Приоритет всех операторов в PHP можно посмотреть в официальной документации.

Типы операторов в PHP

А теперь давайте рассмотрим разные типы операторов

Арифметические операторы

Тут нас ждут знакомые со школьной скамьи операторы:

<?php

$a = 6;
$b = 3;

// Сложение
var_dump($a + $b);

// Вычитание
var_dump($a - $b);

// Умножение
var_dump($a * $b);

// Деление
var_dump($a / $b);

// Остаток от деления
var_dump($a % 4);

// Возведение в степень
var_dump($a ** 2);

Результат:

int 9
int 3
int 18
int 2
int 2
int 36

Многие впадают в ступор от оператора остатка от деления. Тут всё просто. В нашем случае мы вычисляем остаток от деления 6 на 4. Нацело не делится, целая часть – 1, и 2 в остатке. Ещё несколько аналогичных примеров для понимания:

<?php
var_dump(5 % 2);
var_dump(17 % 12);
var_dump(8 % 4);

Результат:

int 1
int 5
int 0

Думаю, арифметические операторы больше не требуют дополнительных разъяснений.

Оператор присваивания

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

<?php
$a = 55;

Ок, тут всё просто. А как на счёт такого:

<?php
$result = ($x = 5) * 2;

Здесь переменной $x присвоили значение 5, а затем умножили на 2 и положили результат выражения в переменную $result. Да, в PHP так тоже можно, хоть и не приветствуется, так как код выглядит довольно запутанно.

Помимо этого есть так называемые сокращенные, комбинированные операторы присваивания.
Например, в комбинации с оператором сложения:

<?php

$x = 5;
$y = 7;

$y += $x;

var_dump($y);

Результат:

int 12

Здесь

$y += $x

можно было бы записать как

$y = $y + $x

Таким образом, если что-то совершается с левым операндом в исходном виде, то можно использовать эти сокращённые варианты. И да, это применяется и выглядит весьма элегантно, стоит к ним привыкать уже сейчас. Давайте рассмотрим ещё несколько примеров:

<?php

$x = 6;
$y = 3;

$x /= $y;

var_dump($x);

Результат:

int 2

И с конкатенацией строк:

<?php

$hello = 'Hello ';

$hello .= 'world!';

var_dump($hello);

Результат:

string ‘Hello world!’ (length=12)

Ок, идём дальше.

Операторы сравнения

Ну тут из названия понятно, что это за операторы и для чего они предназначены. Результатом их работы всегда будет булево значение (true или false).

Начнём с операторов равенства/неравенства:

<?php

$x = 2;
$y = '2';

var_dump($x == $y); //проверка на равенство
var_dump($x === $y); //проверка на тождественное равенство
var_dump($x != $y); //проверка на неравенство
var_dump($x !== $y); //проверка на тождественное неравенство

Результат:

boolean true
boolean false
boolean false
boolean true

Давайте поясню. Оператор == приводит операнды к одному типу и после сравнивает их значения. Так строка ‘2’ была преобразована к числу и значения оказались равными.
Оператор тожественного равенства === не выполняет приведения типов и сравнивает сначала то, что типы значений идентичны, например, целые числа, а затем сравнивает их значения. И если они одинаковы, то только в таком случае возвращает true.

Например:

<?php

$x = 2;
$y = 2;

var_dump($x === $y);

Результат:

boolean true

Оператор неравенства != приводит типы к одному и сравнивает значения. Если они не равны, вернёт true, иначе – false.
Оператор тождественного неравенства !== сначала сравнивает типы, если они не идентичны, например, строка и число, то вернёт true, иначе сравнит их значения. Если они не равны, вернёт true, иначе – false.

Также к операторам сравнения относятся:

<?php

$x = 2;
$y = 4;

var_dump($x > $y); // $x больше $y
var_dump($x < $y); // $x меньше $y
var_dump($x >= $y); // $x больше или равно $y
var_dump($x <= $y); // $x меньше или равно $y

Результат:

boolean false
boolean true
boolean false
boolean true

Тут всё очевидно, не будем задерживаться.

Spaceship

А теперь рассмотрим оператор сравнения, который появился в PHP7. Это спейсшип (или космический корабль) <=> . Похож на корабль штурмовиков из звёздных войн, не так ли?

Логика у этого оператора следующая:
$a <=> $b
Если $a > $b, вернёт 1
Если $a == $b, вернёт 0
Если $a < $b, вернёт -1

Давайте рассмотрим пример:

<?php

var_dump(2 <=> 4);
var_dump(2 <=> 2);
var_dump(5 <=> 3);

Результат:

int -1
int 0
int 1

Данный оператор был введён для использования в функциях сортировки. Эту тему мы пока поднимать не будем, просто знайте, что вот такой интересный оператор появился в последней версии PHP.

Инкремент и декремент

Зачастую в разных алгоритмах приходится увеличивать и уменьшать целые числа на единицу.
Для этого существуют специальные операторы инкремента и декремента.
Варианты могут быть самыми разными:

  • $i++ - постфиксный инкремент, возвращает текущее значение $i, а затем увеличивает значение на единицу
  • $i-- - постфиксный декремент, возвращает текущее значение $i, а затем уменьшает значение на единицу
  • ++$i – префиксный инкремент, сначала увеличивает значение переменной $i на единицу, а затем возвращает результат
  • –$i – префиксный декремент, сначала уменьшает значение переменной $i на единицу, а затем возвращает результат

Давайте рассмотрим несколько простых примеров:

<?php

$i = 5;

$x = $i++; // Сначала переменной $x присвоили текущее значение $i (5), затем $i увеличили на 1 (6)
$y = ++$i; // Сначала переменную $i увеличим на 1 (7), затем присвоили новое значение переменной $y (7)
$z = $i--; // Сначала $z присвоили значение $i (7), затем уменьшили $i на 1 (6)

var_dump($x);
var_dump($y);
var_dump($z);
var_dump($i);

Результат:

int 5
int 7
int 7
int 6

С инкрементом и декрементом на этом всё. Идём дальше.

Логические операторы

А теперь поговорим об одном из самых важных типов операторов, а именно – логических. Эти операторы используются для вычисления условий. Результатом такого оператора всегда будет истина или ложь. При этом операндами так же выступают истина или ложь.
Давайте перечислим их:

  • && - логическое И, вернёт true, только если оба операнда истинны (true)
  • || - логическое ИЛИ, вернёт true, если хотя бы один из операндов является истинным
  • ! – ОТРИЦАНИЕ, возвращает true, если операнд – false, и наоборот. Применяется если нужно инвертировать условие, зачастую это очень кстати.
  • xor – исключающее ИЛИ, вернёт true, только если один из операторов true, а другой – false

Давайте посмотрим на примере:

<?php

var_dump(true && true); // Результат: true
var_dump(true && false); // Результат: false
var_dump(true || true); // Результат: true
var_dump(true || false); // Результат: true
var_dump(false || true); // Результат: true
var_dump(!true); // Результат: false
var_dump(!false); // Результат: true
var_dump(false xor true); // Результат: true
var_dump(true xor true); // Результат: false
var_dump(true xor false); // Результат: true
var_dump(false xor false); // Результат: false

А теперь давайте более интересно – определим, является ли число чётным и при этом оно больше 10. Для того, чтобы проверить на чётность – достаточно взять остаток от деления на 2 и сравнить с нулём. Если будет 0, то число чётное. Давайте напишем первое вычисление:

<?php

$x = 14;

$isEven = $x % 2 == 0;

var_dump($isEven); // true

А теперь второе:

<?php

$x = 14;

$isEven = $x % 2 == 0;

var_dump($isEven); // true

$isMoreThan10 = $x > 10;

var_dump($isMoreThan10); // true

Остаётся сделать так, чтобы выполнились оба условия. Воспользуемся логическим И:

<?php

$x = 14;

$isEven = $x % 2 == 0;

var_dump($isEven);

$isMoreThan10 = $x > 10;

var_dump($isMoreThan10);

$isEvenAndMoreThan10 = $isEven && $isMoreThan10;

var_dump($isEvenAndMoreThan10);

Вычисление можно было бы выразить и одной строкой:

<?php

$x = 14;

$isEvenAndMoreThan10 = $x % 2 == 0 && $x > 10;

Однако, согласитесь, первый вариант разбит по пунктам и более понятен. Я хочу, чтобы Вы поняли. Ваш код не должен занимать как можно меньше места. Он должен быть понятен. Можно сказать, будет очень неплохо, если он будет скучен. Он должен легко читаться программистами. В первом случае всё очевидно: выяснили, что число чётное, что оно больше 10, и решили, что оба эти условия выполняются одновременно. Вот как-то так должен мыслить человек, читающий Ваш код.

И ещё, если операнды не являются булевыми значениями, они будут автоматически приведены к true или false. Оставим это на самостоятельное ковыряние – в домашнем задании будет пункт, касательно этого замечания. Обязательно выполните его.

Строковый оператор конкатенации

Да-да, для строк существует только один оператор – для их объединения в одну: оператор конкатенации. Он представляет из себя точку и его использование выглядит следующим образом:

<?php

$string1 = 'Привет';
$string2 = 'мир!';

echo $string1 . ', ' . $string2;

Результат:

Привет, мир!

На этом заканчивается наш урок по операторам. Обязательно выполните домашку, без неё дальше не пойдёт.

Домашнее задание

  • Самостоятельно изучите официальную документацию на тему приоритетов операторов.
  • С помощью функции var_dump() получите результаты следующих выражений. Если что-то непонятно - спрашивайте в комментариях.
  • !1
  • !0
  • !true
  • 2 && 3
  • 5 && 0
  • 3 || 0
  • 5 / 1
  • 1 / 5
  • 5 + ‘5string’
  • ‘5’ == 5
  • ‘05’ == 5
  • ‘05’ == ‘5’

Условия в PHP

Всем привет! Вот и очередной урок по PHP подоспел. Сегодняшняя тема – одна из самых любимых у тех, кто начинает программировать. Ещё бы, ведь условия в PHP – это то, что позволяет нам составлять различные алгоритмы. Именно в зависимости от условий программа будет вести себя так или иначе. И именно благодаря им мы можем получать разный результат при разных входных данных. В PHP имеются несколько конструкций, с помощью которых можно реализовать условия. Все они используются, и имеют свои преимущества в разных ситуациях, или, если хотите – условиях. Кругом одни условия, не так ли? Так. Никто ведь не будет спорить, что в реальной жизни в зависимости от обстоятельств мы поступаем по-разному. В программировании это не менее важно и сейчас мы этому научимся.

Как вы должны помнить из прошлого урока, в PHP, в зависимости от оператора, операнды приводятся к определённому типу. Для операторов условий в PHP действуют те же правила, и здесь операнд всегда приводится к булевому значению. В случае, если это значение true , то считаем, что условие выполнено, а в случае, если false – то условие не выполнено. В зависимости от того, выполнено ли условие, мы можем делать или не делать какие-либо действия. И тут я предлагаю рассмотреть первый условный оператор – if .

Условный оператор if

Это самый простой, и самый часто используемый оператор. В общем случае конструкция выглядит следующим образом:

<?php

if (условие) {
    код, который нужно выполнить, если условие выполнено;
}

А в реальной жизни использование оператора if выглядит следующим образом:

<?php

if (true) {
    echo 'Условие выполнено';
}

Здесь мы явно передали оператору значение true . Разумеется, это абсолютно бессмысленно. Давайте с помощью условия будем определять числа больше 10. Это довольно просто:

<?php

$x = 15;

if ($x > 10) {
    echo 'Число больше 10';
}

И после запуска мы увидим результат:

Число больше 10

Конструкция if-else

А можно ли сделать так, чтобы, когда условие не выполнилось, выполнился другой код? Конечно можно! Для этого вместе с оператором if используют оператор else (по-русски - иначе). Он пишется после фигурных скобок, в которые заключается код, выполняющийся при выполненном условии. И выглядит конструкция следующим образом:

<?php

$x = 15;

if ($x > 10) {
    echo 'Число больше 10';
} else {
    echo 'Число меньше либо равно 10';
}

Здесь опять же на экран будет выведено сообщение:

Число больше 10

Однако если мы изменим входные данные, и переменной $x в самом начале присвоим значение 8 , то выведется сообщение:

Число меньше либо равно 10

Попробуйте сделать это прямо сейчас.

Конструкция if-elseif-else: несколько условий

В случае, если вам нужно проверить несколько условий, после оператора if добавляется ещё и оператор elseif . Он проверит условие, только если не выполнится первое условие. Например:

<?php

$x = 10;

if ($x > 10) {
    echo 'Число больше 10';
} elseif ($x == 10) {
    echo 'Число равно 10';
}

В данном случае, на экран будет выведено:

Число равно 10

И да, после этого оператора можно добавить else . Код внутри него будет выполнен, если не выполнилось ни одно из условий:

<?php

$x = 9;

if ($x > 10) {
    echo 'Число больше 10';
} elseif ($x == 10) {
    echo 'Число равно 10';
} else {
    echo 'Число меньше 10';
}

Результат этого кода, я полагаю, объяснять не нужно. Да, кстати, возможен целый список из elseif -ов. Например, такой:

<?php

$x = 3;

if ($x <= 0) {
    echo 'Число меньше либо равно 0';
} elseif ($x == 1) {
    echo 'Число равно 1';
} elseif ($x == 2) {
    echo 'Число равно 2';
} else {
    echo 'Число не подошло ни под одно из условий';
}

Приведение к boolean

Помните, в уроке про типы данных в PHP мы с вами научились явно приводить значения к какому-либо типу. Например:

<?php

$x = (boolean)3;

var_dump($x);

Результатом будет true .
Работающее так же, только неявное преобразование, всегда происходит в условии. Например, следующее условие:

<?php

if (3) {
    echo 'Условие выполнено';
}

Выполнится успешно, так как число 3 будет преобразовано к true . К false будут приводиться следующие значения:

  • ‘’ (пустая строка)
  • 0 (число 0)

Таким образом, любое ненулевое число и ненулевая строка будут преобразованы в true и условие выполнится. Исключение – строка, состоящая из одного нуля:

'0'

Она также будет преобразована к false .

Я затронул эту тему с приведением к boolean в домашнем задании к этому уроку. Обязательно его выполните. А сейчас давайте перейдём к следующему условному оператору.

Оператор switch

Помимо конструкции if-else есть ещё один оператор условия. Это – switch . Это очень интересный оператор, требующий запоминания нескольких правил. Давайте для начала посмотрим, как он выглядит на следующем примере:

<?php

$x = 1;

switch ($x) {
    case 1:
        echo 'Число равно 1';
        break;
    case 2:
        echo 'Число равно 2';
        break;
    default:
        echo 'Число не равно ни 1, ни 2';
}

Сначала может показаться, что этот оператор довольно сложный. Однако, если разобраться, то всё становится понятно. В операнде switch указывается некоторое выражение. В нашем случае, это переменная $x , а точнее её значение - 1 .

В фигурных скобках мы перечисляем операторы case , после которых указываем значение, с которым сравнивается значение операнда switch . Сравнение происходит нестрогое, то есть как будто используем оператор ==. И если условие выполнилось, то выполняется код, указанный после двоеточия. Если же ни одно из условий не выполнилось, то выполняется код из секции default , которой в общем-то может и не быть, и тогда ничего выполняться не будет. Обратите внимание, внутри каждой секции case , в конце мы прописали оператор break . Это делается для того, чтобы после выполнения кода в случае выполнения условия не продолжилась проверка условий. То есть, если бы не было break в конце секции case 1 , то после того, как вывелся бы текст

Число равно 1

продолжило бы выполняться условие сравнения с 2 , а затем бы выполнился и код в секции default . Не забывайте писать break !

Сравнение switch с if

Вообще, этот код можно было бы записать и с помощью конструкции if-elseif-else :

<?php

$x = 1;

if ($x == 1) {
    echo 'Число равно 1';
} elseif ($x == 2) {
    echo 'Число равно 2';
} else {
    echo 'Число не равно ни 1, ни 2';
}

Но в виде конструкции switch-case код в конкретно этом случае выглядит проще. И вот почему:

  1. мы сразу видим, что конкретно мы сравниваем (переменную $x ) и понимаем, что сравниваем в каждом условии именно это значение, а не какое-либо ещё;
  2. глазу удобнее воспринимать то, с чем сравниваем – секции case 1 , case 2 визуально воспринимаются легче, сравниваемое значение заметнее.

И снова про switch

И я ещё не всё сказал про switch - можно писать несколько case -ов подряд, тогда код выполнится при условии, что выполнен хотя бы один из них. Например:

<?php

$x = 2;

switch ($x) {
    case 1:
    case 2:
        echo 'Число равно 1 или 2';
        break;
    case 5:
        echo 'Число равно 5';
        break;
    default:
        echo 'Число не равно ни 1, ни 2, ни 5';
}

Согласитесь, это может быть удобно.

Хорошо, давайте пройдёмся по особенностям оператора switch , о которых нужно помнить всегда.

  1. break прерывает набор условий, не забывайте указывать его;
  2. секция default будет выполнена, если не выполнилось ни одно из условий. Она может и вовсе отсутствовать;
  3. несколько case -ов могуть быть записаны подряд, тогда код в секции выыполнится при выполнении хотя бы одного из условий.

Немного практики

Ну что, запомнили операторы условий? Давайте закрепим на практике более реальными примерами.

Чётное или нечётное

Вот один из примеров – нужно определить, чётное ли число или нет. Для этого нам нужно проверить, что остаток от деления на 2 будет равен 0 . Подробнее об операторах читайте тут. Давайте сделаем это:

<?php

$x = 2;

if ($x % 2 == 0) {
    echo 'Число чётное';
} else {
    echo 'Число нечётное';
}

Попробуйте самостоятельно изменить значение переменной $x . Круто, да? Оно работает!

Модуль

Давайте теперь научимся вычислять модуль числа. Если число больше или равно нулю, то нужно вывести само это число, если меньше – заменить знак с минуса на плюс.

<?php

$x = -2;

if ($x >= 0) {
    echo 'Модуль числа: ' . $x;
} else {
    echo 'Модуль числа: ' . -$x;
}

Результат:

Модуль числа: 2

Как мы видим, всё успешно отработало.

Тернарный оператор

Помимо этого, в PHP есть ещё один оператор, который представляет собой сокращённую форму конструкции if-else . Это тернарный оператор. При этом он возвращает разные результаты, в зависимости от того, выполнено ли условие или нет. В общем виде его использование выглядит следующим образом:

условие ? результат_если_true : результат_если_false

Или на примере того же нахождения модуля:

<?php

$x = -2;

$mod = $x >= 0 ? $x : -$x;

echo 'Модуль: ' . $mod;

Результат:

Модуль: 2

Круто, да? Тернарный оператор – очень элегантно вписывается при решении таких вот простеньких задачек.

И ещё немного практики

Условия можно помещать внутрь друг друга и вообще, чего с ними только можно не делать. Например:

<?php

$x = 105;

if ($x > 0) {
    if ($x >= 100) {
        echo 'Число больше либо равно 100';
    } else {
        echo 'Число больше 0 но меньше 100';
    }
} else {
    echo 'Число меньше либо равно 0';
}

Итог

Друзья, надеюсь вам понравился урок. Если это так – буду рад, если вы поделитесь им в социальных сетях или расскажете друзьям. Это лучшая поддержка проекта. Спасибо тем, кто это делает. Если у вас возникли какие-то вопросы или замечания – напишите об этом в комментариях. А сейчас – все быстренько делаем домашнее задание, там ещё больше интересных примеров с условиями. Всем пока!

Домашнее задание

Попробуйте следующие условия:

  • if (‘string’) {echo ‘Условие выполнилось’;}
  • if (0) {echo ‘Условие выполнилось’;}
  • if (null) {echo ‘Условие выполнилось’;}
  • if (5) {echo ‘Условие выполнилось’;}

Объясните результат.
С помощью тернарного оператора определите, является ли число чётным или нечётным и выведите результат.

Функции в PHP

Всем привет! В этом уроке мы познакомимся с таким понятием как функции в языке PHP. Функции – вещь довольно простая. Она представляет собой кусок кода, который принимает определенные параметры и на выходе возвращает какой-либо результат. Можно написать функцию один раз, а затем использовать её в различных местах. Таким образом вам не нужно будет дублировать код, если что-то нужно сделать дважды, или трижды, или сколько угодно раз. Вообще, функции в PHP можно сравнить с функциями в математике.

В PHP изначально содержится огромное число встроенных функций. Это очень сильная сторона этого языка – почти под любую вашу потребность имеется уже готовая функция. Давайте попробуем несколько функций на практике.

Например, нам нужен косинус числа 3.14. Легко! Для этого в PHP есть функция cos.

<?php

echo cos(3.14);

Результат:

-0.99999873172754

Есть очень много функций для работы со строками. Например, можно в строке заменить одни символы другими, для этого есть функция str_replace. Например, давайте в строке “abracadabra” заменим все буквы “a” на “o” .

<?php

$string = 'abracadabra';

echo str_replace('a', 'o', $string);

Результат:

obrocodobro

Документация по стандартной библиотеке функций ( SPL ) доступна на официальном сайте - http://php.net/manual/ru/funcref.php. Большинство из них имеет описание на русском языке. Разумеется, все их запомнить невозможно, однако нужно уметь их находить. И это, как правило, не составляет труда. Например, если вбить в google “заменить символы в строке php” то в выдаче будет ссылка на официальную документацию, там и смотрите.

Поиск функций в PHP

Вообще, гуглить и брать уже готовый код – это хороший подход, который экономит ваше время. В этом нет ничего плохого – скорее всего вы найдёте лучшее решение задачи, чем то, которое бы написали сами. Научитесь на готовых примерах, а со временем запомните наиболее частые подходы для разных случаев. Здесь главное – постоянная практика.

Пользовательские функции: пишем свою первую функцию

Думаю, о том, что такое функции и где найти уже готовые, я объяснил. Но самое крутое то, что функции можно определять самому! В целом определение любой функции выглядит следующим образом:

function имяФункции (аргумент1, аргумент2)
{
    какие-то действия;
    return результат;
}

У функции обязательно должно быть имя. У всех функций должны быть разные имена и имя вашей функции не может называться так же, как и встроенная в PHP функция . Аргументов может быть сколько угодно, в том числе и 0. Функция может что-то возвращать, для этого перед результатом пишется слово return . После него функция завершает свою работу. А может и не возвращать, а, например, изменять свои аргументы, или выводить информацию на экран. Именуются функции так же, как и переменные - camelCase`ом. Подробнее об этом я писал тут - https://webshake.ru/post/726. Именовать их нужно так же осмысленно – то что функция делает, то и нужно писать в имени .

Давайте рассмотрим пример создания простейшей функции в PHP. Пусть она принимает на вход два числа и возвращает их сумму.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

Окей, функцию написали, теперь можно её вызвать и посмотреть на результат её работы.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

$a = 5;
$b = 10;

echo getSum($a, $b) . '<br>';
echo getSum(-3, 4);

Результат:

15
1

Как мы видим, функция успешно отработала. Вот так, написав её лишь один раз мы можем передавать в неё разные аргументы, и получать разные значения. Использовать функцию можно только после кода её определения!

Области видимости

Давайте теперь поговорим об области видимости функции. Тут на самом деле всё просто, и всё сводится к тому, что переменные внутри функции недоступны извне и называются локальными . После завершения работы функции все объявленные внутри неё переменные перестанут существовать. При этом переменные за пределами функции называются глобальными и недоступны внутри функции . Таким образом, можно внутри функции использовать такие же имена переменных, как и снаружи, но при этом это будут совершенно разные переменные.

<?php

function getSum($x, $y)
{
    return $x + $y;
}

$x = 3;
$y = 5;

echo getSum($x, $y);

Данный код абсолютно рабочий. Здесь переменные $x и $y внутри функции getSum живут сами по себе, а переменные с такими же именами за пределами функции – отдельно, и они ничего друг о друге не знают. При вызове функции значение передаваемого аргумента будет скопировано в локальную переменную, а после выхода из функции это значение будет удалено. То есть здесь при вызове getSum мы просто копируем значения 3 и 5 в локальные переменные $x и $y . С этого момента внутри функции внешние переменные перестают существовать, и она знает только о своих переменных.

Параметры функции: передача аргументов по ссылке и по значению

До сих пор в рассматриваемых нами случаях аргументы в функцию передавались по значению. Это значит, что при вызове функции, значение, передаваемое в качестве аргумента, просто копировалось в локальную переменную.

Передача параметров по ссылке

Однако можно передать аргумент по ссылке. Делается это при помощи знака & перед именем аргумента.

function func(&$x)

При этом не происходит копирования значения в локальную переменную. Появляется ещё одна связь для этого же значения, но с другим именем. И теперь, изменяя значение этой переменной внутри функции, мы будем изменять исходное, переданное значение. Давайте рассмотрим пример передачи значения по ссылке.

<?php

function plus5(&$x)
{
    $x = $x + 5;
}

$a = 3;

plus5($a);

echo $a;

Результат:

8

То есть для значения переменной $a внутри функции появилось ещё одно имя - $x . Сейчас оба этих имени указывают на одно и то же значение. И если мы изменим значение переменной внутри функции, то оно изменится также и снаружи!

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

<?php

function plus5($x)
{
    $x = $x + 5;
}

$a = 3;

plus5($a);

echo $a;

Будет выведено:

3

Здесь при вызове функции значение переменной $a было просто скопировано в локальную переменную $x . Внутри функции мы изменили $x , прибавив к нему число 5 , а затем работа функции была завершена. Локальная переменная $x перестала существовать, а мы никак не повлияли на переменную $a .

Функции, в которых все аргументы передаются по значению, называются чистыми. Стоит по возможности использовать их, так как в абсолютном большинстве случаев передача значений по ссылкам не требуется и приводит к запутанности кода.

Начинаем использовать тайп-хинтинг (type hinting) в PHP 7

В PHP 7 в функциях появилась возможность указывать типы аргументов, в том числе для скалярных типов (строки, числа). При этом при передаче аргумента в функцию, передаваемое значение будет автоматически приведено к нужному типу. Давайте перепишем нашу функцию, учитывая современные возможности PHP 7.

<?php

function getSum(int $x, int $y)
{
    return $x + $y;
}

Вот так, теперь при передаче любых значений в функцию, они автоматически будут приведены к числам. Давайте это проверим – вставим вызов функции var_dump внутри нашей функции, и посмотрим, что получится.

<?php

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(5, 10);

Результат:

int 5
int 10
15

Вполне ожидаемо, скажете вы. Мы ведь передали в функцию целые числа, и даже если бы у аргументов не было приведения типов, то там точно так же были бы целые числа. И будете правы. Но давайте попробуем в качестве одного из аргументов передать число с плавающей запятой.

<?php

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

После выполнения мы увидим следующее:

int 12
int 10
22

То есть в тот момент, когда аргумент пришёл в функцию, он был уже нужного типа . Давайте попробуем убрать указание типа из аргумента:

<?php

function getSum($x, $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

Теперь дробное число не будет приведено к целому, и мы получим другой результат:

float 12.5
int 10
22.5

В этом курсе мы всегда будем использовать указание типов. Это помогает писать более строгий код и позволяет допускать меньше ошибок. Посудите сами – если мы работаем с конкретным типом, мы более уверены в том, как будет работать тот или иной код.

Строгая типизация

Как я уже сказал, по умолчанию значение аргумента будет автоматически приведено к указанному типу. Однако в PHP есть возможность указать явно, что аргумент, передаваемый в функцию, будет иметь конкретный тип. Это делается с помощью директивы:

declare(strict_types=1);

Она указывается в начале PHP-файла. Наш код примет следующий вид:

<?php
declare(strict_types=1);

function getSum(int $x, int $y)
{
    var_dump($x);
    var_dump($y);

    return $x + $y;
}

echo getSum(12.5, 10);

При этом, если его сейчас запустить, то произойдёт ошибка с типом TypeError .
Ошибка при передаче некорректного типа

Как тут написано, первый аргумент, переданный в getSum() обязан быть типа integer , а передан с типом float . Это и есть строгая типизация в PHP. Использовать её в рамках данного курса мы не будем, да и в профессиональной разработке на PHP этот функционал пока не используют. Но не рассказать о ней я не мог, вполне возможно, что это могут спросить при собеседовании на работу. А сейчас убираем строку _declare(strict types=1); из нашего кода и идём дальше.

Функции без аргументов

Как я говорил, функция может вообще не иметь аргументов. Таковой, например, является стандартная функция rand() – она просто возвращает случайное число.

Давайте её попробуем в действии:

<?php

echo 'Случайное число: ' . rand();

Результат:

Случайное число: 9582

Давайте запустим ещё раз этот же самый код:

Случайное число: 7324

Работает. А давайте теперь напишем свою функцию, которая тоже не принимает аргументов, и возвращает синус случайного числа:

<?php

function getSinOfRandom()
{
    return sin(rand());
}

echo 'Синус случайного числа: ' . getSinOfRandom();

Результат:

Синус случайного числа: 0.6586666790617

Функция внутри функции

Давайте теперь рассмотрим, что ещё позволяют нам делать функции. Функции в PHP можно вызывать внутри других функций. Давайте приведём абсолютно простейший пример. Например, нам нужно найти сумму косинусов двух чисел. Напишем для этого функцию:

<?php

function getSumOfCos(float $x, float $y)
{
    $cosX = cos($x);
    $cosY = cos($y);
    return $cosX + $cosY;
}

echo getSumOfCos(1.44, 2);

Здесь мы использовали функцию cos() из стандартной библиотеки внутри нашей собственной функции. А можно ли вызывать свои же функции из других своих функций? Да легко!

<?php

function getSum(float $x, float $y)
{
    return $x + $y;
}

function getSumOfCos(float $x, float $y)
{
    $cosX = cos($x);
    $cosY = cos($y);
    return getSum($cosX, $cosY);
}

echo getSumOfCos(1.44, 2);

Здесь мы определили 2 разные функции, и во второй начали использовать первую. Разумеется, эти примеры довольно искусственны. И вы можете подумать, что использовать здесь функции излишне. Ведь можно же просто заменить этот код следующим выражением:

<?php

echo cos(1.44) + cos(2);

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

<?php

function getMax(int $x, int $y)
{
    if ($x > $y) {
        return $x;
    } else {
        return $y;
    }
}

$a = 5;
$b = 8;

echo 'Наибольшее число: ' . getMax($a, $b);

Результат:

Наибольшее число:8

Код данной функции можно упростить, так как если $x не больше $y , то мы в любом случае вернём $y . Поэтому можно убрать блок else :

<?php

function getMax(int $x, int $y)
{
    if ($x > $y) {
        return $x;
    }

    return $y;
}

$a = 5;
$b = 8;

echo 'Наибольшее число:' . getMax($a, $b);

Результат будет таким же. Так происходит, как я уже говорил, что как только в функции выполнится return , значение будет тут же возвращено, а функция завершит свою работу.

Давайте передадим первым аргументом большее число:

<?php

function getMax(int $x, int $y)
{
    if ($x > $y) {
        return $x;
    }

    return $y;
}

$a = 10;
$b = 8;

echo 'Наибольшее число: ' . getMax($a, $b);

Результат:

Наибольшее число: 10

Выполнилось первое условие и вызвался return $x . Всё, до return $y дело не дошло.
Упрощение заключается в том, что чем меньше уровней вложенности в коде, тем проще его читать и понимать. Видите, как плотно пересекается весь изученный материал? В данном случае с темой условий в PHP.

Рекурсивные функции

Рекурсия в картинках

Ох, чувствую, сейчас повеселимся. Осторожно! Если при чтении этого раздела у вас начнут закипать мозги - переходите к следующему уроку, рекурсию можно освоить и в конце курса. Не парьтесь, в общем, если не будет получаться, вы такие не одни =)

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

Например, нам нужно возвести число в степень. Предположим, у нас для этого есть определённая функция. Назовём её power . И пусть она принимает 2 аргумента:

  • число, которое нужно возвести;
  • степень, в которую нужно возвести.

То есть, для того, чтобы возвести число 2 в третью степень, нам нужно вызвать эту функцию следующим образом:

power(2, 3)

Согласитесь, что power(2, 3) равносильно 2 * power(2, 3 - 1) . То есть мы можем умножить число, возводимое в степень, на вызов этой функции, и уменьшить при этом степень на единицу.

Таким образом, получается, что мы можем вызывать эту же функцию с некоторыми дополнительными операциями.

Получаем, что

power($x, $n) = $x * power($x, $n – 1)

Тогда для возведения 2 в степень 3 получим:

  1. power(2, 3) = 2 * power(2, 2)
  2. power(2, 2) = 2 * power(2, 1)
  3. power(2, 1) = 2

Число в первой степени равно самому этому числу. Здесь нам нужно остановиться.

Давайте реализуем это с помощью кода:

<?php

function power(int $x, int $n)
{
    // Если сейчас степень равна единице, то возвращаем само это число
    if ($n == 1) {
        return $x;
    }

    // В остальных случаях - умножаем число на возведённое в степень n - 1 и возвращаем его
    return $x * power($x, $n - 1);
}

echo power(2, 3);

Да, функция будет вызывать сама себя. Таким образом, можно прийти к тому, что рекурсия полезна, когда вычисление функции можно свести к её более простому вызову, а его – ещё к более простому, и так далее, пока мы не достигнем в аргументах какого-то конечного значения (в нашем примере - числа 1). Чтобы понять, как всё работает пошагово, можно добавить вызов var_dump в начале функции и посмотреть, какие аргументы ей передаются на каждом из шагов.

<?php

function power($x, $n)
{
    var_dump($x, $n);
    // Если сейчас степень равна единице, то возвращаем само это число
    if ($n == 1) {
        return $x;
    }

    // В остальных случаях - умножаем число на возведённое в степень n - 1 и возвращаем его
    return $x * power($x, $n - 1);
}

echo 'Результат: ' . power(2, 3);

Вывод получится следующим:

int 2 int 3
int 2 int 2
int 2 int 1
Результат: 8

Таким образом, мы видим, что функция была вызвана трижды, и мы видим, какими были значения аргументов на каждом вызове. Надеюсь, тут всё понятно. Если же нет (а при изучении рекурсии это происходит довольно часто) – пишите ваши вопросы в комментариях, помогу. А ещё можете пошагово разбирать ход программы на листочке – тоже часто помогает.

Давайте для закрепления разберём ещё один пример с рекурсией. Например, мы будем передавать в функцию какое-то число $n , а она будет считать сумму всех чисел от единицы до этого числа. Назовём эту функцию getSumOfNumbersFromZero($n) .

Предположим, нам нужно посчитать сумму всех чисел от 1 до 5 . Тогда вызов функции будет следующим:

getSumOfNumbersFromZero(5);

Как можно догадаться, этот вызов можно представить как

5 + getSumOfNumbersFromZero(4)

Или в общем случае

getSumOfNumbersFromZero($n) = $n + getSumOfNumbersFromZero($n - 1)

И так до тех пор, пока $n не станет равен 1 .

Давайте реализуем это с помощью рекурсивной функции:

<?php

function getSumOfNumbersFromZero(int $n)
{
    // Если сейчас 1, то просто возвращаем 1
    if ($n == 1) {
        return 1;
    }

    // В остальных случаях - прибавляем текущее число к сумме всех предыдущих
    return $n + getSumOfNumbersFromZero($n - 1);
}

echo 'Результат: ' . getSumOfNumbersFromZero(5);

Запускаем:

Результат: 15

Всё верно! Ну, хватит рекурсии, а то я уже слышу, как у вас закипают мозги.
Очень надеюсь, что вам понравился урок. Если это так – буду рад, если вы поделитесь им в социальных сетях или расскажете друзьям. Это лучшая поддержка проекта. Спасибо тем, кто это делает. Если у вас возникли какие-то вопросы или замечания – напишите об этом в комментариях. А сейчас – делаем домашнее задание, варианты ваших решений можете писать в комментариях, я их проверю и скажу, всё ли правильно. Всем пока!

Домашнее задание

  • Напишите функцию, которая будет принимать на вход 3 аргумента с типом float и возвращать минимальное значение.
  • Напишите функцию, которая принимает на вход два аргумента по ссылкам и умножает каждый из них на 2.
  • Напишите функцию, считающую факториал числа (произведение целых чисел от единицы до переданного). Ну разумеется, тут никуда без рекурсии =)
  • Напишите функцию, которая будет выводить на экран целые числа от 0 до переданного значения. И да, тут тоже не обойтись без рекурсии, это задание повышенной сложности. Кто справится и первым напишет верное решение в комментах – тот красавчик и получит от проекта небольшой бонус. UPD: первым справился человек с ником omk . Вариант его решения вы можете увидеть в комментариях.

Отладка PHP-кода с помощью Xdebug в PHPStorm

Отладка программы – это процесс, в ходе которого обнаруживают и устраняют баги. Для этого нам нужно знать, например, значения переменных на каждом шаге выполнения программы, или смотреть выполнилось ли условие, или даже погружаться в работу рекурсивных функций.

Собственно, так как многим рекурсия показалась сложной, то я решил сделать урок по отладке кода на PHP. В этой статье мы рассмотрим настройку отладки с помощью PHP-расширения Xdebug, а производить отладку мы будем в уже известной нам IDE PHPStorm.

Настройка отладки PHP в OpenServer

Первым делом давайте включим расширение Xdebug в файле конфигурации PHP (php.ini). Для этого идём в меню OpenServer -> Дополнительно -> Конфигурация -> PHP.

Конфигурация PHP в OpenServer

Здесь нам нужно найти секцию [Xdebug] . Как правило, она находится в конце этого файла.
Здесь нам нужно раскомментировать (или просто добавить) строки:

zend_extension="%sprogdir%/modules/php/%phpdriver%/ext/php_xdebug.dll"
xdebug.remote_enable = 1
xdebug.remote_port = 9000
xdebug.remote_handler = "dbgp"
xdebug.remote_connect_back = 1
xdebug.idekey = "PHPSTORM"

Должно получиться так:
Включение Xdebug в php.ini

После чего нужно сохранить файл (CTRL + S) и перезапустить веб-сервер.
Перезапуск OpenServer

На этом настройка веб-сервера для отладки завершена.

Настройка отладки в PHPStorm

Теперь нам нужно настроить отладку в PHPStorm. Первым делом идём в настройки:
File -> Settings

Здесь в левом меню выбираем:
Languages & Frameworks -> PHP -> Debug

Прокручиваем правую часть до секции Xdebug, и задаём следующие настройки:

  • Debug port: 9000
  • Force break at first line when no path mapping specified: выключено
  • Force break at first line when a script is outside the project: выключено

Настройки отладки в PHPStorm

Сохраняем изменения, нажав на “OK”.

Теперь в верхней правой части программы жмём на такую выпадающую менюшку:
Выпадающее меню с конфигурацией для отладки

И жмём “Edit Configuration”.

В появившемся окне в левом верхнем углу жмём на плюсик и выбираем “PHP Remote Debug”.
PHP Remote Debug

Задаём настройки:

  • Name: XDebug

И нажимаем справа от пункта “Servers” на три точки:
Servers for debug

В появившемся окне снова жмём на плюсик, и у нас в списке появляется новый сервер. Давайте зададим для него следующие настройки:

  • Name: localhost
  • Host: localhost
  • Port: 80
  • Debugger: Xdebug

Сервер для отладки

Сохраняем нажатием на “OK” и завершаем заполнять ранее открытую настройку. А именно:

  • Ide key (session id): PHPSTORM

И убеждаемся, что в “Servers” указан только что созданный нами “localhost”.
Конфигурация для отладки в PHPStorm

Сохраняем, нажав “OK”. На этом конфигурация PHPStorm для отладки PHP-приложений с помощью Xdebug завершена.

Настройка отладки в браузере Google Chrome

Дело осталось за малым – нужно только установить расширение для Chrome под названием Xdebug helper.

Заходим в Chrome и переходим по адресу: Xdebug helper

Напротив расширения Xdebug helper жмём кнопку “Установить”.

После того, как расширение установлено в верхнем правом углу Chrome появится значок жучка. Жмём по нему правой кнопкой мыши и нажимаем “Параметры”.
Меню Xdebug helper

Здесь в пункте IDE key в выпадающем меню выбираем PhpStorm.

Параметры Xdebug helper

И нажимаем “Save”.

На этом предварительная настройка завершена.

Начинаем отлаживать

Итак, все настройки выполнены и дело осталось за малым – начать пользоваться отладчиком.

Давайте в нашем index.php запишем следующий код:

<?php

$x = 5 + 2;

$x *= 2;

$x += 2;

echo $x;

А затем слева от строки $x *= 2; кликнем по пространству между номером строки и самим кодом – появится красная точка.

Breakpoint в PHPStorm

Это брэйкпоинт (breakpoint), или, как её ещё называют – точка останова. К ней мы вернёмся чуть позже.

Теперь давайте включим отладчик – в правом верхнем углу PHPStorm, там где раньше была пустая выпадашка, а теперь выбран пункт “XDebug”, жмём на значок жучка.

Запуск отладки в PHPStorm

Отладка на уровне PHPStorm запущена.

Теперь возвращаемся в Chrome, заходим на адрес нашего проекта (в моём случае http://myproject.loc/) и после того как зашли(!!!) жмём на значок жучка (уже в Chrome) и выбираем пункт “Debug”.

Включение отладки в Google Chrome

После чего значок станет зелёным.

Теперь можно в Chrome обновить страницу, и увидеть, что она повисла в режиме загрузки.
Ожидание загрузки страницы

А в окне PHPStorm увидеть следующее:
Сработала точка останова в PHPStorm

Наша программа остановила своё выполнение в месте брэйкпоинта.

Внизу программы (во вкладке Variables) мы можем видеть значения всех переменных в данный момент. Как видим, сейчас (до выполнения строки 5) $x равна 7.

Давайте нажмём кнопку “F8”. Она осуществляет выполнение кода на текущей строке и останавливается перед следующим действием.
Переход на следующий шаг

Умножили $x на 2, и как видим, её значение стало равно 14. Вот так с помощью отладки мы можем отслеживать значения переменных в какой-то определенный момент работы программы.

Помимо этого, есть, разумеется, и другие сочетания клавиш, которые используются во время отладки.

Давайте прямо сейчас нажмём F9. Это приведет к тому, что программа продолжит выполнение до следующего брэйкпоинта (да, их можно наставить сколько угодно). Если их больше не встретится (как в нашем примере), то программа просто завершит свою работу.

Давайте поиграемся с кодом посложнее:

<?php

function getSum(float $x, float $y)
{
    return $x + $y;
}

function getSumOfCos(float $x, float $y)
{
    $cosX = cos($x);
    $cosY = cos($y);
    return getSum($cosX, $cosY);
}

echo getSumOfCos(1.44, 2);

И установим два брэйкпоинта на строках 5 и 10.
Два брэйкпоинта

После чего обновим нашу страничку в браузере и попадём в первый брэйкпоинт на строке 10:
Попали в первый брэйкпоинт

Здесь мы видим значения переменных $x и $y внутри функции. Нажмём F9 и программа выполнится до того момента, пока не дойдёт до следующего брэйкпоинта.
Попали на следующий брэйкпоинт

Здесь мы уже видим, что внутри функции доступны переменные $x и $y. Но это уже другие переменные, не те, что были переданы в функцию getSumOfCos(). Вот мы и увидели локальную область видимости в действии.

Помимо этого, в левом нижнем углу есть окошечко “Frames”, это так назваемый “стек вызовов”. Здесь мы можем переключаться на места, откуда был вызван наш код ранее. Так мы можем переключиться в то место, где была вызвана функция getSum().
Стек вызовов

И можем посмотреть переменные, которые были доступны в той области видимости (уровнем выше).

Ещё в правом нижнем углу можно увидеть окошечко “Watches”. Это такое место, где можно задать переменные или даже выражения, значения для которых вы хотели бы видеть всегда под рукой. Добавляются они туда с помощью плюсика. В появившемся окошечке вводим выражение, которое мы бы хотели отслеживать. Пусть это будет $x/2.
Watches при отладке

Отлично, осталось рассмотреть ещё одну клавишу и вы готовы к бою – F7. Она позволяет зайти “внутрь” какой-либо конструкции.

Давайте закончим отладку нажатием F9. Поставим теперь только один брэйкпоинт на строке номер 15 и обновим страничку в браузере.
Один брэйкпоинт

Если сейчас нажать F8, то программа закончит своё выполнение, и мы не попадём внутрь функций. Так происходит потому что во время отладки мы работаем на определённых уровнях вложенности, и если нам нужно будет попасть внутрь функции, то нужно будет нажать F7, находясь на строке 15. После этого мы окажемся на строке 10. Если сейчас нажать F8, попадём на строку 11. Ещё раз – на строку 12. Если мы сейчас, находясь на 12 строке нажмем F7, то попадём внутрь функции getSum() на строку 5. А если бы мы нажали F8, то мы просто поднялись бы на уровень выше, в то место, где была вызвана функция getSumOfCos().

В принципе, большего для отладки вам не потребуется (лично мне этого хватает).

Ну а сейчас пришла пора поотлаживать рекурсивные функции. Коль уж у вас возникли проблемы с прошлой домашкой – давайте их решать =)

Давайте возьмем и поковыряем код из предыдущей домашки:

<?php
function numbers(int $x) {
    if ($x == 0) {
        echo $x;
        return;
    }
    numbers($x - 1);
    echo ', ' . $x;
}

numbers(3);

Поставим брэйкпоинт на 3 строке и запустим программу.
Отладка рекурсивной функции

Итак, в функцию попала переменная $x = 3. Нажимаем F8, и попадаем на строку 7, так как условие не выполнилось. Теперь нажмём F7 и снова попадём в начало нашей функции, но теперь $x = 2. И при этом стек вызовов увеличился ещё на одну строку, то есть мы вошли в ещё один уровень вложенности.
Уровень вложенности возрос

Жмём F8 и снова оказываемся на строке 7. Нажимаем F7 и снова попадаем в новый вызов функции, только уже $x = 1, а в стэке вызовов появился ещё один уровень.
И ещё один уровень вложенности

Снова F8 и затем F7. И вот уже в функции $x = 0.
Жмём F8 и оказываемся на строке 4 (теперь условие выполнилось). На этой строке программа выведет 0.
Пошёл вывод

Жмём F8 и попадаем на строку 5. Сейчас функция завершит свою работу и мы попадём на уровень выше, в то место, где она была вызвана. Итак, жмём F8.

Вуаля, мы вернулись на уровень выше, там, где переменная $x = 1.
Вернулись на уровень выше

И попали мы на следующую строку, после той в которой вызвали функцию numbers(1 - 1). И на этой строке мы вывели уже число 1. А дальше – жмите F8 и наблюдайте за ходом выполнения программы. Надеюсь теперь рекурсия для вас понятна =)

Домашнее задание

  • Настройте отладку как в данном уроке
  • Попрактикуйтесь самостоятельно в управлении этим процессом – поведение клавиш F7, F8 и F9 вы должны запомнить наизусть
  • Отдебажьте построчно как минимум две функции из предыдущей домашки (желательно рекурсивные, к тому же один пример я вам уже привёл)

Подключение файлов в PHP

В PHP имеется возможность подключать файлы с кодом внутри других файлов. Это делается для того, чтобы выстроить архитектуру приложения.

Архитектура программного обеспечения (англ. software architecture) — совокупность важнейших решений об организации программной системы. Архитектура включает:

  • выбор структурных элементов и их интерфейсов, с помощью которых составлена система, а также их поведения в рамках сотрудничества структурных элементов;
  • соединение выбранных элементов структуры и поведения во всё более крупные системы;
  • архитектурный стиль, который направляет всю организацию — все элементы, их интерфейсы, их сотрудничество и их соединение.

То есть нам нужно разбивать наш код на отдельные части, каждая из которых будет выполнять свою роль. К примеру, можно вынести какие-то функции в отдельный файл, подключить этот файл внутри другого, и пользоваться ими уже в этом файле.

Смысл архитектуры в том, чтобы компоненты программы, отвечающие за какое-то похожее поведение, лежали в одном месте, и их можно было легко найти и изменить.

Ну а вообще, давайте на примере. Но сначала давайте изучим одну «магическую» константу. Речь идёт о константе DIR . В ней содержится путь до директории, в которой находится текущий скрипт (скрипт, в котором эта константа была использована).

Давайте запишем в наш index.php следующий код:

<?php
echo __DIR__;

Результат этого кода:

C:\OpenServer\domains\myproject.loc\www

Вуаля, мы теперь знаем, в какой папке находится index.php . Мы будем всегда использовать магическую константу DIR при указании путей подключаемых файлов. При этом в выражениях для подключения файлов следует избегать данных от пользователей, чтобы избежать хакерских атак под названием PHP-injections. Подробнее читайте здесь.

Ну а теперь вернёмся к основной теме урока. Создадим в директории с index.php ещё один файл с именем functions.php и заполним его следующим содержимым:

<?php

function isEven(int $x)
{
    return $x % 2 === 0;
}

Теперь вернёмся в index.php и запишем в него следующий код:

<?php

include __DIR__ . '/functions.php';

?>
<html>
<head>
    <title>Чётные и нечётные числа</title>
</head>
<body>
Число 2 <?= isEven(2) ? 'чётное' : 'нечётное' ?>
<br>
Число 5 <?= isEven(5) ? 'чётное' : 'нечётное' ?>
<br>
Число 8 <?= isEven(8) ? 'чётное' : 'нечётное' ?>
</body>
</html>

Надеюсь, никто не забыл, что можно вставлять PHP-код прямо внутри HTML? Об этом мы говорили в этом уроке. Только там мы использовали для вывода конструкцию вида:

<?php echo 2 + 2; ?>

Если во вставке нам нужно только вывести результат какого-то выражения, то её можно упростить до:

<?= 2 + 2; ?>

И если сейчас мы зайдём в браузере на URL нашего приложения, то увидим следующее:
Работа директивы include

Наше приложение успешно отработало, и основной код страницы у нас не содержит вспомогательных функций – они с помощью директивы include подключились в наш файл. Если говорить более детально – PHP-код из файла functions.php был вставлен в то место, где он был подключен с помощью директивы include .

Разница между require и include

Есть ещё одна директива для подключения файлов – require . Если вы сейчас замените include на require , вот так:

require __DIR__ . '/functions.php';

то ничего по сути не изменится – код отработает точно так же.

Однако между ними всё же есть разница. Она заключается в том, что если подключаемый файл не найден, то при include возникнет warning , но программа продолжит своё выполнение. А если подключаемого не окажется при попытке выполнить require , то произойдёт фатальная ошибка и скрипт завершит свою работу.

Давайте снова вернём директиву include , переименуем functions.php в abc.php и попробуем обновить страничку.

Ошибка подключения с типом warning

Получили ошибки разных типов. Первая из них – warning , сообщающий о том, что файл functions.php не найден. Но скрипт продолжил своё выполнение, а затем упал на строке 10 из-за того, что не была найдена функция isEven() , а это уже fatal error .
Давайте теперь заменим include на require и снова обновим страничку.
Фатальная ошибка при отсутствии файла

Теперь мы получили fatal error сразу на второй строке, приложение завершило свою работу на этом месте.

То есть require нужно использовать там, где подключение файла обязательно. Например, файл с конфигурацией, или необходимыми функциями.

А include можно использовать для файлов, которые необязательно должны быть подключены (если без них можно продолжать выполнение кода). Пример: файл с кодом баннерной рекламы. Да, реклама не покажется, но зато сайт продолжит свою работу.

Как ещё можно использовать require и include

Помимо того, что можно подключать файлы с PHP-кодом, можно также подключать файлы, содержащие какой-то текст, или в частности HTML-код.

Предлагаю рассмотреть следующую ситуацию: у нас на сайте всегда одинаковая шапка, боковая панель, и футер, но при этом меняются заголовок и содержимое страницы. Предположим, наш сайт выглядит так:
Шаблон сайта

Зелёным цветом я выделил ту часть странички, которая будет изменяться.

Давайте для начала сверстаем наш шаблон. Надеюсь, все прошли курс по HTML. У меня получился вот такой код:

<html>
<head>
    <title>Заголовок страницы</title>
    <style>
        table, td {
            border: solid black 1px;
            border-collapse: collapse;
        }

        #layout {
            width: 800px;
            margin: auto;
        }

        #layout td {
            padding: 20px;
        }

        #sidebar {
            width: 300px
        }
    </style>
</head>
<body>
    <table id="layout">
        <tr>
            <td colspan="2">HEADER</td>
        </tr>
        <tr>
            <td id="sidebar">SIDEBAR</td>
            <td>CONTENT</td>
        </tr>
        <tr>
            <td colspan="2">FOOTER</td>
        </tr>
    </table>
</body>
</html>

Вот такая получилась у меня веб-страничка:
Свёрстанная страничка

Давайте теперь разобьём этот код на компоненты. Создадим 4 файла: header.php с шапкой файла, sidebar.php с боковой колонкой, content.php с основным содержимым страницы и footer.php для подвала сайта.

header.php:

<html>
<head>
    <title>Заголовок страницы</title>
    <style>
        table, td {
            border: solid black 1px;
            border-collapse: collapse;
        }

        #layout {
            width: 800px;
            margin: auto;
        }

        #layout td {
            padding: 20px;
        }

        #sidebar {
            width: 300px
        }
    </style>
</head>
<body>
    <table id="layout">
        <tr>
            <td colspan="2">HEADER</td>
        </tr>
        <tr>

sidebar.php:

<td id="sidebar">SIDEBAR</td>

content.php:

<td>CONTENT</td>

footer.php:

    </tr>
    <tr>
        <td colspan="2">FOOTER</td>
    </tr>
</table>
</body>
</html>

А теперь вернёмся в index.php и запишем в него следующий код:

<?php

require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';

Обновим страничку и увидим, что она по-прежнему работает. Только теперь она собралась из маленьких кусочков, каждый из которых отвечает за свою часть.

В подключаемых файлах мы можем использовать переменные, которые были определены до их подключения. К примеру, давайте в index.php добавим переменную $content:

<?php

$content = '<h1>Заголовок статьи</h1><p>Текст какой-то статьи</p>';

require __DIR__ . '/header.php';
require __DIR__ . '/sidebar.php';
require __DIR__ . '/content.php';
require __DIR__ . '/footer.php';

А в файле content.php выведем эту переменную:

<td><?= $content ?></td>

Давайте теперь снова обновим страничку:
Динамически сформированная страничка

Та-да! Наша страничка сформировалась динамически! Мало того, что она была собрана из разных компонентов, так она ещё и выводит значения из переменных.

Директивы require_once и include_once

Иногда нужно, чтобы файл подключился только один раз. Например, чтобы только однажды подключить файл с функциями. Для этого используются директивы require_once и include_once .

Давайте создадим файл config.php и запишем в него следующее содержимое:

<?php
echo 'Это просто заглушка вместо конфига.';

И теперь создадим файл test.php и напишем следующий код:

<?php

include_once __DIR__ . '/config.php';
include_once __DIR__ . '/config.php';
include_once __DIR__ . '/config.php';

Теперь давайте запустим test.php, перейдя по адресу в браузере: http://myproject.loc/test.php

И увидим, что текст вывелся только однажды.
Только одно подключение файла

Теперь давайте заменим include_once на include :

<?php

include __DIR__ . '/config.php';
include __DIR__ . '/config.php';
include __DIR__ . '/config.php';

А вот теперь код подключился несколько раз:
Несколько подключений

Вот такие пирожки. Чуть позже мы ещё вернёмся к теме этих отличий, и когда именно стоит использовать include_once и require_once.

А пока что на этом всё. Делайте домашнее задание и до встречи на следующих уроках!

Домашнее задание

  • Самостоятельно создайте архитектуру, описанную в статье: сделайте шапку, сайдбар, контент и футер в отдельных файлах.
  • Сделайте минимум 4 переменные для каждого из этих блоков в файле index.php и выведете их внутри этих файлов.
  • Изучите официальную документацию по include и изучите как можно использовать выражения вида
$var = include 'file.php';
2 симпатии