Question

How to Pass Variables from PHP to JavaScript Safely

phpjavascript

Question

I have a value in PHP that is created on the server, and I need to use that value inside JavaScript running on the same page.

For example, my PHP code does some API and database work and produces a value:

<?php
$val = $myService->getValue();

Later on that same page, I want to pass $val into JavaScript as an argument:

<script>
    // I tried this, but it did not work
    myPlugin.start($val);

    // This also did not work
    <?php myPlugin.start($val); ?>

    // This works sometimes, but sometimes it fails
    myPlugin.start(<?=$val?>);
</script>

What is the correct and safe way to pass a PHP variable to JavaScript?

Short Answer

By the end of this page, you will understand why PHP variables are not automatically available in JavaScript, how server-side and client-side code interact, and the safest ways to transfer data from PHP to JavaScript using json_encode(), inline script values, and HTML data-* attributes.

Concept

PHP and JavaScript run in different environments:

  • PHP runs on the server before the page is sent to the browser.
  • JavaScript runs in the browser after the page has been delivered.

That means JavaScript cannot directly read PHP variables such as $val. The PHP variable must first be rendered into the HTML or JavaScript output that the browser receives.

The safest and most common way to do this is with json_encode().

Why json_encode() matters:

  • It converts PHP values into valid JavaScript-compatible literals.
  • It safely handles strings, quotes, booleans, numbers, arrays, and objects.
  • It reduces syntax errors caused by manually inserting raw values.

For example:

<script>
    const val = <?php echo json_encode($val); ?>;
    myPlugin.start(val);
</script>

If $val is a string like John, json_encode() outputs:

"John"

If $val is a number like 42, it outputs:

42

If $val is an array, it becomes a JavaScript array or object structure.

This concept matters in real programming because many pages need server-generated data in frontend code, such as:

  • current user information
  • configuration values
  • API tokens or flags
  • form defaults
  • database results

The key rule is simple: PHP must print the data into the page in a format JavaScript can understand.

Mental Model

Think of PHP as a chef in a kitchen and JavaScript as the customer at the table.

  • The chef prepares the meal in the kitchen before it leaves.
  • The customer only sees what is served on the plate.

A PHP variable is like an ingredient in the kitchen. JavaScript cannot walk into the kitchen and grab it directly. PHP has to place that value onto the plate by writing it into the page output.

json_encode() is like packaging the ingredient in a way the customer can safely use.

Take Quiz

Syntax and Examples

Basic pattern: use json_encode()

<?php
$val = $myService->getValue();
?>

<script>
    const val = <?php echo json_encode($val); ?>;
    myPlugin.start(val);
</script>

Why this works

  • echo prints the PHP value into the page.
  • json_encode() makes sure the result is valid JavaScript syntax.
  • JavaScript receives a real value it can use.

Example with a string

<?php
$val = "Hello world";
?>

<script>
    const val = <?php echo json_encode($val); ?>;
    console.log(val);
</script>

Output in the browser becomes:

<script>
    const val = "Hello world";
    console.log(val);
</script>

Example with an array

<?php
$user = [
    'id' => 10,
    'name' => 'Ava',
    'isAdmin' => true
];
?>

<script>
    const user = <?php echo json_encode($user); ?>;
    console.log(user.name);
</script>

JavaScript receives:

const user = {"id":10,"name":"Ava","isAdmin":true};

Using HTML data-* attributes

This is useful when the data belongs to a specific element.

<?php
$val = $myService->getValue();
?>

<div id="app" data-value="<?php echo htmlspecialchars($val, ENT_QUOTES, 'UTF-8'); ?>"></div>

<script>
    const app = document.getElementById('app');
    const val = app.dataset.value;
    myPlugin.start(val);
</script>

Use this when:

  • the value is tied to one element
  • you want cleaner separation between HTML and JavaScript

Passing a larger config object

<?php
$config = [
    'apiBaseUrl' => '/api',
    'userId' => 15,
    'debug' => false
];
?>

<script>
    window.appConfig = <?php echo json_encode($config); ?>;
</script>

Then later:

<script>
    fetch(window.appConfig.apiBaseUrl + '/users/' + window.appConfig.userId)
        .then(response => response.json())
        .then(data => console.log(data));
</script>

Step by Step Execution

Consider this PHP:

<?php
$val = "Book";
?>

<script>
    const val = <?php echo json_encode($val); ?>;
    myPlugin.start(val);
</script>

What happens step by step

  1. PHP runs first on the server.
  2. $val is assigned the string "Book".
  3. json_encode($val) converts the PHP string into valid JavaScript text: "Book".
  4. PHP sends this final HTML to the browser:
<script>
    const val = "Book";
    myPlugin.start(val);
</script>
  1. The browser reads the <script> block.
  2. JavaScript creates a variable named val.
  3. myPlugin.start(val) runs using the value "Book".

Why the broken versions fail

This fails

myPlugin.start($val);

Because $val is PHP syntax, not JavaScript syntax.

This fails

<?php myPlugin.start($val); ?>

Because myPlugin.start() is JavaScript, but PHP tries to interpret it as PHP code.

This is unreliable

myPlugin.start(<?=$val?>);

This may work for simple numbers, but breaks for many strings and special characters.

Example problem:

$val = "John's book";

Output becomes invalid JavaScript if not properly escaped.

json_encode() solves this correctly.

Real World Use Cases

Common practical uses

Passing the current user to frontend code

<script>
    const currentUser = <?php echo json_encode([
        'id' => $user->id,
        'name' => $user->name
    ]); ?>;
</script>

Used in dashboards, profile pages, and admin tools.

Sending feature flags or settings

<script>
    const settings = <?php echo json_encode([
        'darkMode' => true,
        'itemsPerPage' => 20
    ]); ?>;
</script>

Useful for frontend behavior controlled by backend configuration.

Preloading form data

<script>
    const formDefaults = <?php echo json_encode($formData); ?>;
</script>

Helpful in edit forms and multi-step forms.

Embedding API endpoint information

<script>
    const apiBase = <?php echo json_encode('/api/v1'); ?>;
</script>

Often used in apps that call backend routes from JavaScript.

Attaching per-element values

<button data-product-id="<?php echo (int)$product['id']; ?>">Buy</button>

JavaScript can read this when the button is clicked.

Take Quiz

Real Codebase Usage

In real projects, developers usually choose one of these patterns:

1. Bootstrapping page data

A page outputs a single object that JavaScript reads on startup.

<script>
    window.pageData = <?php echo json_encode([
        'user' => $user,
        'csrfToken' => $csrfToken,
        'cartCount' => $cartCount
    ]); ?>;
</script>

This is common in server-rendered apps.

2. Element-specific data via data-*

<div
    class="user-card"
    data-user-id="<?php echo (int)$user['id']; ?>"
    data-user-name="<?php echo htmlspecialchars($user['name'], ENT_QUOTES, 'UTF-8'); ?>"
></div>

Useful for widgets and reusable UI components.

3. Guarding against invalid output

Developers avoid raw output when values may contain:

  • quotes
  • newlines
  • HTML
  • Unicode characters

That is why json_encode() is preferred for JavaScript values.

4. Validation and defaults

In production code, values are often normalized before output:

<?php
$limit = isset($limit) ? (int)$limit : 10;
?>
<script>
    const limit = <?php echo json_encode($limit); ?>;
</script>

5. Keeping secrets on the server

Real codebases are careful not to expose sensitive values such as:

  • database credentials
  • private API keys
  • internal tokens

Only data needed by the browser should be printed into JavaScript.

Common Mistakes

1. Printing raw strings into JavaScript

Broken example:

<?php
$val = "John's book";
?>
<script>
    myPlugin.start('<?php echo $val; ?>');
</script>

This can break because the quote inside the string ends the JavaScript string early.

Better:

<script>
    myPlugin.start(<?php echo json_encode($val); ?>);
</script>

2. Forgetting that PHP and JavaScript are different languages

Broken example:

<script>
    console.log($val);
</script>

$val means nothing to JavaScript unless PHP prints it into the output.

3. Using short echo tags without understanding output

This can be risky if you print unescaped content blindly:

<script>
    myPlugin.start(<?=$val?>);
</script>

Prefer:

<script>
    myPlugin.start(<?php echo json_encode($val); ?>);
</script>

4. Mixing HTML escaping with JavaScript encoding

htmlspecialchars() is for HTML contexts, not for building JavaScript values.

Use:

  • htmlspecialchars() for HTML attributes and text
  • json_encode() for JavaScript values

5. Exposing sensitive backend data

Just because PHP can access a value does not mean the browser should receive it.

Avoid outputting:

  • passwords
  • secret keys
  • internal-only IDs if not needed

6. Assuming types stay the same in all contexts

A numeric string in PHP may become a JavaScript string if encoded as a string.

<?php
$val = "42";
?>
<script>
    const val = <?php echo json_encode($val); ?>;
    console.log(typeof val); // string
</script>

If you need a number, convert it before output or in JavaScript.

Comparisons

ApproachBest forSafe for strings?Handles arrays/objects?Notes
json_encode($value) inside <script>General PHP-to-JS transferYesYesBest default choice
Raw echo $value inside JSSimple numbers onlyNoNoEasy to break
data-* attributesElement-specific valuesYes, with htmlspecialchars()LimitedGood for small values
AJAX/fetch requestData loaded after page renderYesYesBest when data should be fetched later

json_encode() vs htmlspecialchars()

FunctionMain purposeUse it for
json_encode()Create valid JSON / JavaScript-compatible outputValues inside <script>
htmlspecialchars()Escape HTML special charactersHTML attributes and text

Inline value vs separate config object

PatternExampleWhen to use
Inline single valueconst id = <?php echo json_encode($id); ?>;One or two values
Global config objectwindow.appConfig = ...Several related values
data-* attributesdata-id="123"Values attached to elements
Take Quiz

Cheat Sheet

Quick rules

  • PHP runs first on the server.
  • JavaScript runs later in the browser.
  • JavaScript cannot directly access PHP variables.
  • PHP must output the value into the page.
  • Use json_encode() for JavaScript values.
  • Use htmlspecialchars() for HTML attributes.

Safe pattern

<script>
    const value = <?php echo json_encode($value); ?>;
</script>

Safe string example

<script>
    const name = <?php echo json_encode($name); ?>;
</script>

Safe array/object example

<script>
    const data = <?php echo json_encode($data); ?>;
</script>

For HTML attributes

<div data-name="<?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); ?>"></div>

Avoid

myPlugin.start(<?=$val?>);

when $val might be a string or contain special characters.

Good default decision

  • Need value in JS now? Use json_encode().
  • Need value attached to an element? Use data-*.
  • Need data later or dynamically? Use fetch() or AJAX.

FAQ

Why can PHP not be accessed directly from JavaScript?

Because PHP runs on the server before the page is sent, while JavaScript runs in the browser after the page loads.

What is the safest way to pass a PHP variable to JavaScript?

Use json_encode() when printing the value into a <script> block.

Can I use <?=$val?> directly?

Only in limited cases, such as simple numeric output. It is not reliable for strings or complex data.

Should I use htmlspecialchars() or json_encode()?

Use json_encode() for JavaScript values. Use htmlspecialchars() for HTML content and attributes.

Can I pass PHP arrays to JavaScript?

Yes. json_encode() converts PHP arrays into JavaScript arrays or objects.

Is it okay to put data into window variables?

Yes, for page bootstrapping or configuration, but keep the structure organized and do not expose sensitive data.

When should I use data-* attributes instead?

Use them when the data belongs to a specific HTML element and does not need to be global.

Can I pass secret API keys from PHP to JavaScript?

No. Anything printed into the page is visible to the browser and user.

Take Quiz

Mini Project

Description

Build a small product page where PHP provides product information and JavaScript uses it to initialize frontend behavior. This demonstrates the most common real-world pattern: generating data on the server and safely bootstrapping it into browser code.

Goal

Create a page that passes PHP product data into JavaScript and displays a message using that data.

Requirements

  1. Create a PHP array with a product id, name, price, and inStock value.
  2. Pass the product data safely into JavaScript.
  3. Show the product name and price in the browser console.
  4. Display a different message depending on whether the product is in stock.
Take Quiz

Keep learning

Related questions

View more