Simple PHP/Ajax

I have written multiple ajax/php request.

But I have to send this to php as a request in JSON, how do I get this from the server request.
(Single object)

{QueryFilter: “myresult”}

Sorry for the dumb question, have only dealt with JSON as the return format never the send format.

I think you’d need to show the code that you’re using to send the request for anyone to be able to help you in detail.

What is in your $_POST array when you var_dump() it for debugging? Is it just a case of calling json_decode() on the appropriate post variable, the opposite of the json_encode() you’re familiar with?

1 Like

A bit of a play and an example

HTML/JS

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <title>Document</title>
</head>
<body>
  <output id='users'></output>
  <script>

    /**
     * Asynchronously fetches data from a specified URL using the POST method.
     *
     * @param {string} url - The URL to fetch data from.
     * @param {object} data - The data to be sent in the request body.
     * @returns {Promise<object>} - A promise that resolves to the parsed JSON response.
     */
    const fetchPost = async (url = '', data = {}) => {
      const response = await fetch (url, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data) // stringify the data to be sent
      });

      return response.json();
    }
    
    // wrapping code in an async IIFE, so that I can use async/await
    (async() => {
      // sample data
      const users = [
        {
          'id': 1,
          'name': 'Leanne Graham',
          'username': 'Bret',
          'email': 'Sincere@april.biz'
        },
        {
          'id': 2,
          'name': 'Ervin Howell',
          'username': 'Antonette',
          'email': 'Shanna@melissa.tv',
        }
      ];

      // somewhere to output the response
      const output = document.querySelector('#users');
      // send POST data and fetch response
      const data = await fetchPost('./server/test.php', users);

      // output response
      output.insertAdjacentHTML(
        'afterbegin',
        `<pre>${JSON.stringify(data, null, 2)}</pre>`
      )
    })()
  </script>
</body>
</html>

Not an expert with php, and did have to refer to some past tests I have done e.g. the use of file_get_contents('php://input') to fetch the raw data

PHP

<?php
// file_get_contents('php://input') gets the raw POST data as a string
$users = json_decode(file_get_contents('php://input'), true);

// just for a demo transform all user names to UpperCase
foreach($users as &$user) {
  $user['name'] = strtoupper($user['name']);
}

unset($user);
// echo the transformed data for fetch response
echo json_encode($users);

Output (names converted to Uppercase)

[
  {
    "id": 1,
    "name": "LEANNE GRAHAM",
    "username": "Bret",
    "email": "Sincere@april.biz"
  },
  {
    "id": 2,
    "name": "ERVIN HOWELL",
    "username": "Antonette",
    "email": "Shanna@melissa.tv"
  }
]

There maybe a more correct way of doing this, but in my tests it did work. I believe if you want to use $_POST you will need to send the data as form data

headers: {
  'Content-Type': 'application/x-www-form-urlencoded'
},

Have tried a couple of ways to decode the JSON, still failing to get the object on php side.
Here is the request, it is just a single object, do not need to cycle through an array.

$.ajax({
  type: "POST",
  contentType: "application/json; charset=utf-8",
  url: pg + "ajax/auto-complete",
  dataType: "json",
  data: '{QueryFilter: "' + request.term + '"}',
  success: function (data) {
    response(
      $.map(data, function (item) {
        return {
          label: item.text,
          value: item.id,
          link: item.url
        };
      })
    );
  }
});

Request payload would be {QueryFilter: “dddd”}

This is no valid json string. You need to double quote the QueryFilter also,

1 Like

While we’re at it… why are we mapping a 3 parameter object into… another 3 parameter object? Why are we using jQuery to do it? Why are we using a map for a single value? Why are we wrapping it in the response creator? I have many questions.

A point was raised (since deleted) about just sending the one variable as opposed to sending a JSON object.

Trial and error, but here is an alternative using jQuery and a FormData object to send the one property QueryFilter

HTML/JS

<body>
  <h1>Products</h1>
  <output id='products'></output>
<script
  src='https://code.jquery.com/jquery-3.7.1.min.js'
  integrity='sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo='
  crossorigin='anonymous'
></script>
<script>
  // sample request object
  const request = { term: 'Ipad' };

  // create a FormData object and append the QueryFilter property
  const formData = new FormData();
  formData.append('QueryFilter', request.term);

  $.ajax({
    url: './server/test.php',
    type: 'POST',
    // disable Jquery's default behaviour for contentType and processData
    contentType: false,
    processData: false,
    dataType: 'json', // return type
    data: formData,
    success: function (data) {
      const output = document.querySelector('#products');
      // Just for an example output the returned data
      output.insertAdjacentHTML(
        'afterbegin',
        `<pre>${JSON.stringify(data, null, 2)}</pre>`
      );
    }
  });
</script>
</body>

PHP

<?php
// Sample products
$products = [
  0 => [
    'id' => 1,
    'name' => 'Ipad',
    'text' => 'All-screen design with 10.9-inch Liquid Retina display delivers an amazing viewing experience',
    'url' => './my-products/ipad',
  ],
  1 => [
    'id' => 2,
    'name' => 'Iphone',
    'text' => 'An all‑new 48MP Main camera enables super‑high‑resolution photos and 2x Telephoto. Durable colour‑infused back glass and aluminium design. ',
    'url' => './my-products/iphone',
  ],
  2 => [
    'id' => 3,
    'name' => 'Ipad Pro',
    'text' => 'All-screen design with 12-inch Liquid Retina display delivers an amazing viewing experience',
    'url' => './my-products/ipad-pro',
  ],
];

if($_SERVER['REQUEST_METHOD'] == 'POST') {
  // search term to lower case
  $queryName = strtolower($_POST['QueryFilter']);

  $results = [];

  foreach($products as $product) {
    if (str_contains(strtolower($product['name']), $queryName)) {
      array_push($results, $product);
    };
  }

  echo json_encode($results);
}

Output (search term ‘Ipad’)

Products

[
  {
    "id": 1,
    "name": "Ipad",
    "text": "All-screen design with 10.9-inch Liquid Retina display delivers an amazing viewing experience",
    "url": "./my-products/ipad"
  },
  {
    "id": 3,
    "name": "Ipad Pro",
    "text": "All-screen design with 12-inch Liquid Retina display delivers an amazing viewing experience",
    "url": "./my-products/ipad-pro"
  }
]

Alternatively just use JSON.stringify

data: JSON.stringify({ QueryFilter: request.term }),

That was me, I wondered why the OP needed to go to all the trouble of sticking it into a JSON object as it’s only a single string, but then I re-read their original post which says

so I presume they’re not in control of the server end of things.

Good point!

You got me looking at the request,
Changed it to a string and picked up the variable as a $_POST

Working now, thanks

Thought is was meant to be sent as JSON but it doesn’t, picked it up using post variable $_POST on php server and returned it as JSON