Counting Page Visits on WordPress without Plugins

I remember dissecting moon rovers in my childhood, now I dissect WordPress plugins smile This time I was dealing with WP-PostViews - a plugin for counting visits to posts/pages in WordPress. The analysis was a success: I removed about 90% of the code, as it turned out to be unnecessary for my task.

This code is no longer supported!

I recommend using my own plugin. It includes:

  • More stable visit counting principles.
  • Visits count for taxonomies, main, and archives.
  • Visit chart (including unique visits).
  • Minimal data in the database (the database won't grow rapidly like in other plugins).
  • The counting process works with AJAX and is very fast - it doesn't burden the WP environment.
  • Designed to work with object caching plugins.
View the plugin

The only thing I always needed from this plugin was the number of page and post visits. I mean, I didn't have to display posts by highest view count. Moreover, the counter implemented in the plugin is weak for objective visit counting, and the functions offered by the plugin for displaying the most visited articles and so on turn into nonsense. The number of visits calculated by this plugin is just a general representation of page visits.

Regarding the aforementioned display of posts by highest visit count, this can be done using the WordPress function get_posts().

Why did I choose wp-postviews as the benchmark? Because it is one of the simplest in its kind - for comparison, an alternative to wp-postviews is the WordPress plugin WP-PostViews Plus - it is more advanced - creates its own table in the database, has more powerful visitor calculations (IP, Browser, etc.). In my opinion, such functionality is already excessive... After all, we are not collecting statistics, for that, there is analytics from Google or Yandex.

If you choose plugins for visit counting based on simplicity, then wp-postviews is probably the best... However, it is not without drawbacks - it is designed for global traffic and does not account for Yandex bots.

The plugin has settings where you can specify whose visits to count. My logic always told me that visits should only be counted for guests (non-logged-in users) and exclude search engine robots/bots. The exclusion principle of search engine bots and robots in the plugin is implemented a little wrong, because it excludes visits from the specified bots, and if a bot is not specified in the list, it will be counted as a visitor, which creates an unobjective counting. I decided to approach it from a different angle - not to exclude those who should not be counted, but to include those who should be counted, for this I simply specified browser identifiers. In my opinion, it's better to let the counter count strictly, but it will be known for sure that the numbers are "left" by real people, not all sorts of dirt like search engine bots. smile

Here is the function I ended up with - function for counting page visits on WordPress.

// Counting the number of page visits
add_action( 'wp_head', 'kama_postviews' );

/**
 * @param array $args
 *
 * @return null
 */
function kama_postviews( $args = [] ){
	global $user_ID, $post, $wpdb;

	if( ! $post || ! is_singular() )
		return;

	$rg = (object) wp_parse_args( $args, [
		// The meta-field key of the post where the number of views will be recorded.
		'meta_key' => 'views',
		// Whose visits to count? 0 - All. 1 - Only guests. 2 - Only registered users.
		'who_count' => 1,
		// Exclude bots, robots? 0 - no, let them also be counted. 1 - yes, exclude from counting.
		'exclude_bots' => true,
	] );

	$do_count = false;
	switch( $rg->who_count ){

		case 0:
			$do_count = true;
			break;
		case 1:
			if( ! $user_ID )
				$do_count = true;
			break;
		case 2:
			if( $user_ID )
				$do_count = true;
			break;
	}

	if( $do_count && $rg->exclude_bots ){

		$notbot = 'Mozilla|Opera'; // Chrome|Safari|Firefox|Netscape - all equal Mozilla
		$bot = 'Bot/|robot|Slurp/|yahoo';
		if(
			! preg_match( "/$notbot/i", $_SERVER['HTTP_USER_AGENT'] ) ||
			preg_match( "~$bot~i", $_SERVER['HTTP_USER_AGENT'] )
		){
			$do_count = false;
		}

	}

	if( $do_count ){

		$up = $wpdb->query( $wpdb->prepare(
			"UPDATE $wpdb->postmeta SET meta_value = (meta_value+1) WHERE post_id = %d AND meta_key = %s",
			$post->ID, $rg->meta_key
		) );

		if( ! $up ){
			add_post_meta( $post->ID, $rg->meta_key, 1, true );
		}

		wp_cache_delete( $post->ID, 'post_meta' );
	}

}

As per usual, insert the function into the functions.php file of your theme, and where you need to display the number of visits, use this:

Visits: <?php echo get_post_meta( $post->ID, 'views', true ); ?>

Inside the function, there are its settings: the name of the custom field, whom to count, and whether to exclude bots or not.

The name of the key is necessary so that it can be replaced with another plugin that also uses custom fields to record visits. For example, if a plugin was installed that changed the custom field named 'post_meta_name', then to replace it, you need to change the variable $meta_key in the function to 'post_meta_name' and replace 'views' when displaying the view count:

Visits: <?php echo get_post_meta( $post->ID, 'post_meta_name', true ); ?>