How to Use AJAX With PHP on Your WordPress Site Without a Plugin

When using WordPress as a CMS, situations often arise where you need to display, add or update content on your WP site without turning to plugins. While bolting in some PHP alone can do the job, nothing is more seamless that the magic of jQuery’s AJAX.

While there are plenty of sources on the Web that cover this topic, when I first began developing for WordPress I was left scratching my head understanding methods that made the process easy and within WordPress best practices. Fortunately once you understand a few basic resources you can tap into, AJAXifying your WP site couldn’t be easier.

NOTE: This article assumes you have a good understanding of jQuery and AJAX (and of course, PHP). If not, this article is a good tutorial.

Step 1 – enabling the WordPress AJAX handler
As part of its core, WordPress includes a handler file called “admin-ajax.php” to facilitate all things AJAX. This file will allow you to use jQuery to call PHP functions much like an API.

To utilize admin-ajax.php you need to instantiate it using WordPress’ wp_localize_script() function. The best place to do this is in your theme’s functions.php file. In functions.php, create a function and add the following:

function your_function_name() 
{

     wp_localize_script( 'function', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );

}

You can change your_function_name(), ‘function’ and ‘my_ajax_script’ to whatever you like. We’ll cover these more in depth shortly.

Step 2 – create your PHP functions
Next you’ll want to create some PHP functions you can invoke within your AJAX call. You can place these directly in your functions.php page, but I generally like to create a separate PHP file and include it. For example, if you create a PHP file called MyFunctions.php, you’ll want to add it to your functions.php file like:

$dirName = dirname(__FILE__);
$baseName = basename(realpath($dirName));
require_once ("$dirName/MyFunctions.php");

Where MyFunctions.php is in the same folder as functions.php. If you’re using a theme you didn’t write, be sure to check if other files are being included and simply include your new PHP functions file in the same place.

Your PHP functions can obviously be anything you’d like. A call to a table you’ve created, grabbing or adding values from the wp_options table, etc. For example:

function get_my_option()
{
     $var = get_option('my_var');
     echo json_encode($var);
     die();
}

Here I’m grabbing a value from the wp_options table then outputting it in JSON format by wrapping it in PHP’s json_encode() function so jQuery can consume and display the value on my site. Notice that I’ve added the die() function at the end. I’ve done this because without this function, admin-ajax.php will append the value outputted with a “0”—obviously not something you want.

This is clearly an oversimplified example. I’m sure you’ll come up with something much more useful! :-)

For each PHP function you create, you’ll want to declare it in functions.php using WP’s add_action() hook. This ensures you can call the functions via AJAX when you want to use them.

For my get_my_option() function, I’ll add the following:

add_action("wp_ajax_nopriv_get_my_option", "get_my_option");

The first parameter tells WP I want to use AJAX to call my PHP function by first typing “wp_ajax_nopriv_” and following it with my function name. The “nopriv” part indicates that I want to make this function available for non logged-in users (on the front-end). If I want to make the function available regardless of login state or in the WP admin, add the following:

add_action("wp_ajax_nopriv_get_my_option", "get_my_option");
add_action("wp_ajax_get_my_option", "get_my_option");

If you have more than one PHP function, just continue to add them using the add_action() hook.

Step 3 – add your JavaScript
The next thing I want to do is write some JavaScript where I can call my PHP function and do something with it. You’ll want to create an external file for your JS, then tell WP you want to use it (we’ll cover what’s in the file in step 4). For this, I’ll use WP’s wp_enqueue_script() function:

wp_enqueue_script( 'function', get_template_directory_uri().'/my_js_stuff.js', 'jquery', true);

Note in the first part ‘function’ needs to match the name you used when you localized admin-ajax.php. So if you changed that, used the same name here. Next, I’m using WP’s get_template_directory_uri() function to get the path to my theme directory, then giving it the name of my JS file, again, being relative to the functions.php file. Lastly, I’m telling WP that this file depends on jQuery, so if jQuery isn’t already being called to my WP site, it will now.

With this addition we’re just about ready to go. We just need to add another action hook to initiate the function we created earlier in functions.php:

add_action('template_redirect', 'your_function_name');

The ‘template_redirect’ tells WP to run this function before loading the template file and ensures the admin-ajax.php file and my_stuff.js will be properly added to the ‹head› portion of your site. You can place the action hook before or after your function. Our final code in functions.php looks like this:

function your_function_ name()
{

     wp_localize_script( 'function', 'my_ajax_script', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
     wp_enqueue_script( 'function', get_template_directory_uri().'/my_js_stuff.js', 'jquery', true);

}
add_action('template_redirect', 'your_function_ name');

$dirName = dirname(__FILE__);
$baseName = basename(realpath($dirName));
require_once ("$dirName/MyFunctions.php");

add_action("wp_ajax_nopriv_get_my_option", "get_my_option");
add_action("wp_ajax_get_my_option", "get_my_option");

Step 4 – call your PHP function using jQuery
Now it’s on to our JS file! In the my_js_stuff.js file, we’ll want to create at least one JS function. In order to invoke our PHP function we’ll structure it as:

function my_js_function() 
{
     jQuery.ajax({
     url: my_ajax_script.ajaxurl,
     data: ({action : 'get_my_option'}),
     success: function() {
      //Do stuff here
     }
     });
}

Notice for “url:” we’re using the function name of my_ajax_script we declared when we instantiated admin-ajax.php using WP’s wp_localize_script() function. This tells WP that we want to use admin-ajax.php to process the PHP function we declare on the next line: data: ({action : ‘get_my_option’}),

If your PHP function is expecting additional request variables, you’ll also want to pass these in the data: line separated by commas. Like:

data: ({action : 'get_my_option', id: 26, name: ‘Bob’}),

Obviously there’s lots more you can add to your JS. For example if you’re posting variables to be stored in a table, you’ll probably want to add type: ‘POST’ and then handle any data your PHP functions returns in the success() function of your JS. You can always use a beforeSend() function if you want to display an AJAX spinner while your PHP function is being called.

Lastly, you can call your JS function from anywhere on your WP site in your HTML. Perhaps you have a Page Template you’ve created specifically for this purpose. Or you can modify any of your theme files like index.php, single.php or page.php. Invoke the JS function using an onclick method, or a click function in your JS—whatever makes sense.

There you have it. With a few simple steps, you’ll be slinging AJAX around your WP site like a pro! Happy coding.

Comments (21)

  1. Thank you for this article. I have created a nice login and sign-up page with no-page-reload validation using jQuery, but then discovered that $.ajax() doesn’t work out of the box in WordPress. So, hopefully I can get your solution to work, so I can use $.ajax() within wordpress.

    I have created a test on a wordpress installation with almost exactly the code you use above. I have kept all the ‘your_function_name’ and ‘my_ajax_script’ as you have it. I have only changed…$dirName = get_stylesheet_directory(); AND get_stylesheet_directory_uri().’/my_js_stuff.js’. This is because I’m using a Child Theme.

    When I view the source I can see that my_js_stuff.js has been added to the head properly.

    I added a button to my page like this: Try it.

    When I click the button, I get the following error in the Chrome Developer Console: Uncaught ReferenceError: my_ajax_script is not defined.

    Any thoughts on what I might be doing wrong and how I can fix it? Thanks!

        • Hey guys. Sorry you’re having issues. Right-click and look at the source of your pages. In the section, you should see something like this:

          var ajaxurl = ‘http://YOURWEBSITE.com/wp-admin/admin-ajax.php’;

          That code definitely needs to be in the head of your HTML, and based on the article it should be. If not, I can post an alternate method of putting it in there…

          • Thanks David for your response.

            I’m getting the following in my head:

            var my_ajax_script = {“ajaxurl”:”http:\/\/MYWEBSITE.com\/courses\/wp-admin\/admin-ajax.php”};

            The wordpress installation is in /courses. If I open this URL in my browser I get a ’0′, which I think is a good indicator that I am in fact getting to admin-ajax.php.

            So given what I’m getting, should the following be working in the jQuery.ajax():

            url: my_ajax_script.ajaxurl,

            Any other thoughts?

          • Hopefully this will work:

            LT =

            LTscript type=’text/javascript’GT
            /* LT![CDATA[ */
            var my_ajax_script = {"ajaxurl":"http:\/\/mymagicaljourney.com\/courses\/wp-admin\/admin-ajax.php"};
            /* ]]GT */
            LT/scriptGT

  2. Got it working!

    I had wrapped – function my_js_function() in a jQuery(document).ready(function($) { code });.

    Once I removed the jQuery wrapper it worked.

    Now I’ll be migrating what I learned over to my actual project. I really hope I can get this to work, because not being able to use $.ajax() in WordPress would be a real bummer!

    Sorry for all the comments trying to get my code to appear correctly. Feel free to delete any of them.

    Thanks David!

    • There is BUG ! & here follows the FIX !!

      # Replace the following function
      ———————————-
      function your_function_ name(){
      wp_localize_script( ‘function’, ‘my_ajax_script’, array( ‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ) ) );
      wp_enqueue_script( ‘function’, get_template_directory_uri().’/my_js_stuff.js’, ‘jquery’, true);
      }
      ———————————
      # with
      ———————————
      function your_function_name(){
      // Need to check why localize script is not working..
      wp_enqueue_script( ‘function’, get_template_directory_uri().’/my_js_stuff.js’, ‘jquery’, true);
      wp_localize_script( ‘function’, ‘my_ajax_script’, array( ‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ) ) );
      }
      ———————————

      ## STRICTLY Remember : ” wp_localize_script() must be decleared after the declearing the script which going to use the localized object.”

      Wish u HAPPY WP AJAXING !

      :)

  3. Hi David,

    I have been searching for a solution and have tried many that I found but can’t seem to get things working. Maybe you can give me a tip? Code Below

    Functions.php code:

    function add_myjavascript(){
    wp_enqueue_script( ‘ajax-implementation’, get_bloginfo(‘template_directory’) . “/js/ajax-implementation.js”, array( ‘jquery’ ), true );
    wp_localize_script( ‘ajax-implementation’, ‘my_ajax_script’, array( ‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ) ) );
    }

    add_action( ‘template_redirect’, ‘add_myjavascript’ );

    function myajax_submit(){
    $response = json_encode( array( ‘success’ => true ) );

    header( “Content-Type: application/json” );
    echo $response;

    exit;
    /*check_ajax_referer( ‘my-special-string’, $_POST['security'] );*/
    /*$headers = ‘From: Ellett Exterminator ‘ . “\r\n”;
    wp_mail( ‘[email protected]’, ‘Contact Me Request’, $_POST['form_name'] . ‘ has requested a call. Phone number:’ . $_POST['form_phone'], $headers );*/
    }

    add_action( ‘wp_ajax_nopriv_myajax_submit’, ‘myajax_submit’ );
    add_action( ‘wp_ajax_myajax_submit’, ‘myajax_submit’ );

    Javascript file code:

    jQuery(function($) {

    $(“#call-submit”).click(function(){
    /*jQuery.post(
    // see tip #1 for how we declare global javascript variables
    MyAjax.ajaxurl,
    {
    // here we declare the parameters to send along with the request
    // this means the following action hooks will be fired:
    // wp_ajax_nopriv_myajax-submit and wp_ajax_myajax-submit
    action : ‘myajax-submit’,

    // other parameters can be added along with “action”
    postID : MyAjax.postID
    },
    function( response ) {
    alert( response );
    }
    );*/
    $.ajax({
    type: ‘POST’,
    url: my_ajax_script.ajaxurl,
    dataType: ‘json’,
    data: {
    action: ‘myajax_submit’,
    form_name: ‘Brian’,
    form_phone: ’9876746363′
    },
    success: function(data, textStatus, XMLHttpRequest){
    alert(‘Thank you for your submission.’);
    },
    error: function(MLHttpRequest, textStatus, errorThrown){
    alert( textStatus );
    }
    });
    });
    });

    • As long as your page use a permalink, yes, search engines can crawl pages that are populated via AJAX. What gets tricky is when you’re passing parameters in the URL and not giving Google links in your content to crawl that. Just make sure the page is crawlable and you should be fine.

  4. hello david,
    great article!

    i adapted this way for my wordpress site. but the js-methods won’t work. in my case, i have a html-site in wordpress with a form, from where i want to execute the php-file. this php-file connects to an remote postgresql database to store strings from textfields.

    here are my (cleaned&simplified) code snippets:

    HTML-CODE ON WP-SITE:

    /* */

    …some style for my divs…

    [inline]
    …some js.code to create divs with textboxes…
    [/inline]

    …some elements like select, options etc. …

    PHP-CODE IN (inside functions.php file):

    function add_criteria_to_pgdb(){
    $db = pg_connect(“host=$hostadress port=$port dbname=$dbname user=$user password=$pw”);
    …filling data in vars($nextid,$okList)…
    query = “INSERT INTO criteriatable(cid,projectname,oklist) VALUES($nextid,’icetrasse’,'$okList’)”;
    $result = pg_query($db, $query);
    }

    JS-CODE (outsourced in dir of functions.php, named ‘call_DB_PHP_FILE.js’):

    function call_php_file(){
    // for testing purposes just an alert
    alert(‘hola back girl’);
    }

    added functions.php (from responsive-theme) CODE:

    function send_criteria_function()
    {

    // wp_enqueue_script( ‘function’, get_template_directory_uri().’/call_DB_PHP_FILE.js’, ‘jquery’, true);
    wp_enqueue_script( ‘function’, get_template_directory().’/call_DB_PHP_FILE.js’, ‘jquery’, true);
    wp_localize_script( ‘function’, ‘my_ajax_script’, array( ‘ajaxurl’ => admin_url( ‘admin-ajax.php’ ) ) );

    }
    add_action(‘template_redirect’, ‘send_criteria_function’);

    function add_criteria_to_pgdb(){
    …php-code -> see above…
    }

    add_action(“wp_ajax_nopriv_add_criteria_to_pgdb”, “add_criteria_to_pgdb”);
    add_action(“wp_ajax_add_criteria_to_pgdb”, “add_criteria_to_pgdb”);

    MY QUESTIONS:
    where do i have to put the js-method (‘call_php_file()’) into? in input with type=submit, or can i put it (like above in html-code) in onclick from a button? or should i use it in script-tag in the header (where the other js-code is)?

    i will be very thankful for any help!

    ciao,
    david

  5. oops, my HTML-code isn’t there?!

    here is it:

    /* */

    …some style for my divs…

    [inline]
    …some js.code to create divs with textboxes…
    [/inline]

    …some elements like select, options etc. …

    • (in general in forums) for which reason get the html-tags removed?
      i hope this works:

      //
      //
      //
      //
      // /* */
      //
      // …some style for my divs…
      //
      [inline]
      …some js.code to create divs with textboxes…
      [/inline]
      //
      //
      //
      //
      //
      //
      //
      …some elements like select, options etc. …
      //
      //
      //
      //
      //
      //
      //
      //
      //
      //

      sorry for spamming, but there’re maybe important parts in the html-code (just imagine, there are no comments^^)

  6. ok, last try: inserting # for arrow signs^^:

    #html#
    #head#
    #meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″#
    #script type=’text/javascript’#
    /* #![CDATA[ */
    var my_ajax_script = {"ajaxurl":"http:\/\/130.83.41.43\/wordpress\/wp-admin\/admin-ajax.php"};
    /* ]]# */
    #/script#
    #style# …some style for my divs… #/style#
    #script type=’text/javascript’#
    [inline]
    …some js.code to create divs with textboxes…
    [/inline]
    #/script#
    #/head#
    #!–raw–#
    #body#
    #div id=”body_div” align=”center” style=’width:580px;’#
    #form name=”oks” id=”mainform” class=”form_div” style=”width:600;background-color: gray;padding:1px”#
    #p#
    …some elements like select, options etc. …
    #p#
    #p align=”center”#
    #input id=”btnCreateDivs” type=”button” value=”Create Divs” onclick=”createDivs();”/#
    #input type=’button’ id=’saveDataInDB’ onclick=’call_php_file()’ value=’save data in db’ style=’margin-left:35px;width:250px’ disabled/#
    #br##/p#
    #/form#
    #div#
    #/body#
    #!–/raw–#
    #/html#

    (really sorry for spamming)

  7. Hi All,
    I am very very new to wordpress, i can just create the page , now my requirment is using ajax. Your post is good and i understood , but i struct at one point that i dont know where to call ajax in page. For example in my page have one button , when i click the button, ajax function get call. Simplly says i need that line of code in page how to call ajax as like simple ajax call in HTML&Javascrip or jQuery. Pls help me.

Participate