Is the regular ajax request method safe or I should use admin-ajax.php?

On the homepage I have some links:

<a class="link" data-id="1">first link</a>
<a class="link" data-id="2">second link</a>
<a class="link" data-id="3">third link</a>

When one of these links is clicked, I want to send an ajax request to a php file to update the Database to increase views column of that post.

$(document).ready(function(){
    $(document).on('click', '.link', function(e){

        var post_id = $(this).data('id');

        $.ajax({ 
            url: "views.php",
            type: 'POST',
            data: {id: post_id},
            success: function(){
                alert("done");
        }}); // ajax

    }); // on click

}); // ready

In views.php:

//Check if the id is posted.
if( isset($_POST['id']) ){

    //Assigning the id to a variable.
    $id = $_POST['id'];

    //Check if the id is an integer.
    $pattern = '/[0-9]/';
    if( preg_match($pattern, $id) ){

        //Check that the user didn't visit that post before.
        $post_cookie="p_" . $id;
        if( !isset($_COOKIE[$post_cookie]) ){

            //Insert or update if the post id exists.
            $query = $conn->prepare('INSERT INTO posts (id, views) VALUES (:id, 1) ON DUPLICATE KEY UPDATE views = views+1');
            $query->bindValue(':id', $id, PDO::PARAM_INT);
            $query->execute();

            //Set a cookie with the post id to indicate that the post is viewed.
            setcookie( $post_cookie, '1');

        }// No cookie with that name (the user didn't visit that post).
    } // id matches the pattern.
} // id is posted.

I could use other options than the posts id to add/update the views, But I’m wondering if that way is safe or I should use admin-ajax.php.

The posts are custom posts from Database, Not WordPress posts

1 Answer
1

OMG… No, no, no!!! Never do that this way…

Why? There are many reasons…

  1. You won’t be able to do anything with users in your views.php – what if you’ll have to count only views by anonymous (not logged in) users?

  2. What if table_prefix is set to ”? Your posts table will cause conflicts…

  3. What if there are some plugins that operate on DB connection? You script will connect to wrong DB or cause other conflicts.

  4. What, if for security reasons your script won’t be runnable?

  5. There are many many other reasons, why you shouldn’t do it this way…

There is a reason for having best practices and standards. And life of all developers is way easier and nicer if everyone is coding according to these standards and practices… This way it’s easy to debug all AJAX calls, and so on…

So yes, you definitely should use admin-ajax.php and wp_localize_script, and $wpdb, and proper SQL escaping, and so on…

What’s the difference? won’t the ajax function be visible to the users?

Yes, it will be visible. But… It won’t be standard AJAX call – so it will be harder to understand…

Let’s make some quick experiment… Let’s take a look at these two codes:

1.

add_action( 'wp_ajax_get_post_status', 'ajax_get_post_status_callback' );
function ajax_get_post_status_callback() {
    $id = $_POST['id'];
    $post = get_post( $id );

    if ( $post ) {
        echo $post->post_status;
        die;
    }

    echo 0;
    die;
}

2.

include "ustawienia-polaczenia.php";
$i = $_POST['id'];
$wiersz = PostsQuery()::create()->filterById( array($i) )->find();
if ( $wiersz ) {
    echo $wiersz->post_status;
    die;
}

echo 0;
die;

Which one is easier to read? I bet the first one. Why? Because it uses WP core functions and everybody knows, how they work. I know (or I can easily check) what get_post function does, and so on. This code also respects all filters and actions – so it will generate no conflicts with other plugins…

On the other hand, the second code is just a mess… It includes some other file, it uses some strange DB connection (yes, it’s Propel). It’s even hard to guess if it’s the same DB or some other one and how exactly does it work. And it completely ignores any other plugins…

So yes – everyone will see that your code sends some strange AJAX and what file is responsible for processing it. The problem is that debugging your strange/custom code will consume much more time… And it’s much more probable that your code will create problems and conflicts…

Leave a Comment