Returning search results based off checkboxes I use the following code to filter data from SQL and it works fine. However, below code is vulnerable to SQL injection, but all the $post values are checkbox value (it's not user input).  So can I use below code?

Or do I need to use "prepared statement" as per this answer? I can only send number in array. 

Conn.php

    try {

    //create PDO connection 
    $conn = new PDO("mysql:host=" . DBHOST . ";port=3306;dbname=" . DBNAME, DBUSER, DBPASS);
    $conn-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $conn-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn-&gt;exec("SET CHARACTER SET utf8");
} catch (PDOException $e) {
    //show error
    echo '&lt;p class="bg-danger"&gt;' . $e-&gt;getMessage() . '&lt;/p&gt;';
    exit;
}


INDEX

&lt;div class="md-radio my-1"&gt;
     &lt;input type="radio" class="filter_all cate" name="cate" id="car" value="Car"&gt;
     &lt;label for="car"&gt;Car&lt;/label&gt;
&lt;/div&gt;


script

$(document).ready(function () {
            filter_data();
            function filter_data() {
                $('.filter_data');
                var action = 'fetch_data';
                var cate = get_filter('cate');
                $.ajax({
                    url: "fetch.php",
                    method: "POST",
                    data: {
                        action: action,
                        cate: cate
                    },
                    success: function (data) {
                        $('.filter_data').html(data);
                    }
                });
            }
            function get_filter(class_name) {
                var filter = [];
                $('.' + class_name + ':checked').each(function () {
                    filter.push($(this).val());
                });
                return filter;
            }
            $('.filter_all').click(function () {
                filter_data();
            });
        });


fetch.php

if (isset($_POST["action"])) {

 $query = "SELECT * FROM allpostdata WHERE sts = '1'";

if (isset($_POST["cate"])) {
    $cate = implode("','", $_POST["cate"]);
    $query .= "AND sca IN('" . $cate . "')";
}

$stmt = $conn-&gt;prepare($query);
$stmt-&gt;execute();
$result = $stmt-&gt;fetchAll();
$total_row = $stmt-&gt;rowCount();
$output = '';
if ($total_row &gt; 0) {
    foreach ($result as $row) {
    $output .= '&lt;a href="/single_view.php?p=' . $row['link'] . '&gt;' . $row['link']. '&lt;/a&gt;
 }
} else {
    $output = '&lt;h3&gt;No Data Found&lt;/h3&gt;';
}
echo $output;
}
Applying YCS's tutorial can't be dumbed down any further, so I suppose I'll write it out.

if (isset($_POST["action"])) {
    $query = "SELECT link FROM allpostdata WHERE sts = '1'";

    if (!empty($_POST["cate"])) {
        $query .= " AND sca IN (" . str_repeat("?,", count($_POST["cate"]) - 1) . "?)";
    } else {
        $_POST["cate"] = []; // in case it is not set 
    }

    $stmt = $conn-&gt;prepare($query);
    $stmt-&gt;execute($_POST["cate"]);
    $result = $stmt-&gt;fetchAll();
    if (!$result) {
        exit('&lt;h3&gt;No Data Found&lt;/h3&gt;');
    }
    foreach ($result as $row) {
        echo "&lt;a href=\"/single_view.php?p={$row['link']}\"&gt;{$row['link']}&lt;/a&gt;";
    }
}


I assume this will display your links side by side.  You may want to style them a bit to position the links in a user friendly fashion.

Additionally, $('.filter_data'); is doing nothing and can be removed.

I'd probably change the filter_data() declaration to something more brief:

function filter_data() {
    $.post(
       "fetch.php",
       {action: 'fetch_data', cate: get_filter('cate')}
    )
    .done(function(data) {
        $('.filter_data').html(data);
    });
}