Как безопасно передать переменную из php в js
Чтобы передать переменную из php в js, выведите ее в HTML через JSON или отправьте HTTP-запросом. PHP работает на сервере, JavaScript – в браузере. В статье вы найдете безопасные примеры для строки, числа, массива, объекта, bool и null, а также узнаете, как отправить значение обратно в PHP.
- Почему PHP-переменную нельзя прочитать из JavaScript напрямую
- Какой способ выбрать
- Как передать переменную из php в js через json_encode
- JSON в теге script type="application/json"
- Data-атрибуты
- Переменные для внешнего JavaScript-файла
- Получение данных через fetch
- Как передать переменную из JavaScript в PHP
- Ошибки при передаче переменных из PHP в JS
- Как выбрать способ под задачу
Почему PHP-переменную нельзя прочитать из JavaScript напрямую
PHP выполняет код на сервере до отправки страницы. JavaScript запускается в браузере после получения HTML.
Переменная $user остается в памяти PHP. Браузер видит готовый HTML и ответы отдельных HTTP-запросов.
Поэтому передать переменную из php в js можно через выведенный текст или HTTP-запрос. Для структурированных значений используйте json_encode: функция превращает PHP-значение в JSON с сохранением подходящего типа.
Какой способ выбрать
Выберите способ по моменту получения данных и месту их использования. Значение для первого рендера передайте в HTML, меняющиеся сведения запросите после загрузки.
| Способ | Когда подходит | Типы данных | Кэширование страницы и JS | Совместимость с CSP | Сложность |
|---|---|---|---|---|---|
Inline и json_encode | Данные нужны сразу | Все JSON-типы | Данные связаны с HTML | Исполняемый inline-код требует разрешения, например nonce | Низкая |
application/json | Внешний скрипт читает объект | Все JSON-типы | HTML содержит данные, JS кэшируется отдельно | Подходит при запрете исполняемого inline-кода | Низкая |
| Data-атрибуты | Значение относится к элементу | Строки и JSON-строка | Данные связаны с HTML | CSP влияет на скрипт, но не на атрибут | Низкая |
| Глобальный объект | Данные нужны внешнему script.js | Все JSON-типы | JS можно кэшировать отдельно | Объявление требует разрешения inline-кода | Средняя |
fetch | Данные меняются после загрузки | Все JSON-типы | Страница и ответ кэшируются отдельно | Внешний JS требует разрешения загрузки; запрос регулирует connect-src | Средняя |
Как передать переменную из php в js через json_encode
Этот способ формирует JavaScript во время генерации страницы. Не добавляйте кавычки вокруг результата json_encode: функция уже возвращает JSON нужного типа.
Для запуска примеров нужен установленный PHP, доступный командой php в терминале.
- Создайте папку
php-js-demoдля учебных файлов. - Сохраните первый PHP-пример из этого раздела в
php-js-demo/index.phpс кодировкой UTF-8. - Откройте терминал в папке
php-js-demo. Если терминал открыт в родительской папке, выполнитеcd php-js-demo. - Запустите встроенный сервер командой
php -S 127.0.0.1:8000. Терминал сообщит о запуске сервера; оставьте это окно открытым. - Откройте в браузере адрес
http://127.0.0.1:8000/index.php. - Откройте инструменты разработчика браузера и переключитесь на консоль. Первый пример выведет имя Анна, число 28 и остальные значения из листинга.
Папка php-js-demo теперь служит корнем сайта для всех примеров. Файл script.js размещайте рядом с index.php, обработчики – внутри подпапки api. Каждый способ запускайте отдельно: заменяйте содержимое учебных файлов соответствующими листингами и обновляйте страницу.
Открытие файла напрямую с диска не запускает PHP. Встроенный сервер используйте только для локальных упражнений; после работы остановите его сочетанием Ctrl+C в терминале.
HEX-флаги заменяют символы внутри JSON-строк Unicode-последовательностями. Каждый флаг отвечает за свою группу символов:
JSON_HEX_TAGкодирует угловые скобки. Пользовательский текст не сможет закрыть тег</script>.JSON_HEX_AMPкодирует амперсанд.JSON_HEX_APOSкодирует одинарную кавычку.JSON_HEX_QUOTкодирует двойную кавычку внутри значения строки, сохраняя кавычки синтаксиса JSON.
Флаг JSON_THROW_ON_ERROR превращает ошибку кодирования в исключение. Список констант и их поведение описаны в документации PHP о JSON-константах.
В JavaScript используйте const для переменных без повторного присваивания, let – для изменяемых, вместо var.
<?php
$userName = 'Анна <admin@example.com>';
$age = 28;
$roles = ['editor', 'author'];
$profile = [
'name' => $userName,
'active' => true,
'middleName' => null
];
$jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS |
JSON_HEX_QUOT | JSON_THROW_ON_ERROR;
?>
<script>
const userName = <?= json_encode($userName, $jsonFlags) ?>;
const age = <?= json_encode($age, $jsonFlags) ?>;
const roles = <?= json_encode($roles, $jsonFlags) ?>;
const profile = <?= json_encode(
$profile,
$jsonFlags | JSON_UNESCAPED_UNICODE
) ?>;
console.log(userName);
console.log(age);
console.log(roles);
console.log(profile);
console.log(profile.active, profile.middleName);
</script>В консоли появятся строка, число, массив и объект. Последний вызов выведет true и null. Флаг JSON_UNESCAPED_UNICODE оставляет кириллицу читаемой в исходном JSON.
Анна <admin@example.com>
28
["editor", "author"]
{ name: "Анна <admin@example.com>", active: true, middleName: null }
true null| Тип PHP | Тип JavaScript |
|---|---|
string | string |
int, float | number |
| Последовательный массив | Array |
| Ассоциативный массив | Object |
bool | boolean |
null | null |
Массив с последовательными индексами от нуля становится JavaScript-массивом. Массив с именованными ключами становится объектом. Большие целочисленные идентификаторы передавайте строками, чтобы JavaScript не потерял точность.
Синтаксис <?= – краткая запись echo. Оставляйте результат JSON без внешних кавычек для строки, числа, bool и null.
JSON в теге script type="application/json"
Неисполняемый JSON-блок отделяет данные от логики. Такой формат удобен для внешнего файла и политики CSP, которая запрещает исполняемые inline-скрипты. Сама политика должна разрешать загрузку внешнего файла.
Замените содержимое php-js-demo/index.php PHP-разметкой, а JavaScript сохраните в php-js-demo/script.js.
<?php
$config = [
'apiUrl' => '/api/profile.php',
'userId' => 17,
'features' => ['comments', 'dark-mode']
];
$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS |
JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR;
?>
<script id="app-config" type="application/json"><?= json_encode($config, $flags) ?></script>
<script src="script.js" defer></script>const configElement = document.getElementById('app-config');
const config = JSON.parse(configElement.textContent);
console.log(config.apiUrl);
console.log(config.userId);
console.log(config.features);После обновления страницы в консоли появятся путь /api/profile.php, число 17 и массив ["comments", "dark-mode"]. Читайте блок через JSON.parse и свойство textContent.
Не применяйте htmlspecialchars к JSON внутри raw text-элемента. HTML-сущности попадут в строку и помешают разбору JSON. HEX-флаги нужны и здесь: HTML-парсер распознает конец тега независимо от его типа.
Data-атрибуты
Data-атрибут подходит для значения, которое относится к кнопке, карточке или строке таблицы. Свойство dataset читает такие атрибуты.
Поместите PHP-разметку в php-js-demo/index.php. JavaScript добавьте в php-js-demo/script.js, подключенный после кнопки с атрибутом defer.
<?php
$userId = 17;
$userName = 'Анна "Редактор"';
$tags = ['php', 'javascript'];
$jsonFlags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS |
JSON_HEX_QUOT | JSON_THROW_ON_ERROR;
?>
<button
id="profile-button"
data-user-id="<?= htmlspecialchars((string) $userId, ENT_QUOTES, 'UTF-8') ?>"
data-user-name="<?= htmlspecialchars($userName, ENT_QUOTES, 'UTF-8') ?>"
data-tags="<?= htmlspecialchars(
json_encode($tags, $jsonFlags),
ENT_QUOTES,
'UTF-8'
) ?>"
>Профиль</button>
<script src="script.js" defer></script>const button = document.getElementById('profile-button');
const userId = Number(button.dataset.userId);
const userName = button.dataset.userName;
const tags = JSON.parse(button.dataset.tags);
console.log(userId, userName, tags);В консоли появятся число 17, строка Анна "Редактор" и массив ["php", "javascript"]. Запись data-user-id превращается в dataset.userId.
Все значения в dataset приходят строками. Преобразуйте число через Number, массив или объект – через JSON.parse. Для булева значения сравните строку с 'true': Boolean('false') тоже возвращает true.
htmlspecialchars с ENT_QUOTES кодирует одинарные и двойные кавычки для HTML-атрибута. Функция также кодирует амперсанд и угловые скобки. Передавайте через эту функцию каждое значение, которое попадает внутрь атрибута.
Переменные для внешнего JavaScript-файла
Внешний script.js прочитает настройки из объекта window.appConfig, созданного на странице. Сохраните PHP-разметку в php-js-demo/index.php, следующий JS-листинг – в php-js-demo/script.js.
<?php
$settings = [
'seconds' => 30,
'redirectUrl' => '/account.php',
'isGuest' => true
];
$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS |
JSON_HEX_QUOT | JSON_THROW_ON_ERROR;
?>
<script>
window.appConfig = <?= json_encode($settings, $flags) ?>;
</script>
<script src="script.js" defer></script>const { seconds, redirectUrl, isGuest } = window.appConfig;
console.log(seconds, redirectUrl, isGuest);В консоли появятся 30, путь /account.php и значение true.
Если внешний файл выполнится до создания объекта, деструктуризация вызовет TypeError, потому что window.appConfig имеет значение undefined. Обращение к необъявленному имени дает ReferenceError, а отсутствующее свойство существующего объекта возвращает undefined.
Атрибут defer откладывает выполнение внешнего классического скрипта до разбора HTML. Такие отложенные скрипты запускаются в порядке появления в документе. Блок данных ставьте выше script.js.
Модульный скрипт с type="module" без async тоже выполняется после разбора документа. Объект window.appConfig доступен и модулю. Добавлять defer модулю не требуется; подробности описаны в документации MDN о script.
Получение данных через fetch
Используйте fetch, когда данные зависят от запроса пользователя или меняются после загрузки страницы.
Создайте подпапку api внутри php-js-demo и сохраните обработчик в api/profile.php. На локальном сервере ему соответствует путь /api/profile.php.
Заголовок ответа отправляйте до любого вывода, включая HTML и пробелы перед PHP-кодом.
<?php
// /api/profile.php
header('Content-Type: application/json; charset=utf-8');
$response = [
'name' => 'Анна',
'notifications' => 3,
'active' => true
];
echo json_encode(
$response,
JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
);Поместите JavaScript в php-js-demo/script.js. Для этого примера замените содержимое index.php строкой <script src="/script.js" defer></script> и обновите http://127.0.0.1:8000/index.php.
async function loadProfile() {
try {
const response = await fetch('/api/profile.php');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const profile = await response.json();
console.log(profile.name);
console.log(profile.notifications);
} catch (error) {
console.error('Профиль не загрузился', error);
}
}
loadProfile();Успешный запрос выведет имя Анна и число уведомлений 3. Проверка response.ok обнаруживает HTTP-ошибку до разбора JSON. Блок catch также обработает сетевой сбой и некорректный JSON.
HEX-флаги здесь не нужны: ответ передается отдельным JSON-документом. Если выводите полученный пользовательский текст на страницу, присваивайте его свойству textContent.
Сервер проверяет права доступа до формирования ответа. Персональные данные нельзя отдавать общей странице или общему кэшу для разных пользователей.
Как передать переменную из JavaScript в PHP
Обратное направление тоже использует HTTP-запрос. FormData подходит для отдельных полей, JSON – для объектов и массивов. Примеры возвращают полученные значения без записи в базу данных.
POST с FormData
PHP получает поля формы через массив $_POST. Не задавайте заголовок Content-Type вручную: браузер добавит границу multipart-данных.
Сохраните обработчик в php-js-demo/api/save-name.php, JavaScript – в php-js-demo/script.js. В index.php оставьте подключение <script src="/script.js" defer></script>.
<?php
// /api/save-name.php
$name = $_POST['name'] ?? '';
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'saved' => true,
'name' => $name
], JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);async function saveName() {
const formData = new FormData();
formData.append('name', 'Анна');
const response = await fetch('/api/save-name.php', {
method: 'POST',
body: formData
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result.saved, result.name);
}
saveName().catch(error => {
console.error('Запрос не выполнен', error);
});После обновления http://127.0.0.1:8000/index.php в консоли появятся true и имя Анна. Поле saved здесь демонстрирует ответ сервера, но не подтверждает сохранение.
Перед реальной записью проверьте тип, формат, длину и права пользователя.
POST с JSON-телом
JSON подходит для объекта или массива. PHP читает тело через php://input, а параметр true у json_decode превращает JSON-объекты в ассоциативные массивы.
Сохраните PHP-код в php-js-demo/api/save-settings.php, JavaScript – в php-js-demo/script.js. В index.php оставьте подключение <script src="/script.js" defer></script>.
<?php
// /api/save-settings.php
header('Content-Type: application/json; charset=utf-8');
try {
$body = file_get_contents('php://input');
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $error) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON'], JSON_THROW_ON_ERROR);
exit;
}
if (!is_array($data) || !is_string($data['theme'] ?? null)) {
http_response_code(400);
echo json_encode(['error' => 'Invalid theme'], JSON_THROW_ON_ERROR);
exit;
}
echo json_encode([
'saved' => true,
'theme' => $data['theme']
], JSON_THROW_ON_ERROR);async function saveSettings() {
const settings = { theme: 'dark', compact: true };
const response = await fetch('/api/save-settings.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(settings)
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result.saved, result.theme);
}
saveSettings().catch(error => {
console.error('Запрос не выполнен', error);
});После обновления страницы в консоли появятся true и строка dark. Этот обработчик тоже только возвращает данные. Если запрос изменяет состояние с авторизацией через cookie, добавьте проверку прав и защиту от CSRF.
GET-параметры подходят для коротких значений при чтении данных: PHP получает их через $_GET. HTML-форма отправляет поля без JavaScript, а форма с method="post" заполняет $_POST. JSON-тело не заполняет этот массив автоматически.
Ошибки при передаче переменных из PHP в JS
Выберите экранирование по месту вывода. Защита JavaScript не заменяет защиту HTML-атрибута.
- Сырой
echoв JavaScript. Кавычка пользователя ломает код, а текст с</script>может закрыть тег. Используйтеjson_encodeс HEX-флагами. - Лишние кавычки вокруг JSON. У строки результат
json_encodeуже содержит внешние двойные кавычки. Подстановка в записьconst data = "<?= json_encode($data) ?>";даст две пары кавычек и синтаксическую ошибку. У числового массива вроде[1, 2]внутренних кавычек нет, поэтому внешние кавычки превратят значение в строку. Оставляйте JSON без добавленных кавычек. - HTML-сущности в application/json. Не применяйте
htmlspecialcharsк raw text-блоку, который затем читаетtextContent. - Пропущенное экранирование атрибута. Для
data-*применяйтеhtmlspecialchars(..., ENT_QUOTES, 'UTF-8'). - Неверный тип. Data-атрибут всегда строка. Массив из JSON нужно разобрать через
JSON.parse. - Ассоциативный массив принят за список. Последовательный массив становится JavaScript-массивом, а именованные ключи создают объект. Пропуски в числовых индексах тоже превращают массив в объект; для списка сбросьте индексы через
array_values. - Скрипт загружен раньше данных. Обращение к необъявленному имени вызывает
ReferenceError. Деструктуризация отсутствующегоwindow.appConfigвызываетTypeError. - Персональные данные попали в кэш. Не отдавайте страницу одного пользователя как общую страницу для всех.
Inline-код требует отдельного разрешения политики CSP. Если политика запрещает его, вынесите логику во внешний файл и передайте данные через JSON-блок или fetch. Разрешите загрузку внешнего скрипта, а для запросов – нужный адрес через connect-src.
Nonce разрешает конкретный исполняемый скрипт, когда значение совпадает с политикой CSP. Сервер генерирует непредсказуемое значение заново для каждого ответа. Правила nonce описаны в документации MDN по CSP.
Как выбрать способ под задачу
Для небольшой настройки, которая нужна сразу, используйте json_encode во встроенном скрипте. Этот вариант короткий, но требует разрешения inline-кода в CSP.
Для внешнего файла выберите JSON-блок или window.appConfig. JSON-блок отделяет данные от логики, а глобальный объект проще читать из нескольких скриптов.
Короткий идентификатор элемента храните в data-*. Формат подходит, когда значение живет рядом с конкретной кнопкой или карточкой.
Меняющиеся или персональные данные получайте через fetch, чтобы сервер обработал каждый запрос. Для обычной формы отправляйте FormData, для объекта или массива – JSON-тело.
Совет от нашей редакции: сначала определите место вывода, затем выберите экранирование – JSON нужен JavaScript, а htmlspecialchars нужен HTML-атрибуту.
Популярное за неделю
- Как создать сайт самому в 2026: 4 способа + пошаговая инструкция 34 мин чтения
- Лучшие конструкторы для создания сайтов — плюсы, минусы и сравнения 22 мин чтения
- Как сделать редирект на PHP 6 мин чтения
- Основы ООП в PHP: принципы и примеры 6 мин чтения
- Адаптивный помесячный календарь на AJAX и PHP 2 мин чтения
- Как создать формы регистрации и авторизации на PHP 5 мин чтения
Комментарии
а то я не могу создать игру в однаклассниках
НАФИГ ТУТ ПИСАТЬ ЭТО JAVASCRIPT А НЕ JAVA
✳
а как зарегистрироваться в jave
В JAVE регестрироваться не надо