Вы находитесь на странице: 1из 30

Blog  /   Development  /   Using AJAX With PHP...

Share on f t i g

Last updated May 30, 2017 ª 9 Comments

Using AJAX With PHP on Your WordPress Site Without
a Plugin

A jax is damn cool! It enables websites to load content into various elements without
refreshing the page. This may not seem like a huge feature list but it allows us to
do so much.

From up-voting to liking, from Disqus to Tweets, all these actions use Ajax to give you a seamless user experience.

It was made popular in 2005 by Google in their suggest feature, which gives you search suggestions as you type. This is not only a
seamless experience but would be completely impossible without AJAX.

In this article I’ll show you how to use Ajax in WordPress. It is a little more complicated than you may be used to, for good reason,
but if you have a good understanding of HTML, CSS and PHP, and rudimentary understanding of Javascript, you should be just ne.
Let’s get started.

Note: While this post provides a great guide to getting started with AJAX, if you want to level up your development skills why not check
out The Academy? There are courses on everything from WordPress development and learning PHP to starting an online business and
mastering Multisite. And if you’re an WPMU DEV member, joining The Academy is free!
How AJAX Works

Ajax is actually just Javascript. It is short for Asynchronous Javascript And XML. The reason it can quickly become a lot more
complex is that it is a technology meant as a bridge between your website and your server. This means that you will use it in
conjunction with the rest of your Javascript code, your CSS, HTML and perhaps even PHP.

The heart of Ajax is the XMLHttpRequest object, which exchanges data with the server. The whole process works a lot like
submitting a form. Here are the basic steps:

1. You specify information to send

2. You con gure the Ajax call

3. The XMLHttpRequest object is used to send the data to the server

4. The server response is returned and can be used by your JS code

Ajax is most commonly used through jQuery wrapper functions. If you would like to learn Ajax without jQuery I suggest taking a look
at the W3Schools Tutorial. Here we’ll be looking at the jQuery functions only.

Your First Ajax Call

Before we jump in, you will need a theme you can modify – a child theme or a plugin. I recommend a plugin and creating one is
super-simple. In a nutshell: create a folder in the wp-content/plugins directory, I named mine ajax-text . Within your folder

create a PHP le with the same name as the folder – mine is ajax-test.php . Paste the following code into this le:
1 <?php
3 /**
4 * Plugin Name: Ajax Test
5 * Plugin URI: http://danielpataki.com
6 * Description: This is a plugin that allows us to test Ajax functionality in WordPress
7 * Version: 1.0.0
8 * Author: Daniel Pataki
9 * Author URI: http://danielpataki.com
10 * License: GPL2
11 */

plugin.php hosted with ❤ by GitHub view raw

Once saved you should see your plugin pop up in the plugins section of the backend of your WordPress site. Go ahead and activate
it. If you would like to know a whole lot more about creating plugins in general, take a look at our plugin development guide.

Enqueueing Our JavaScript

We’ll need to add a JavaScript le to our plugin, which we’ll do by enqueueing it. This is easy to understand and simple to copy-paste
but if you want to know more we have a guide on enqueueing, too.

1 add_action( 'wp_enqueue_scripts', 'ajax_test_enqueue_scripts' );

2 function ajax_test_enqueue_scripts() {
3 wp_enqueue_script( 'test', plugins_url( '/test.js', __FILE__ ), array('jquery'), '1.0', true );
4 }

enqueue‑first.php hosted with ❤ by GitHub view raw

The code above adds a test.js script to our site. I’ve indicated that jQuery is a dependency and that it should be loaded in the
footer. Now let’s go in and create a simple Ajax call within the Javascript le.

Creating the Ajax Call

An Ajax call has a lot of parameters we can set. Take a look at all the available options on the jQuery Documentation page. We’ll stick
with the basics here:

1 jQuery(document).ready( function($) {
3 $.ajax({
4 url: "http://yourwebsite.com",
5 success: function( data ) {
6 alert( 'Your home page has ' + $(data).find('div').length + ' div elements.');
7 }
8 })
10 })

js‑first.js hosted with ❤ by GitHub view raw

All we’re doing is using the $.ajax() function and specifying some options. The url tells the Ajax call where to send the

request. The success parameter is a function which receives the response in the rst parameter.

The URL should point to your actual main page. If all is well, as soon as you reload the page you will receive a popup telling you how
many div elements you have on the page.
Alert box

