Skip to content
← Back to Functions
Code

Reading Time Estimator

Estimates human reading time from cleaned text and configurable words-per-minute.

Function signature

ogEstimateReadingTime(content, words_per_minute = 225, strip_code_blocks = true)

Categories

  • Developer Utilities

Parameters

contentSource content.words_per_minuteReading speed used for the estimate.strip_code_blocksWhether to remove pre/code blocks before counting.

Return value

Short public-safe status message.

  • word_count
  • minutes
  • label

Compatibility

Existing function name and call order preserved; metadata signature corrected to source.

Minimum PHP version: 7.4

Security notes

Validate request method, identity, permissions, and caller-owned allowlists before use; keep secrets and internal paths out of public output.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Estimates reading time from cleaned text and a words-per-minute setting.
 *
 * Code blocks can be removed before counting when the source is article HTML
 * or markdown-like content.
 *
 * @param string $content Source content.
 * @param int $words_per_minute Reading speed used for the estimate.
 * @param bool $strip_code_blocks Whether to remove pre/code blocks before counting.
 * @return array Structured result with word count, minutes, and label.
 */
function ogEstimateReadingTime($content, $words_per_minute = 225, $strip_code_blocks = true) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$content = (string)$content;
	$words_per_minute = (int)$words_per_minute;
	if ($words_per_minute < 100) {
		$words_per_minute = 225;
	}

	if ($strip_code_blocks) {
		$content = preg_replace('/<pre\b[^>]*>.*?<\/pre>/is', ' ', $content);
		$content = preg_replace('/<code\b[^>]*>.*?<\/code>/is', ' ', $content);
	}

	$text = html_entity_decode(strip_tags($content), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
	$text = preg_replace('/\s+/', ' ', trim($text));
	if ($text === '') {
		$result['message'] = 'No readable text supplied.';
		return $result;
	}

	$words = preg_split('/\s+/', $text);
	$word_count = count($words);
	$minutes = (int)ceil($word_count / $words_per_minute);
	if ($minutes < 1) {
		$minutes = 1;
	}

	$label = $minutes . ' minute read';
	if ($minutes != 1) {
		$label = $minutes . ' minute read';
	}

	$result['success'] = true;
	$result['message'] = 'Reading time estimated.';
	$result['data'] = array(
		'word_count' => $word_count,
		'minutes' => $minutes,
		'label' => $label
	);

	return $result;
}