Мы уже научились отправлять на сервер и принимать обратно данные в JSON-формате. Финальный шаг — будем хранить все наши данные на сервере, чтобы получить доступ к ним с любого устройства. Это поможет нам делать проекты независимыми от локального хранилища.
Как это будет работать
Мы возьмём код из прошлого проекта про отправку JSON на сервер и добавим в него новые возможности.
Логика будет такая:
- Мы научим сервер каждый раз запоминать данные, которые отправит ему наша страница. Чтобы убедиться, что данные в порядке, мы сразу же в ответ будем посылать результат — то, как сервер это запомнил.
- После этого мы поработаем с данными от сервера в понятном для JavaScript виде. Для этого мы немного их поменяем и отправим обратно на сохранение. Это поможет нам понять, как работать с данными в других проектах.
👉 Мы специально используем самые простые и не самые лучшие конструкции в PHP и JavaScript. Наша цель — собрать быстрый прототип и показать, как можно обмениваться данными с сервером. Когда разберёмся с этим, можно и код пооптимизировать. А пока так.
Сохраняем JSON в файл на сервере
Сейчас работает так — по нажатию на кнопку «Проверить JSON» наша страница отправляет на сервер JSON-строку с двумя ключами: именем и фамилией. Новая задача сервера — сохранять себе все полученные данные и отправлять их обратно на страницу. Чтобы данные не потерялись после окончания работы программы, будем сохранять их на сервере в файл json.data
. Мы выбрали такое название, но вы можете взять любое другое, имя файла ни на что не влияет.
Так как по нажатию этой кнопки страница обращается на сервере к файлу json.php, то и изменять тоже нужно именно его. Сделаем так:
- Получаем данные от страницы (это уже сделано в прошлом проекте).
- Проверяем, есть ли на сервере нужный нам файл с данными — json.data.
- Если есть — запоминаем его содержимое, а если такого файла нет — создаём его отдельной командой.
- Всё, что было в этом файле, переводим в массив, с которым умеет работать PHP. Таким способом у нас каждая JSON-запись будет храниться в отдельной ячейке массива.
- Добавляем новую запись в этот массив — кладём в него то, что пришло со страницы.
- Записываем это всё обратно в файл и тут же читаем обратно из него — так мы убедимся, что запись прошла нормально и мы можем с этим работать.
- Отправляем всё содержимое файла на страницу, чтобы там увидеть, что сервер работает как нужно.
Задача этого алгоритма — сохранять данные на сервере и отдавать их обратно на страницу. На языке PHP то же самое будет выглядеть так:
<?php
// на какие данные рассчитан этот скрипт
header("Content-Type: application/json");
// 1. Получаем данные от страницы
$data = json_decode(file_get_contents("php://input"));
// 2. Проверяем, есть ли на сервере нужный нам файл с данными — json.data.
// Берём новую переменную и пишем в неё имя файла
$filename = 'data.json';
// 3. Если есть — запоминаем его содержимое, а если такого файла нет — создаём его отдельной командой.
if (file_exists($filename)) {
// Если файл есть — открываем его и читаем данные
$file = file_get_contents('data.json');
// Если такого файла нет…
} else {
// …то создаём его сами
$file = fopen("data.json", "a+");
}
// 4/ Всё, что было в этом файле, переводим в массив, с которым умеет работать PHP. Таким способом у нас каждая JSON-запись будет храниться в отдельной ячейке массива.
$taskList = json_decode($file, true);
// 5. Добавляем новую запись в этот массив — кладём в него то, что пришло со страницы.
$taskList[] = array($data);
// 6. Записываем это всё обратно в файл и тут же читаем обратно из него — так мы убедимся, что запись прошла нормально и мы можем с этим работать.
// Записываем данные в файл…
file_put_contents('data.json', json_encode($taskList));
// …и сразу считываем их обратно
$file = file_get_contents('data.json'); // Открыть файл data.json
// 7. Отправляем всё содержимое файла на страницу, чтобы там увидеть, что сервер работает как нужно.
echo $file;
// Освобождаем память от переменных, которые нам пока не нужны
unset($file);
unset($taskList);
Обратите внимание на последние строки в коде — мы освобождаем память на сервере, чтобы она не хранила те переменные, которые нам уже не нужны. Зачем это делать и что будет, если этого не делать, — почитайте в статье про сборщики мусора.
Подготавливаем страницу
Теперь научим нашу страницу правильно обрабатывать ответ от сервера и работать с полученными данными. Для этого нам нужно:
- Преобразовать сырые данные, полученные от сервера, в вид, понятный для JavaScript.
- Любым образом поменять их значения.
- Отправить изменённые данные назад на сервер.
- Получить сразу их обратно и вывести на экран, чтобы убедиться, что сервер правильно понял все изменения.
Перед тем как работать с полученными данными в JavaScript, нам нужно их куда-то сохранить. Для этого в самом начале скрипта заведём новую переменную res
, и добавим в функцию sendJSON() такую строку:
// запоминаем данные, которые пришли с сервера
res = this.responseText;
// выводим то, что ответил нам сервер —
так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
Теперь в этой переменной у нас будут лежать сырые данные, которые отправит нам сервер.
Чтобы мы могли отдельно управлять всеми изменениями, добавим в наш HTML-файл с прошлого проекта новую кнопку рядом с первой:
<!-- эта кнопка поменяет полученные данные
и отправит их снова на сервер --!>
<button onclick="editJSON()">Изменить JSON</button>
Сделаем функцию editJSON(), которая сработает по нажатию на эту кнопку. Работать она будет так:
- Возьмёт сырые данные от сервера и преобразует их в формат, понятный для JavaScript.
- Найдёт все имена, посчитает количество символов в них и допишет это число к имени. Так мы поймём, что данные можно менять как нам нужно.
- Преобразует всё это обратно в JSON и отправит на сервер.
- На всякий случай снова выведет результат на странице, чтобы мы убедились, что на сервере лежат уже новые данные.
Чтобы не писать код заново, мы скопируем уже существующую функцию sendJSON(), переименуем её в editJSON() и добавим в неё то, что нам нужно. А перед этим в самом начале скрипта снова добавим две новые переменные:
newData
, где мы будем хранить данные в понятном формате;sendData
, куда мы поместим новую JSON-строку перед отправкой на сервер.
Что мы делаем с JSON, полученным с сервера
Перед тем как показать финальный код, поясним один момент. Мы переводим данные с сервера в формат для JavaScript командой
newData = JSON.parse(res).map(Object.values);
В результате мы получаем двумерный массив, с которым можно работать так:
newData[1][0].name = 'Привет';
newData[3][0].lastname = 'Привет';
Дело тут вот в чём: первая цифра в квадратных скобках отвечает за порядковый номер JSON-записи, которые мы отправляли на сервер. Нумерация идёт с нуля, как принято у программистов.
Вторая цифра у нас всегда 0, потому что хотя это и двумерный массив, но каждая запись состоит всего из одного элемента. Так как нумерация с нуля, то мы и пишем 0.
После этого через точку идёт имя поля — у нас это name и lastname. Через них мы можем обращаться к конкретным значениям и менять в них что угодно.
Такая громоздкость получилась из-за того, что мы решили проблему в лоб — просто перевели данные с помощью встроенных средств языка. Это можно было сделать гораздо красивее, но так — быстрее.
Сам код новой функции:
function editJSON() {
// переводим данные от сервера в массив, понятный для JavaScript
newData = JSON.parse(res).map(Object.values);
// добавляем к каждому имени число с его длиной в скобках
for (var i = newData.length - 1; i >= 0; i--) {
newData[i][0].name = newData[i][0].name + '(' + newData[i][0].name.length + ')';
console.log(newData[i][0].name);
}
// а вот сюда мы поместим ответ от сервера
let result = document.querySelector('.result');
// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();
// адрес, куда мы отправим нашу JSON-строку
let url = "http://mihailmaximov.ru/projects/json/edit.php";
// открываем соединение
xhr.open("POST", url, true);
// устанавливаем заголовок — выбираем тип контента, который отправится на сервер, в нашем случае мы явно пишем, что это JSON
// xhr.setRequestHeader("Content-Type", "application/json");
// когда придёт ответ на наше обращение к серверу, мы его обработаем здесь
xhr.onreadystatechange = function () {
// если запрос принят и сервер ответил, что всё в порядке
if (xhr.readyState === 4 && xhr.status === 200) {
// выводим то, что ответил нам сервер — так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
}
};
// преобразуем наши новые данные в JSON-строку
sendData = JSON.stringify(newData);
// когда всё готово, отправляем JSON на сервер
xhr.send(sendData);
}
Делаем новый PHP-обработчик на сервере
В скрипте мы обращались к файлу edit.php, которого у нас ещё нет. Всё, что нужно от этого файла, — чтобы он сохранил то, что ему пришло, и тут же отправил это обратно, чтобы мы убедились, что всё хорошо. Мы специально выносим такую простую функцию в отдельный файл, чтобы каждый из них отвечал за свою область работы.
Сам файл довольно прост:
<?php
// на какие данные рассчитан этот скрипт
header("Content-Type: application/json");
// получаем данные от страницы
$data = file_get_contents("php://input");
// открываем наш файл с данными
$file = file_get_contents('data.json');
// записываем в него то, что пришло от страницы
file_put_contents('data.json', $data);
// тут же заново считываем все данные, чтобы убедиться, что всё записалось правильно
$file = file_get_contents('data.json');
// и сразу отправляем их на страницу, чтобы это увидел пользователь
echo $data;
// освобождаем память
unset($file);
Что дальше
Теперь у нас всё готово, чтобы переделать наши старые проекты и научить их хранить свои данные в облаке. Этим и займёмся.
<!DOCTYPE html>
<html>
<head>
<title>
Отправляем JSON-данные на сервер
</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body style="text-align:center;" id="body">
<!-- заголовок -->
<h1> Простая форма для проверки работы JSON </h1>
<!-- делаем форму с полями ввода -->
<p>
<input type="text" id="name" placeholder="Ваше имя">
<input type="text" id="lastname" placeholder="и фамилия">
<!-- по нажатию на эту кнопку данные уйдут на сервер -->
<button onclick="sendJSON()">Проверить JSON</button>
<!-- эта кнопка поменяет полученные данные и отправит их снова на сервер -->
<button onclick="editJSON()">Изменить JSON</button>
<!-- а вот тут они появятся снова, но уже после обработки сервером -->
<p class="result" style="color:blue"></p>
</p>
<!-- скрипт, который обработает нажатие на кнопку и отправит данные на сервер -->
<script>
var res;
var newData;
var sendData;
// эта функция сработает при нажатии на кнопку
function sendJSON() {
// с помощью jQuery обращаемся к элементам на странице по их именам
let name = document.querySelector('#name');
let lastname = document.querySelector('#lastname');
// а вот сюда мы поместим ответ от сервера
let result = document.querySelector('.result');
// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();
// адрес, куда мы отправим нашу JSON-строку
let url = "http://mihailmaximov.ru/projects/json/json.php";
// открываем соединение
xhr.open("POST", url, true);
// устанавливаем заголовок — выбираем тип контента, который отправится на сервер, в нашем случае мы явно пишем, что это JSON
// xhr.setRequestHeader("Content-Type", "application/json");
// когда придёт ответ на наше обращение к серверу, мы его обработаем здесь
xhr.onreadystatechange = function () {
// если запрос принят и сервер ответил, что всё в порядке
if (xhr.readyState === 4 && xhr.status === 200) {
// запоминаем данные, которые пришли с сервера
res = this.responseText;
// выводим то, что ответил нам сервер — так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
}
};
// преобразуем наши данные в JSON-строку
data = JSON.stringify({ "name": name.value, "lastname": lastname.value });
// когда всё готово, отправляем JSON на сервер
xhr.send(data);
}
function editJSON() {
// переводим данные от сервера в массив, понятный для JavaScript
newData = JSON.parse(res).map(Object.values);
// добавляем к каждому имени число с его длиной в скобках
for (var i = newData.length - 1; i >= 0; i--) {
newData[i][0].name = newData[i][0].name + '(' + newData[i][0].name.length + ')';
console.log(newData[i][0].name);
}
// а вот сюда мы поместим ответ от сервера
let result = document.querySelector('.result');
// создаём новый экземпляр запроса XHR
let xhr = new XMLHttpRequest();
// адрес, куда мы отправим нашу JSON-строку
let url = "http://mihailmaximov.ru/projects/json/edit.php";
// открываем соединение
xhr.open("POST", url, true);
// устанавливаем заголовок — выбираем тип контента, который отправится на сервер, в нашем случае мы явно пишем, что это JSON
// xhr.setRequestHeader("Content-Type", "application/json");
// когда придёт ответ на наше обращение к серверу, мы его обработаем здесь
xhr.onreadystatechange = function () {
// если запрос принят и сервер ответил, что всё в порядке
if (xhr.readyState === 4 && xhr.status === 200) {
// выводим то, что ответил нам сервер, — так мы убедимся, что данные он получил правильно
result.innerHTML = this.responseText;
}
};
// преобразуем наши новые данные JSON в строку
sendData = JSON.stringify(newData);
// когда всё готово, отправляем JSON на сервер
xhr.send(sendData);
}
</script>
</body>
</html>
<?php
// на какие данные рассчитан этот скрипт
header("Content-Type: application/json");
// 1. Получаем данные от страницы
$data = json_decode(file_get_contents("php://input"));
// 2. Проверяем, есть ли на сервере нужный нам файл с данными — json.data.
// Берём новую переменную и пишем в неё имя файла
$filename = 'data.json';
// 3. Если есть — запоминаем его содержимое, а если такого файла нет — создаём его отдельной командой.
if (file_exists($filename)) {
// Если файл есть — открываем его и читаем данные
$file = file_get_contents('data.json');
// Если такого файла нет…
} else {
// …то создаём его сами
$file = fopen("data.json", "a+");
}
// 4/ Всё, что было в этом файле, переводим в массив, с которым умеет работать PHP. Таким способом у нас каждая JSON-запись будет храниться в отдельной ячейке массива.
$taskList = json_decode($file, true);
// 5. Добавляем новую запись в этот массив — кладём в него то, что пришло со страницы.
$taskList[] = array($data);
// 6. Записываем это всё обратно в файл и тут же читаем обратно из него — так мы убедимся, что запись прошла нормально и мы можем с этим работать.
// Записываем данные в файл…
file_put_contents('data.json', json_encode($taskList));
// …и сразу считываем их обратно
$file = file_get_contents('data.json'); // Открыть файл data.json
// 7. Отправляем всё содержимое файла на страницу, чтобы там увидеть, что сервер работает как нужно.
echo $file;
// Освобождаем память от переменных, которые нам пока не нужны
unset($file);
unset($taskList);
<?php
// на какие данные рассчитан этот скрипт
header("Content-Type: application/json");
// получаем данные от страницы
$data = file_get_contents("php://input");
// открываем наш файл с данными
$file = file_get_contents('data.json');
// записываем в него то, что пришло от страницы
file_put_contents('data.json',$data);
// тут же заново считываем все данные, чтобы убедиться, что всё записалось правильно
$file = file_get_contents('data.json');
// и сразу отправляем их на страницу, чтобы это увидел пользователь
echo $data;
// освобождаем память
unset($file);
?>