This looks quite ugly but what we’ve done is actually loaded a completely separate page without re-loading the one we were on.

A Complete WordPress Ajax Example

WordPress does a lot more to help you with Ajax calls and to standardize how they are performed. Let’s replace that URL with
something more dynamic and create a better way to interact with the server. In this example we’ll take a look at how we can create a
“Love this post” function on your site.

I started a new plugin named “post-love” – I’ll have a zip le ready for you guys and it contains the whole plugin. You can download
it at the end of the article.

Storing And Displaying Our Data

We’ll be storing the number of “loves” a post has received in a meta eld in the database, let’s call it post_love . The value of this
eld will be displayed under each post in the single page, here’s how:

1 add_filter( 'the_content', 'post_love_display', 99 );

2 function post_love_display( $content ) {
3 $love_text = '';
5 if ( is_single() ) {
7 $love = get_post_meta( get_the_ID(), 'post_love', true );
8 $love = ( empty( $love ) ) ? 0 : $love;
10 $love_text = '<p class="love-received"><a class="love-button" href="#" data-id="' . get_the_ID() . '">give love</a><span id="l
12 }
14 return $content . $love_text;
16 }

content‑filter.php hosted with ❤ by GitHub view raw

By using the the_content lter we can display anything we’d like, right under the post content. I made sure to only do this on

single pages using the is_single() conditional function. I retrieved the love count from the post meta and made sure the value
was 0 if no love has been given yet.

I then used some HTML to create the display which consists of a link to give love and a span for showing the count. I also added the
ID of the post as a data parameter to the link. This will be used later. I then returned the content followed by our text.
It looks very basic, so let’s give it a little style by enqueueing a stylesheet and adding some styles. First the enqueue:

1 add_action( 'wp_enqueue_scripts', 'post_love_assets' );

2 function post_love_assets() {
3 if( is_single() ) {
4 wp_enqueue_style( 'love', plugins_url( '/love.css', __FILE__ ) );
5 }

style.php hosted with ❤ by GitHub view raw

Note that I use the is_single() conditional tag here as well. There’s no sense in loading our stylesheet on any other page since it

won’t be used. This enables us to minimize the effect of our plugin on the site’s loading time. Create the love.css le in the

plugin directory and use the following CSS to give it some style.

1 .entry-content .love-button {
2 background: #f14864;
3 color: #fff;
4 padding:11px 22px;
5 display:inline-block;
6 border:0px;
7 text-decoration: none;
8 box-shadow: 0px 6px #d2234c;
9 position:relative;
10 }
12 .entry-content .love-button:hover{
13 top:3px;
14 box-shadow: 0px 3px #d2234c;
15 }
17 .entry-content .love-button:active{
18 top:6px;
19 box-shadow: none;
20 }
23 #love-count {
24 background: #eee;
25 box-shadow: 0px 6px #ddd;
26 color: #666;
27 padding:11px 22px;
28 display:inline-block;
29 }

style.css hosted with ❤ by GitHub view raw

The end result should be a nice button with a 3D effect and a counter next to it, like you see below.

WP Checkup
by wpmudev
Enter URL and scan performance, security and SEO
Our little love button

The Ajax Call

Next, let’s assemble the Ajax call. This involves enqueueing our script and writing the Javascript. Before do that, let’s discuss the
url parameter of the Ajax call. In our last example I hard-coded the url. We can’t do that in a proper plugin or theme because
everyone has a different site URL.
Luckily WordPress is here to help. It gives us a uni ed le to use – wp-admin/admin-ajax.php and the means to grab the full URL
of the le. It involves a little trick while enqueueing, here’s how it’s done:

1 add_action( 'wp_enqueue_scripts', 'ajax_test_enqueue_scripts' );

2 function ajax_test_enqueue_scripts() {
3 if( is_single() ) {
4 wp_enqueue_style( 'love', plugins_url( '/love.css', __FILE__ ) );
5 }
7 wp_enqueue_script( 'love', plugins_url( '/love.js', __FILE__ ), array('jquery'), '1.0', true );
9 wp_localize_script( 'love', 'postlove', array(
10 'ajax_url' => admin_url( 'admin-ajax.php' )
11 ));
13 }

localize.php hosted with ❤ by GitHub view raw

As you can see, I registered the JavaScript le as usual. Then I used the wp_localize_script() function to pass a string to our
script. This function was originally meant to add translation support to Javascript les – you can add as many strings as you like in
that array. In our script we’ll be able to use postlove.ajax_url to output the URL of the admin-ajax.php le, let’s do that now.

1.6 million WordPress Superheroes read and trust our blog. Join them and get daily posts delivered to
your inbox - free!

Email address SUBSCRIBE

1 jQuery( document ).on( 'click', '.love-button', function() {
2 var post_id = jQuery(this).data('id');
3 jQuery.ajax({
4 url : postlove.ajax_url,
5 type : 'post',
6 data : {
7 action : 'post_love_add_love',
8 post_id : post_id
9 },
10 success : function( response ) {
11 alert(response)
12 }
13 });
14 })

love‑basic‑ajax.js hosted with ❤ by GitHub view raw

This isn’t the nal version just yet but communicates with the server just ne. First of all, we execute a function whenever we click
on a “give love” button. We grab the ID of the current post and store it in the post_id variable.

Next we build an Ajax call. The URL uses the postlove.ajax_url discussed above. I set the type to post which is the

equivalent of setting a form to the same value. If you use “post” you can retrieve the data sent via $_POST , if you use “get” you

can grab it with $_GET .

The data section holds any parameters you want to send yourself. We need to send the post ID so we know which post to attribute
the love to. WordPress also requires us to send an action when using the admin-ajax.php le. Keep in mind that we’ve set this to
‘post_love_add_love’. Finally, we simply alert the response in the success function.

If you try it out now the alert will show 0 which is perfectly ne, it actually means all is well! If an action hook is not de ned for our
set action (we’ll do this in the next step) the admin-ajax le exists and returns 0 – which is what is happening.

Server Side Processing

At this stage we are sending things to the server but we need to tell the server what to do with our data. We should increment the
love counter meta box by one and return the new value. To create a facility for processing data arriving via AJAX we’ll need to use
two hooks:

1 add_action( 'wp_ajax_nopriv_post_love_add_love', 'post_love_add_love' );

2 add_action( 'wp_ajax_post_love_add_love', 'post_love_add_love' );
4 function post_love_add_love() {
6 }

hooks.php hosted with ❤ by GitHub view raw

The rst hook is executed for guest users, the second for logged in users. This is a great way to control access by the way! The
convention is this:
Remember how we de ned an action parameter in our Ajax call? This needs to be appended to wp_ajax_ and/or

wp_ajax_nopriv_ . The function can be named anything, I just used the same string as the action name for consistency. Let’s
move on and create the incrementing functionality.

1 add_action( 'wp_ajax_nopriv_post_love_add_love', 'post_love_add_love' );

2 add_action( 'wp_ajax_post_love_add_love', 'post_love_add_love' );
4 function post_love_add_love() {
5 $love = get_post_meta( $_POST['post_id'], 'post_love', true );
6 $love++;
7 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
8 update_post_meta( $_POST['post_id'], 'post_love', $love );
9 echo $love;
10 }
11 die();
12 }

post‑love.php hosted with ❤ by GitHub view raw

Nothing special going on here. The current value is retrieved, incremented and saved. We echo the value, this will be the response.
The only thing to note is that you must use die() at the end. If you don’t, admin-ajax.php will execute it’s own die(0)

code, echoing an additional zero in your response.

If you press the button now you should see the new love value being alerted. Reload the page and the button should re ect it as
well. Functionality-wise we are nearly there, we just need to make sure the count changes without needing to reload the page. From
here on out this is easy JS, here’s the full Ajax call with the count change built in:

1 jQuery( document ).on( 'click', '.love-button', function() {

2 var post_id = jQuery(this).data('id');
3 jQuery.ajax({
4 url : postlove.ajax_url,
5 type : 'post',
6 data : {
7 action : 'post_love_add_love',
8 post_id : post_id
9 },
10 success : function( response ) {
11 jQuery('#love-count').html( response );
12 }
13 });
14 })

post‑love.js hosted with ❤ by GitHub view raw

With that nal bit added the button now shows the correct count after it is clicked, we’re all done. Or are we?

Graceful Fallback

Making our element a link is not very semantic of us since it isn’t actually a link. The reason I decided to do so is that if someone
doesn’t have Ajax enabled, why not make this link work all the same? We need to modify things slightly but not a lot:

First of all, we need to do is make the target URL the same as the target of our Ajax call:
http://yourwebsite.com/wp-admin/admin-ajax.php?action=post_love_add_love&post_id=23 . Here’s what the nal version looks

1 add_filter( 'the_content', 'post_love_display', 99 );

2 function post_love_display( $content ) {
3 $love_text = '';
5 if ( is_single() ) {
7 $love = get_post_meta( get_the_ID(), 'post_love', true );
8 $love = ( empty( $love ) ) ? 0 : $love;
10 $love_text = '<p class="love-received"><a class="love-button" href="' . admin_url( 'admin-ajax.php?action=post_love_add_love&p
12 }
14 return $content . $love_text;
16 }

final‑display.php hosted with ❤ by GitHub view raw

Since our URL is now not # we need to return false at the end of our click event to make sure the URL isn’t followed for users
who have Javascript enabled.

1 jQuery( document ).on( 'click', '.love-button', function() {

2 var post_id = jQuery(this).data('id');
3 jQuery.ajax({
4 url : postlove.ajax_url,
5 type : 'post',
6 data : {
7 action : 'post_love_add_love',
8 post_id : post_id
9 },
10 success : function( response ) {
11 jQuery('#love-count').html( response );
12 }
13 });
15 return false;
16 })

final‑js.js hosted with ❤ by GitHub view raw

The nal step is to differentiate between Ajax and non-Ajax operations in our post_love_add_love() function. When Ajax is used
the new value needs to be echoed, the script needs to die. When Ajax is not used (ie: the user is redirected to admin-ajax) we need
to simply redirect back to the article after we run our script. Here’s the nal version of our post_love_add_love() function:

1 function post_love_add_love() {
2 $love = get_post_meta( $_REQUEST['post_id'], 'post_love', true );
3 $love++;
4 update_post_meta( $_REQUEST['post_id'], 'post_love', $love );
5 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
6 echo $love;
7 die();
8 }
9 else {
10 wp_redirect( get_permalink( $_REQUEST['post_id'] ) );
11 exit();
12 }
13 }

increment‑final.php hosted with ❤ by GitHub view raw

I’ve changed the $_POST variables to $_REQUEST since Ajax users will use post while others will use get. The $_REQUEST

variables allows access to our data whichever the case.

With that you’ve completed this tutorial, you now have a great button to get some love for your posts. In the conclusion I’ll share the
download link for the full plugin I’ve created.

There’s More To Do!

As I mentioned, Ajax isn’t hard but there are a lot of simple things you need to know. Here are the two most important aspects of
using Ajax once you have the basics down:


Security can be a big issue with Ajax if you’re not careful. Our button doesn’t check for multiple clicks so you could just sit there
clicking it and incrementing the value all day. Aside from skewing results it could result in a higher server load, especially if a couple
of people do it at once.

In addition, you wouldn’t even have to click the button. Just by visiting
http://yourwebsite.com/wp-admin/admin-ajax.php?action=post_love_add_love&post_id=23 you could increment the counter.

While our button could only cause minimal harm, some plugins allow you to delete posts from the front-end. What if there was a
URL you could visit to accomplish the same thing? Not an idea situation.

One way to prevent these security holes from opening up is to use nonces. Nonces are a way of securing forms and links from
malicious attempts.
User Interface and Experience

Another important aspect of Ajax is user experience. The whole premise of the technology is that the user gets more interactivity
and less loading time. This also means that you need to put a lot of work into your Ajax functionality to make sure they really do
improve the experience.

Users should always know what is happening and why. If I were creating this plugin for the repository the rst thing I would do is
add a loading state, during which it is impossible to press the button. The beforeSend parameter of the $.ajax() function
allows us to execute some code before the data is sent to the server.

In this function I would add the loading state and disable the button. Upon success the button would pop back to its normal state
and be usable once again.

It may also be advisable to add some sort of visual cue to the number change. If the user doesn’t know what to expect, they may not
notice what’s changed. A little shake or a highlight could do the trick.

Be very careful not to gravitate toward the other extreme. With the advent of Ajax and animation techniques people tended to make
everything move, animate and do unnecessary things. Never make your users wait for the animation to end and only add JS eye-
candy where it makes sense, otherwise the user experience will be lowered, not raised.


Ajax is a powerful tool in a developers tool belt to add interactivity and to lower server strain. It opens countless doors, such as
allowing your comments to appear without reloading, in nite scrolling for posts, lazy-loading images, and so much more.
As long as you use it where necessary and take the time to round off your Ajax calls with some UI details, Ajax will make your
applications that much better.

If you’d like to see the plugin as a whole you are welcome to download it, learn a little something from it and also use it on your

Do you use Ajax on your site? Let us know in the comments below.

Related Posts

How to Use AJAX in WordPress to Load Search Results Loading WordPress Posts Dynamically With AJAX

Keeping WordPress Safe – Security 101 WordPress Development for Beginners: Getting Started

Related Projects
P Hummingbird PDefender
Everything you need to… Regular security scans, vulnerability…

P Snapshot Pro P WP Smush Pro

The automated, on-demand time-traveler… Incredibly ef cient image optimization…

9 Responses


1 1 pts 2 1 pts 3 Level 0

Great tutorial. I was looking to nd out more about WP and ajax – so thanks!

March 18, 2015, 6:22 pm


1 3 pts 2 0 pts 3 Level 0

Therefore i’m never using Ajax, but from now i must learn it. Okay for HTML i got
it, PHP just a little, i think i can learn Ajax syntaks too.

March 20, 2015, 12:16 am


1 6 pts 2 3 pts 3 Level 0

Great tutorial, easy to follow. Now I get basic understanding of ajax.

March 27, 2015, 3:06 am


1 0 pts 2 0 pts 3 Level 0

There are no ‘Loves’ on any posts.

It is not working!

April 12, 2015, 6:41 pm


1 0 pts 2 0 pts 3 Level 0

This doesn’t seem to work for logged out users? I’m using a completely stripped
out theme with no plugins other than this demo and Hello World news post.

April 16, 2015, 12:34 am

Daniel Pataki AUTHOR

1 32 pts 2 77 pts 3 Level 3

Hi Devon,

As long as you use both the wp_ajax_ and wp_ajax_nopriv hooks it should work
for both.


April 16, 2015, 1:53 am


1 1 pts 2 2 pts 3 Level 0

Hi Daniel, how are you. Thanks for the tutorial however Devon and Jaek are
right in that this plugin doesn’t work as it’s described in the above steps.
There are differences between the code in the tutorial here and the code in
the provided download. I don’t think I can paste code snippets here so I’ll
direct you to the differences. In the tutorial, when we rst create the
post_love_add_love function, we’re told that if we click the button we’ll see a
response and reloading the page should re ect the new love count value.
This doesn’t happen. We don’t see this new value until we’ve implemented
the if( de ned( ‘DOING_AJAX’ ) && DOING_AJAX ) functionality which doesn’t
happen until much later in the tutorial. So while the tutorial is right, the way in
which it’s written needs to be revised. HTH

June 8, 2015, 2:04 pm


1 1 pts 2 1 pts 3 Level 0

Hi. New to Ajax so excuse my stupidity.

If you were to have multiple buttons on the same page into DIVs with varying IDs
(say, based on the post ID), how would you add that to jQuery(‘#love-count’).html(
response ); ? I can see that you can snatch that var from the serialised data with
var post_id = jQuery(this).data(‘id’); but can’t work out how it’s used.
Also, where you’ve used var post_id = jQuery(this).data(‘id’);, what is the meaning
of data? I can’t nd a reference why that was used in the docs.

January 13, 2016, 7:10 am


1 2 pts 2 2 pts 3 Level 0

If you need a great plugin for navigation try Zajax.

Zajax is a WordPress plugin who add ajax navigation to your WordPress website.
It will work with search, All form will work, like comments, it will understand links
with # hash and external links or admin links. Beautifull loading bar at the top and
a loading circle in the center. (Look like mobile loading from Android). Some
differences with others ajax pluging. Zajax work with Google analytics, it will
work with all form, input, comments ect.. Preload pages on mouse hover for
instant loading with the Zajax-pro version.

November 5, 2016, 2:11 pm

Comments are closed.

Join WPMU DEV to get everything you need
for WordPress, on unlimited sites, for one low price.
Security - Performance - Themes - 100+ Plugins - Backups - Marketing & SEO - Expert WP Support


Plugins Themes Resources Blog

Performance Theme Builder 24/7 Support Academy 7 Best Sites to Find CSS Snippets and Inspiration

Security Spirit Contact The Team We’re Giving You The WhiP VIP Absolutely Free!

Marketing Luke & Sara Jobs & Pros Documentation Fake WordPress Plugins: What You Need to Know

Backups Parrot Exclusive Newsletter Product Roadmap More...

More... More...

1 2 3 ,4 5 6 happy members ‹ © 2004-2017 Project by Incsub | Terms & Privacy f t g m