Сегодня познакомимся с языком PHP, веб-сервером NginX, и инструментом контейнеризации Docker.
До этого мы занимались чистым FrontEnd - только видимая часть пользователю. Делали дизайн, верстали, поработали немного с Javascript.
...ну, не считая того урока, где мы настраивали сервер и выкладывали на него.
Сейчас мы погрузимся в Backend - в то, что происходит под капотом нашего проекта - на сервере. Это недоступно пользователю и это является основой нашего проекта. Большая часть работы ведется именно здесь.
Те, кто хочет индивидуальное обучение с преподавателем и быстрое гарантированное трудоустройство, пишите нам в телеграм:
Что было на прошлом занятии?
https://dzen.ru/media/id/62d57767cc38491671976547/63136fda6fda040b2bbf265e
Мы научились:
- Работать с Javascript
- Реагировать на нажатие кнопки
- Управлять отображением элементов на странице с помощью Javascript
- Проверять корректность заполнения полей ввода в контактной форме с помощью Javascript
- Отлаживать JS код в консоли браузера.
Что будет на этом уроке?
На этом уроке мы:
- Разберемся, что такое виртуализация и контейнеры
- Разберемся в общих чертах, как обрабатываются запросы браузера на сервере
- Разберемся и настроим веб-сервер NginX
- Создадим контейнеры NginX и php в Docker
- Поднимем у себя на компьютере локально Docker-сервис - это будет наш веб-сервер
- Будет первое знакомство с языком программирования php и мы напишем несколько строк кода и получим результат в браузере
Если в процессе изучения что-то не понятно - не стесняйтесь спрашивать нас и других учеников в нашей открытой группе в телеграм:
Для тех, кто только к нам присоединился, ссылка на все уроки:
https://dzen.ru/srmt22_webclasses
И ссылка на самый первый урок:
Локально или на сервере
Мы уже попробовали работать следующим образом:
1. Локально (на своем компьютере) сделали дизайн, верстку, все настроили.
2. Выложили результаты на сервер.
Серверы используются при разработке для разных целей:
1. DEV (Development) - сервер, где ведется разработка. Как правило DEV-серверы используются, если невозможно вести разработку локально (на своем компьютере). Например, когда объем данных настолько большой, что просто не поместится локально или если проект требует высокой производительности и компьютер разработчика просто не сможет этот проект запустить.
2. Тестовый сервер - сервер, куда разработчики выкладывают результаты своей работы, а на сервере уже производится проверка: тестировщиком, заказчиком. Если проект большой, то тестовый сервер, как правило, принадлежит команде разработки и заказчик туда не ходит.
3. Stage сервер - как правило примерно тоже самое, что и тестовый, но данные уже максимально приближены к боевому/production (куда ходят реальные клиенты) серверу. Часто бывает, что на Stage-сервере прогоняют новую версию кода с уже реальными боевыми данными и на него запускает часть реальных клиентов из фокус-группы. Если проект большой, то фактически это сервер с "околобоевыми" данными и на нем уже показывают работу заказчику.
4. Боевой или Production сервер - на этом сервере работает проект. На него ходят реальные клиенты. Разработку и эксперименты на нем не ведут - на этом сервере все должно работать надежно, безотказно - сюда приходят только проверенные результаты работы.
Итого, в идеальном случае, мы должны проходить через все 4 этапа, а в самом начале должна быть локальная разработка. Но на маленьких проектах, как правило, все обходится локальной разработкой и тестированием, а потом уже выкладывается на боевой сервер.
Локальная разработка
Итак, нам для локальной разработки нужно, чтобы на нашем компьютере работало все тоже самое, что у нас будет работать на сервере.
Есть два пути, как этого добиться:
1. Установить себе на компьютер все серверное ПО (программное обеспечение) - такое же как на сервере.
2. Использовать средства виртуализации. То есть на компьютер себе установить только средство, которое будет запускать виртуальные серверы, а эти виртуальные серверы уже можно развернуть хоть у себя на компьютере, хоть у вашего коллеги, хоть на боевом, хоть на тестовом сервере. То есть мы один раз настраиваем виртуальный сервер под наш проект и на каждый конкретный компьютер устанавливаем один раз только средство виртуализации.
Вариант 1 - именно такой подход использовался раньше. Как правило была масса приключений с установкой всего себе на компьютер, а потом, когда все попадало на сервер, начинались приключения из-за того, что на сервере Linux, а один разработчик работал под Windows, другой под MAC OS, а третий на Linux, у всех разные версии PHP, веб-сервера.
Вариант 2 - используют сейчас и его использовать будем мы.
Какие бывают средства виртуализации?
Концептуально у нас сейчас два варианта, используемых в веб-разработке?
1. Виртуализация всей машины. При виртуализации мы у себя или на сервере крутим полную версию операционной системы, например Linux. Можно на компьютере с Windows внутри запустить виртуальную машину Linux, развернуть ее на весь экран и пользоваться полноценным Linux. Точно также на MAC OS можно запустить Windows на виртуальной машине и установить и использовать ПО, доступное только на Windows. Крутой вариант в том, что мы получаем полную идентичную копию реальной машины, а на сервере можем развернуть прям ее - виртуальную машину. Из минусов - вы у себя запускаете сразу 2 машины, которые отнимают каждая огромное количество ресурсов компьютера: процессор, диск, память. Нужен очень мощный компьютер. В общем, для веб-разработке это нецелесообразно. Это прекрасно подходит, если вам нужно запустить какую-то программу от другого типа операционной системы на своем, например Adobe Photoshop от Windows на Linux. Средства для этого: VmWare Fusion, VmWare Workstation, VmWare Esxi, Virtual Desktop, Virtualbox (бесплатный и, пожалуй, самый популярный).
2. Контейнер. Контейнеризация - Запускается не полная версия операционной системы, а контейнер или, как правило, нужное программное обеспечение в контейнере. Например, веб-сервер. На пальцах - это урезанная и упрощенная версия виртуальной машины, которая быстро работает, быстро запускается. На контейнер не нужно ничего устанавливать привычным способом - все требуемые установки прописываются в конфигурационном файле и устанавливаются при "сборке" контейнера автоматически.
Вся фишка в том, что когда вы приходите на современный проект - у них уже все конфигурационные файлы сделаны - вам достаточно скачать себе проект и запустить одной командой в консоли - все в контейнер установится автоматически без вашего участия. И этот контейнер точно также будет работать на сервере (справедливости ради: есть определенные особенности в работе с контейнерами на MAC OS/ Windows/Linux, но скорость и эффективность стоят этих жертв)
Docker
Итак, подходящее нам средство виртуализации - контейнеры. Средство контейнеризации, которое мы будем использовать - Docker.
Установка Docker Desktop
Мы уже ставили докер на наш сервер под Debian Linux через консоль.
Для его использования на своем компьютере нужно установить Docker Desktop. Есть версии под Windows, Linux и Mac OS. Установка простая - команды в консоли вводить не придется.
Docker бесплатный. Вы можете скачать и установить его с официального сайта. Устанавливается просто - как обычное приложение. Потом появляется приложение Docker Desktop - его запускайте.
Если возникнут сложности - задавайте вопросы в нашу открытую группу Телеграм:
Работа с проектом под Docker
Я сделал заготовку проекта, с которым мы дальше будем работать. Сейчас его нужно будет скачать, а я расскажу о каждой папке и файле внутри и пройдусь по каждой строке.
https://github.com/madmaker/srmt22-lsn14-start/archive/refs/tags/v1.zip
Скачиваем, распаковываем, открываем папку/проект в любимой IDE (PHPStorm или VSCode, или любая другая)
Я, все-таки больше люблю phpstorm. После двух недель работы с vscode, я понял, что между ними пропасть. Как минимум PhpStorm намного тщательней и активней проверяет за вами код, да еще и подсказки по улучшению кода дает, а начинающему программисту это очень полезно. А опытному программисту предоставлен целый арсенал удобных функций: начиная от работы с базами данных.
Сейчас, все-таки есть способы купить его за довольно маленькие деньги, сравнимые с походом в фаст-фуд, поэтому кому интересно - пишите в наш чат в Телеграм - кину ссылки.
Итак, вы скачали, распаковали и открыли проект. Видите такую структуру папок и файлов:
Структура папок проекта в Docker
Давайте разбирать по порядку.
docker
В этой папке мы будем хранить настройки и различные данные серверов:
mysql
Здесь у нас будут храниться база данных для разработки
nginx
Мы про него еще не разговаривали, но это веб-сервер. Как раз он будет работать в контейнере docker и будет нам выдавать наши файлы с сервера.
nginx.conf
Файл конфигурации nginx сервера. Его подробно рассмотрим ниже.
php
Здесь будут находиться конфигурационные файлы контейнера с интерпретатором php. PHP - это язык программирования. Наши файлы, которые мы будем писать на php, обрабатывает интерпретатор и серверу nginx выдает результат, а nginx уже потом этот результат отдает браузеру (Chrome)
Dockerfile
В этом файле содержится информация по сборке php и установке зависимостей и модулей. Его рассмотрим ниже подробно.
logs
В этой папке будут храниться логи. Логи - это файлы, в которых хранится различная информация о сервере и приложениях, например, запросы пользователей к серверу, ошибки, предупреждения.
В логах у нас две папки: mysql и nginx - там как раз будут храниться файлы логов контейнера с базой данных mysql и веб-сервера nginx
www
Здесь будут храниться файлы нашего проекта. HTML, CSS, PHP - все здесь. То есть то, что мы выдаем пользователю. Файлы, не предназначенные для пользователя, здесь храниться не должны. Они должны быть в папке, недоступной для посетителей.
index.php
Это "индексный" файл проекта - если никакой другой файл не запрошен, то веб-сервер nginx по умолчанию будет обращаться к index.php, интерпретатор php будет его обрабатывать, возвращать nginx результат, а nginx возвращать результат пользователю.
.gitignore
Это файл системы контроля версий GIT. О GIT мы будем разговаривать позже.
docker-compose.yml
Это конфигурационный файл docker. Мы его рассмотрим подробно по каждой строчке.
Readme.md
Файл с информацией о проекте. Этот файл принято создавать и писать в нем информацию о проекте, чтобы другие, которые будут пользоваться вашим проектом, могли понять что и как. Мы сейчас не будем углубляться в Readme.
Запрос-ответ - как работает
Я сделал схему, как все происходит между серверами, сервисами и браузером пользователя.
1. Пользователь запрашивает сайт mysite.ru у браузера. Браузеру нужно понять, на какому конкретном сервере находится mysite.ru. У серверов есть адреса - это IP-адреса. Соответственно, компьютер пользователь у DNS-сервера спрашивает IP-адрес сервера, который обслуживает сайт mysite.ru
2. DNS-сервер возвращает пользователю IP сервера.
3. Браузер пользователя отправляет запрос на сервер.
4. Сервер, видя запрос на страницу сайта, определяет, какой сервис у него отвечает за обработку таких запросов. Это docker-сервис, в котором и работает веб-сервер.
5. В докере есть контейнер с веб-сервером NginX - запрос как раз он и будет обрабатывать.
6. NginX, в свою очередь, определяет, что придется обработать php-сценарий, поэтому он запрашивает у php-интерпретатора обработку php-файла.
7. PHP-интерпретатор возвращает в NginX результат.
8. NginX уже отдает пользователю ответ от php-интерпретатора.
Роли серверов
Сервер в датацентре
Это компьютер, на котором работают сервисы, обслуживающие наш сайт.
Docker-сервис
В докере запущены контейнеры, в которых работают разные службы: веб-сервер NginX, php-интерпретатор, база данных MySQL и т.д.
Веб-сервер NginX
Он обрабатывает входящие запросы от пользователей, обрабатывает их и возвращает результат. Например, если приходит запрос на изображение - веб-сервер возвращает это изображение, если приходит запрос на php-сценарий, то NginX запрашивает у интерпретатора php результат выполнения сценария.
Php-интерпретатор
Выполняет php-сценарии и возвращает результат их выполнения.
Конфигурационные файлы серверов
nginx.conf
Как и обещал, пройдемся по важным для нас файлам и рассмотрим каждый построчно.
server {
index index.php;
server_name localhost;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
В этом файле мы описываем настройки веб-сервера nginx.
Первая строка server, дальше открывающая фигурная скобка и внутри тело конфигурации.
index index.php;
Объявляет, что индексный файл - это index.php. Индексный файл - это тот, который открывается по-умолчанию. Если не запрошен никакой конкретный файл, то возвращается индексный.
server_name localhost;
Это имя сервера.
localhost - это имя нашего локального компьютера. В целом local host и означает "Локальный хост".
error_log /var/log/nginx/error.log;
В какой файл записывать возникающие ошибки при работе сервера nginx.
access_log /var/log/nginx/access.log
В какой файл писать лог запросов к серверу nginx.
root /var/www;
Указываем путь, по которому nginx будет искать исходные файлы нашего проекта.
location ~ \.php$ {
Дирректива Location. Мы можем задавать разные правила для обработки разных запросов. Например, эта дирректива объясняет, что любые запросы по любым адресам, заканчивающиеся на .php нужно отправлять php-интерпретатору. То есть, если пользователь запрашивает файл php, то нужно не содержимое файла вернуть, а вернуть результат обработки этого файла в php-интерпретаторе.
Внутри идут настройки для этого location.
Все, что находится в теле location, я опишу, но вы можете пропустить - это будет совсем не понятно и сейчас вам с этими настройками можно не заморачиваться. Просто скопируйте. Многие разработчики вообще не понимают, что там написано внутри и зачем. Мы потом в работе уже будем подробнее рассматривать эти настройки.
try_files $uri =404;
Смысл простой: сначала сервер пробует найти запрошенный файл (URI - это адрес, который запросил браузер) и, если его нет - выдаст ошибку 404 "Не найден".
fastcgi_split_path_info ^(.+\.php)(/.+)$;
Вникать на данном этапе не обязательно, но этот параметр отвечает за разбивку запрошенного URL и сохранение его частей в переменные SCRIPT_FILENAME и PATH_INFO.
Для особо пытливых вот документация:
https://nginx.org/ru/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info
fastcgi_pass php:9000;
Порт, по которому nginx общается с php
fastcgi_index index.php;
Аналогично, можно не вникать. Задаёт имя файла, который при создании переменной $fastcgi_script_name будет добавляться после URI, если URI заканчивается слэшом. Например, при таких настройках.
include fastcgi_params;
Просит подключить параметры fastcgi
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
Задает значения параметрам.
Что нам полезно в этих настройках на данном этапе:
1. Мы задаем папку, в которой у нас лежит проект - root
2. Мы задаем имя индексного файла - index
3. Мы задаем, где хранить логи - error_log, access_log
В остальное можно пока не вникать.
Dockerfile
Этот файл занимается сборкой php, установкой требуемых зависимостей и модулей.
Зависимость - это программное обеспечение и библиотеки, которые требуются для работы php
Все это делается автоматически по описанному в Dockerfile сценарию. И как раз освобождает нас от необходимости на каждый компьютер или сервер устанавливать все вручную каждый раз. Особенное удовольствие от контейнеризации можно испытать, если у вас 2 проекта и требуемые библиотеки под один и другой друг с другом конфликтуют - то есть, чтобы работал один проект - нужно удалить зависимость второго и установить то, что нужно для первого, но это сразу приведет к тому, что второй перестанет работать.
Ну и сейчас мы с вами просто запустим docker-сервис и это освободит нас в принципе от кучи установок, без которых ничего бы не работало.
Разберу строки Dockerfile, как и обещал.
FROM php:8.1.10-fpm
Указываем образ, на основе которого все будет работать. Мы выбрали образ php:8.1.10-fpm. Обратите внимание, версия php - 8. Этот образ будет скачан автоматически при сборке контейнера.
RUN
RUN выполняет команды: делает тоже самое, что мы вручную делаем в консоли, только автоматически. Пишется так: RUN и далее команда к выполнению. Здесь мы устанавливаем модули и зависимости PHP.
Модули PHP устанавливаются командой docker-php-ext-install.
Каждый RUN создает новый слой в образе. Команды RUN рекомендуется объединять - для этого используется символ \ (бэкслэш).
WORKDIR /var/www
Указываем рабочую папку php
CMD ["php-fpm"]
Осуществляет запуск контейнера.
docker-compose.yml
В этом файле находится конфигурация докер-сервиса.
version: '3'
Указываем версию файла конфигурации. От этой версии зависит, что и как можно писать в этом файле.
services:
Блок, в котором описываются сервисы докер.
nginx:
Первый сервис, который мы опишем - это контейнер нашего веб-сервера NginX.
image: nginx:1.23.1
Указываем образ, на основе которого будет сделан контейнер. Этот образ будет скачан автоматически при сборке контейнера.
container_name: nginx
Имя контейнера. Сделали nginx.
depends_on:
- php
Список контейнеров, от которых зависит этот контейнер. Контейнеры, от которых зависят другие, будут запущены первыми.
links:
- php
Задаем "в лоб" имя, по которому nginx сможет обращаться к контейнеру php.
volumes:
- ./www:/var/www/
- ./docker/nginx:/etc/nginx/conf.d/
Здесь мы задаем соответствия путей на сервере с путями внутри контейнера.
Например, папка www в нашем проекте будет соответствовать папке /var/www в контейнере nginx. Папки внутри проекта начинаются с точки и слэша.
docker/nginx - это папка, где хранятся конфигурационные файлы NginX и, в том числе, файл nginx.conf
ports:
- "80:80"
Здесь указывается соответствие портов внутри контейнера к тем, которые будут снаружи докер-сервиса. Порт 80 - это порт по умолчанию для веб-сервера. Когда вы вводите адрес сайта, например yandex.ru, подразумевается, что вы ввели yandex.ru:80 - просто порт опускается. Это порт по-умолчанию для протокола http, поэтому его можно не писать.
Есть и другие порты, которыми мы уже пользовались: 443 - https протокол. Это тоже веб-сайты, но по защищенному каналу. Последняя S как раз означает Secured.
21-й порт - порт FTP протокола. Когда мы закачиваем файлы на FTP, как раз используется 21-й порт (есть еще SFTP - о нем ниже).
22-й порт - порт для SSH. Мы, когда настраивали сервер в датацентре, подключались с нашей консоли к консоли сервера как раз по 22-му порту.
Также мы по 22-му порту загружали файлы через SFTP - то есть это FTP через SSH.
Портов очень много. На сервере или любом компьютере сервис, который обрабатывает внешние сетевые подключения, работает как раз по своему порту. Вы можете также задать любой порт вместо 80 для своего сайта, например 8080. И тогда ваш сайт нужно будет открывать так: http://mysite.ru:8080. То есть порт придется явно указывать.
Собственно, чтобы людям не приходилось указывать порт, мы будем использовать порт по-умолчанию: 80.
php:
Ниже описаны настройки контейнера php. В нем у нас работает php-интерпретатор, который как раз занимается выполнение php-сценариев.
image: php:8.1.10-fpm
Указываем образ, на основе которого работает контейнер.
volumes:
- ./www:/var/www/
Также, как и в предыдущем контейнере, "пробрасываем" папки из нашего проекта внутрь контейнера php. То есть в проекте www, а в контейнере /var/www
Вот и все. Я предполагаю, что из всего материала выше понятно мало, но это не проблема. Мы в процессе работы со всеми настройками разберемся. Сейчас просто используйте как есть.
Запускаем контейнеры Docker
Теперь переходим к самому интересному: давайте запустим наш сервис.
Для этого в вашей любимой IDE откройте терминал.
Как открыть терминал в phpstorm:
Как открыть терминал в VsCode:
В терминале выполняем команду:
docker-compose up
Docker считает наш docker-compose.yml и запустит 2 контейнера: Веб-сервер NginX и интерпретатор php..
Первый запуск может занять некоторое время, потому что будут скачиваться образы, зависимости, модули, собираться контейнеры.
В браузере откройте такой адрес: 127.0.0.1 или localhost.
127.0.0.1 - это IP вашего локального компьютера внутри него самого. localhost - это имя вашего компьютера внутри него самого. То есть любой сервер или компьютер внутри себя может к себе обратиться по такому IP или имени.
В браузере откроется такая страница.
Теперь давайте, разберемся, как она получилась.
Мы запустили докер-сервис, в котором работает веб-сервер nginx, который как раз обрабатывает запросы от браузера по протоколу http и порту 80. В конфиге nginx.conf мы указали, что по умолчанию нужно выдавать результат выполнения скрипта index.php, который лежит в папке www.
Контейнер Nginx передал контейнеру php на обработку скрипт index.php и вернул результат в браузер.
Что находится в index.php?
<?php
phpinfo();
Там всего 2 строки:
<?php
Так нужно начинать блок кода, внутри которого идет php-скрипт. В нашем случае так нужно начинать весь файл php.
phpinfo();
Это вызов функции, которая вернет на экран информацию о php: установленные модули, версию, информацию о системе, настройки php.
В конце каждой строки должна стоять точка с запятой. В целом, это почти во всех языках программирования должно быть. Просто в Javascript это не обязательно, если в конце строки стоит переход на новую строку.
Давайте, все-таки перейдем к программированию.
Hello world на php
Закомментируйте строку с phpinfo(); - просто слева допишите два слэша: //. Или в начале строки поставьте /*, а в конце */.
Двойной слэш - это строчный комментарий - он комментирует все до самого конца строки
/* */ - это блочный комментарий. Он комментирует только тот код, который находится внутри блока комментария.
Напомню, комментарии - это просто текст для разработчика. Этот код не выполняется. Его используют, как правило, либо для заметок самому себе или коллегам, или чтобы временно отключить блок кода, но не удалять его.
На новой строке напишите:
print "Hello world";
Проверьте в браузере - будет выведено "Hello world".
print выводит на экран то, что находится справа: строка или переменные. В нашем случае строка.
"Строка"
Строки в php берутся в двойные или одинарные кавычки. Если текст не взять в кавычки, то получите ошибку.
Переменные в php
Переменные в php начинаются со знака доллара. То есть переменная, например, в которой захотим хранить имя, будет выглядеть так: $myName.
Давайте объявим переменную с именем и запишем в нее значение:
$myName = "Николай".
Этот код нужно написать над print "Hello world"
Что мы сделали:
Мы объявили переменную $myName (обратите внимание на стиль написания: каждое новое слово в имени переменной пишутся слитно и с большой буквы - это Camel Case).
Потом мы в эту переменную записали значение - строку.
Код за print замените на :
print "Hello, ".$myName;
Проверьте в браузере: на экране будет Hello, Николай.
Символ точки
Точка внутри строк - это символ конкатенации в php. Конкатенация - это "склеивание". То есть мы конкатенировали значение переменной $myName к строке "Hello, ".
А print все это вывел на экран.
Можно было, кстати, написать так:
print "Hello, "; print $myName;
Функция echo
echo делает тоже самое, что print, но ей можно передать несколько аргументов через запятую.
То есть можно написать:
echo "Hello, ".$myName;
И результат будет точно такой же, как и с print.
А вот этот код можно упростить:
print "Hello, "; print $myName;
Написать так:
echo "Hello, ", $myName;
И, кстати, этот код эффективней с точки зрения производительности (скорости работы) кода с конкатенацией, потому что он просто выведет на экран то, что ему передали, а, в случае с конкатенацией, сначала две строки будут соединены, а потом выведены на экран.
Так-то мелочь, но все же.
Все, всем спасибо. Не забудьте подписаться и поставить лайк.
Результат урока можно скачать здесь:
https://github.com/madmaker/srmt22-lsn14/archive/refs/tags/v1.zip
Резюме урока
Поздравляю, мы познакомились с Docker, Nginx, PHP.
Чтобы обучение было эффективным, вам после каждого занятия нужно самостоятельно экспериментировать с вашим кодом: ломайте проект, меняйте код, пишите новый, экспериментируйте.
С чем вы уже знакомы?
- HTML
- CSS
- SASS
- Javascript
- Docker
- Linux-серверы
- Верстка
- Дизайн сайтов
- PHP
Я подчеркну, что именно знакомы. До уверенного программирования нам еще далеко.
Что делать дальше и как нам помочь?
1. Поставить лайк
2. Написать в комментарии, за сколько времени удалось сделать урок, с чем возникли сложности, что бы хотелось разобрать более детально
3. Подписаться на этот канал
4. Добавиться к нам в группу в наш открытый клуб веб-разработки в телеграм: https://t.me/srmt22_webclub
5. Сделать репост этого урока себе в соцсети.
Что будет на следующем занятии?
Соберем результаты всех наших уроков воедино. Разберемся с POST, GET и Ajax - научимся отправлять данные из браузера на сервер. Отправим результат заполнения формы в диалоге на сервер.
Ссылка на следующий урок:
https://dzen.ru/media/id/62d57767cc38491671976547/631f8246c0fd3557a7bea7b6
Трудоустройство
Те, кто хочет индивидуальное обучение с преподавателем и быстрое гарантированное трудоустройство, пишите нам в телеграм: