0

I'm using AJAX to transport id name of my div to use it as a string in a query. The problem is that it does not want to display any content related to the database (it can display a normal text echo from my function).

// head HTML (AJAX)
$(function () { 
        $('.product').on('click', function (e) {
            var product = $(this).attr('id');
            
            $.ajax({
                type: "post",
                url: 'php/recipe-container.php',
                data: JSON.stringify({
                    data: product,
                }),
                processData:false,
                processData:false,
                contentType: false,
                success: function(response) {
                    $(".display_recipe").html(response);
                }
            });
        });
});
//HTML
<div class="product" id="pizza">pizza</div>
<div class="product" id="lasagna">lasagna</div>
<div class="product" id="sushi">sushi</div>
<div class="display_recipe">
  <?php
    require "php/recipe-container.php";
  ?>
</div>
//PHP (recipe-container.php)
<?php

function display(){
    $con = mysqli_connect("localhost", "root", "", "cookbook");
    echo "test ";
    $product = substr(file_get_contents("php://input"), 9, -2);
    
    $sql = "SELECT * FROM product WHERE name = '$product'";
    $res = mysqli_query($con,$sql);

    while($row = mysqli_fetch_assoc($res)) {
        echo "test2 ";
        $name = $row['name'];
        $description = $row['description'];
        $date = $row['date'];

        echo $name;
        echo $description;
        echo $date;
    }

mysqli_close($con);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST'){ 
    display(); 
}

?>

This is what I see after the button click - "test test2 pizza". "pizza" is the ID name, not the actual name from the database. I don't know how to remove that. I know everything has something to do with the "success" function (response), but I have no idea how to fix that.

Astw41
  • 394
  • 3
  • 12
  • 1
    What exactly _is_ in your database which you'd expect to see in the output then? The only echo statements in your code apart from the "test" one are to show data from the database, so where do you think the "pizza" part of the output is coming from? And what other debugging have you done? Also your query is vulnerable to sql injection attacks, please learn to use prepared statements and parameters. – ADyson Aug 07 '22 at 19:04
  • P.s. why are you encoding a single variable as JSON? It adds no real value. And why are you then not decoding it properly on the server side and relying on string manipulation? Seems like badly done workaround for a problem that didn't really exist to begin with – ADyson Aug 07 '22 at 19:06
  • @ADyson Because I was told that this is the solution to my previous problem :) echo $name etc. should display data from my database, for example, if I click a div with ID = "pizza" I should get name = pizza, description = pizza with salami and mozzarella cheese, date = 07.08.2022 15:34 (the date the product was added) – Astw41 Aug 07 '22 at 19:09
  • OK. So where is then output you're actually seeing coming from then? As I said, the only echo statements apart from the one that says "test" are getting data from the database. "test2 pizza" must surely have come from those. Are you sure you don't have two rows in the database with the same name, or something? – ADyson Aug 07 '22 at 19:11
  • And if you are sending the ID why are you then querying the name field? Don't you also have an ID field in the database table? – ADyson Aug 07 '22 at 19:12
  • `Because I was told that this is the solution to my previous problem `...why not just send the data in regular format and find it via the normal $_POST array? I think you were badly advised about that. – ADyson Aug 07 '22 at 19:14
  • Sorry, I edited my code. There is a "test2" echo. "Pizza" is a problem that I'm trying to solve, it's not from the database, I'm guessing it's the div's ID displaying because of "response" in success, ajax. Div ID differs from product ID in the database. Div ID is in fact the same as "name" from the database. – Astw41 Aug 07 '22 at 19:15
  • @ADyson Normal post didn't work. https://stackoverflow.com/questions/73268930/undefined-array-key-when-sending-id-name-to-php-variable-ajax – Astw41 Aug 07 '22 at 19:16
  • `I'm guessing it's the div's ID displaying because of "response" in success, ajax`...this makes no sense. The only thing which will be in `response` will anything which is echoed by the PHP script. There cannot be anything else in it. – ADyson Aug 07 '22 at 19:27
  • `Div ID is in fact the same as "name" from the database.`...this is a bad design idea. Names can change, names can be duplicated. IDs are unique - that's why we use them when we want to identify a specific item. – ADyson Aug 07 '22 at 19:28
  • 1
    `Normal post didn't work`...because you didn't name the variable. It should be ` data: { "name": product }` and then remove all the `processData: false, contentType: false` unnecessary stuff. And then jQuery will automatically convert your object into a url-parameter string (i.e. `name=pizza` or whatever) and the data will arrive in PHP inside `$_POST["name"]`. Very standard stuff, which you can see in most jQuery AJAX tutorials. Nowhere in that link you gave do I see anyone advise to do the weird thing you've actually done – ADyson Aug 07 '22 at 19:31
  • Anyway if you're seeing `test2` in your output then at least we know the SQL query returned some data. So to debug it a bit more easily, just for now put `var_dump($row);` instead of the `echo $name; echo $description; echo $date;` bit then you can see exactly what's in all the fields returned by the database. – ADyson Aug 07 '22 at 19:33
  • **Warning:** Your code is vulnerable to SQL Injection attacks. You should use parameterised queries and prepared statements to help prevent attackers from compromising your database by using malicious input values. http://bobby-tables.com gives an explanation of the risks, as well as some examples of how to write your queries safely using PHP / mysqli. **Never** insert unsanitised data directly into your SQL. The way your code is written now, someone could easily steal, incorrectly change, or even delete your data. – ADyson Aug 07 '22 at 19:35
  • https://phpdelusions.net/mysqli also contains good examples of writing safe SQL using mysqli. See also the [mysqli documentation](https://www.php.net/manual/en/mysqli.quickstart.prepared-statements.php) and this: [How can I prevent SQL injection in PHP?](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) . Parameterising your queries will also greatly reduce the risk of accidental syntax errors as a result of un-escaped or incorrectly quoted input values. If you learnt your current technique from a tutorial or book, please don't use it again. – ADyson Aug 07 '22 at 19:35
  • Also never configure your web app to login to the database as `root`. Root can do whatever it likes, so on top of the SQL injection vulnerabilities this just leaves your database an open book for hackers. Instead create a separate user account specifically for this application which has only the permissions it actually _needs_ in order to work properly. Don't even use the root account as a shortcut during development or testing, because you need to test your account permissions as well - otherwise when you go live you might have unexpected errors relating to the user account setup. – ADyson Aug 07 '22 at 19:36
  • var_dump shows something like this "array(14) { ["id"]=> string(3) "129" ["name"]=> string(5) "pizza" ["description"]=> string(0) "" " (and more). So the query seems right (at least I think so). How to display it with echo then? – Astw41 Aug 07 '22 at 19:48
  • 2
    You already did, in your original code. Your `echo $name;` echoed "pizza" because that's the name of the field. `echo $description;` produced nothing because as the dump shows, the description field is empty. Presumably the date is empty too but you didn't finish the dump output so I can't see it. – ADyson Aug 07 '22 at 19:51
  • 1
    Using `` in your code makes no sense. The script only outputs data when POSTed to – brombeer Aug 07 '22 at 20:03
  • Because "pizza" is the only product name you have, the description and date are empty. check your database fields and correct the code. – Mohammed Khurram Aug 10 '22 at 04:05

2 Answers2

0

you have to make an array in php before while loop as:

$data = [];
while($row = mysqli_fetch_assoc($res)){

    $data['name'] = $row['name'];
    $data['description'] = $row['description'];
}
return $data;
// return json_encode($data);
exit();

I hope this works fine for you. Now you just have to pass json format in your ajax request and decode and then it works fine for you

  • Thank you, but I already have a solution :) – Astw41 Aug 07 '22 at 20:22
  • This is no different really from what the OP is doing already, except it adds an extra step of complexity that they have to decode the JSON on the client side. It doesn't really solve anything of the issue they are experiencing. We can see (from the comments above, posted before your answer), that the database simply didn't contain what they were expecting it to. – ADyson Aug 07 '22 at 20:22
  • @Astw41 what was the solution then? – ADyson Aug 07 '22 at 20:25
  • data: { "name": product } + that I didn't see that some of the data in the row is empty. – Astw41 Aug 07 '22 at 20:27
-1

Your solution is:

Change:

var product = $(this).attr('id');

To:

var product = $(this).html();
Khoshghalb2c
  • 32
  • 1
  • 9
  • Sorry, but it didn't work. The first part gave the same result, the second part displayed nothing. – Astw41 Aug 07 '22 at 19:26
  • Why would that help? `obj` is not defined anywhere in the OP's code, and `this` works perfectly well to select the object which triggered the event handler. – ADyson Aug 07 '22 at 19:26
  • Sorry for the previous answer. Please read my answer again; I think I understand your problem. – Khoshghalb2c Aug 07 '22 at 19:48
  • @SAZL in the OP's example, the ID and the inner HTML area of the element contain the exact same data. So again, how would this help? You seem to be just guessing. The fact you haven't actually explained any logic behind your answer also suggests this to me. – ADyson Aug 07 '22 at 19:58
  • I apologize to everyone; I know the reason for these obvious mistakes is the fatigue of other projects. You are requesting results from the database whose "name" is "pizza". So, as a result of the names it prints, it is definitely "pizza". – Khoshghalb2c Aug 07 '22 at 20:39