PHP Manual

Обробка ajax POST запитів в PHP

01. 11. 2019

Obsah článku

Розробляючи ajax Vue.js додатки, через роки я нарешті дізнався, як використовувати ajax в PHP і як отримувати дані методом POST.

Суперглобальна змінна $_POST доступна тільки для форм

У PHP для зберігання даних, надісланих з форми, зазвичай використовується суперглобальна змінна $_POST.

Він відносно простий у використанні.

На стороні HTML потрібно створити форму:

<form action="process.php" method="post">
Jméno: <input type="text" name="username">
<input type="submit" value="Odeslat">
</form>

І тоді у файлі process.php до значень можна отримати доступ як до елементів масиву:

echo htmlspecialchars($_POST['ім'я користувача'] ?? '');

Попередження:**.

При такому простому підході може скластися враження, що POST-дані автоматично визначаються як індекси масиву у змінній $_POST. Але це не відповідає дійсності!

Насправді, причина, по якій дані, відправлені з форми методом POST, записуються в змінну $_POST, полягає в тому, що браузер автоматично відправляє HTTP-заголовок 'Content-Type': 'application/x-www-form-urlencoded' при відправці HTML-форми.

Без правильно встановленого заголовка до значень просто неможливо отримати доступ, і нам доводиться використовувати обхідні шляхи.

Відправка даних по ajax

При спробі відправити дані за допомогою ajax, нам потрібно трохи змінити підхід на стороні PHP. Детальніше можна почитати дискусію на Facebook.

У javascript, наприклад, можна використовувати бібліотеку axios для відправки даних за допомогою ajax. Щоб легко ним користуватися, просто підключіть javascript з сервера CDN і відразу ж використовуйте його:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
axios.post('/api/form-process', {
username: 'Jméno uživatele'
})
.then(response => {
// Zpracování odpovědi z API
alert(response.data.message); // Vyhodí hlášku se zprávou
});
</script>

У цьому простому випадку за допомогою ajax викликається URL '/api/form-process' і методом POST передається об'єкт { username: 'Ім'я користувача' }. Сама бібліотека вже обробляє логістику передачі даних автоматично, тому вони надсилаються в серіалізованому вигляді у форматі Json. На мові фронтенд-розробників це називається json payload.

На стороні PHP я б очікував, що він буде використовуватися як форма (зрештою, це був POST-метод):

echo htmlspecialchars($_POST['ім'я користувача'] ?? '');

Однак, в цьому випадку поле $_POST буде пустим і ніяких даних не буде передано. Змінна $_POST використовується тільки для даних, отриманих з форм (це видно по HTTP-заголовку, який ми не викинули).

Тому в даному випадку нам потрібно отримати дані безпосередньо з HTTP-запиту, для цього використовується trick solution. Після цього його легко використовувати:

$data = json_decode(file_get_contents('php://input'), true);
echo htmlspecialchars($data['ім'я користувача'] ?? '');
header('Content-Type: application/json');
echo json_encode([
'повідомлення' => 'Серверний повзун',
]);
die;

Як приклад, також наводжу просту відповідь на javascript. Головне - правильно передати HTTP-заголовок Content-Type: application/json і вийти зі скрипта після відправки всіх даних.

Примусове використання `$_POST``

Якщо ви все ж таки хочете розглядати подані дані безпосередньо як форму, існує спосіб їх передачі. В такому випадку потрібно доопрацювати створення самого ajax-запиту і коректно передати HTTP-заголовки:

axios.post(
'/api/form-process',
{
username: 'Jméno uživatele'
},
{
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}
).then(response => {
// Nějaké zpracování
});

В цьому випадку, однак, обробка на стороні PHP не буде приємною, оскільки нам все одно доведеться коригувати дані і перетворювати їх в масив.

Я примудрився придумати цей жах:

if (\count($_POST) === 1
&& preg_match('/^\{.*\}$/', $post = array_keys($_POST)[0])
&& ($json = json_decode($post)) instanceof \stdClass
) {
foreach ($json as $key => $value) {
$_POST[$key] = $value;
unset($_POST[$post]);
}
}
echo htmlspecialchars($_POST['ім'я користувача'] ?? '');

Однак набагато краще дотримуватися першого підходу і використовувати для отримання даних метод 'php://input'.

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
4.
Status:
All systems normal.
2024