Skip to content
← Back to Functions
Code

Trailing Slash Canonicalizer

Determines whether a path should redirect to slashless or slashed canonical form.

Function signature

ogCanonicalizeTrailingSlash(request_path, request_method = 'GET', options = array())

Categories

  • Security

Parameters

request_pathIncoming request path to match or canonicalize.request_methodHTTP method used to avoid redirecting state-changing requests.optionsOptional documented policy controls for the helper.

Return value

Public-safe status string returned by the function for controller branching or logging.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and context-specific escaping; validate file paths, routes, email tokens, cart totals, discount rules, and tax-region rules before production use.

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.
 */

/**
 * Determines whether a path should redirect to slashless or slashed canonical form.
 *
 * Primary use case: Routing and .htaccess logic support.
 * Typical inputs: request path, route policy.
 * Typical output: redirect target or none.
 *
 * Implementation note: Do not redirect POST requests blindly.
 *
 * @param string $request_path Incoming path.
 * @param string $request_method HTTP request method.
 * @param array $options Canonicalization options.
 * @return array Redirect decision data.
 */
function ogCanonicalizeTrailingSlash($request_path, $request_method = 'GET', $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	$request_path = parse_url((string)$request_path, PHP_URL_PATH);
	$request_path = '/' . trim((string)$request_path, '/');
	$request_method = strtoupper(trim((string)$request_method));

	if (!is_array($options)) {
		$options = array();
	}

	if ($request_path === '/') {
		$result['success'] = true;
		$result['message'] = 'Homepage path is already canonical.';
		$result['data'] = array('redirect' => false, 'target' => '/');
		return $result;
	}

	if ($request_method != 'GET' && $request_method != 'HEAD') {
		$result['success'] = true;
		$result['message'] = 'Unsafe method was not redirected.';
		$result['data'] = array('redirect' => false, 'target' => $request_path);
		return $result;
	}

	$slashless = true;
	if (isset($options['slashless']) && $options['slashless'] === false) {
		$slashless = false;
	}

	$target = $request_path;
	if ($slashless) {
		$target = rtrim($request_path, '/');
	} else {
		$target = rtrim($request_path, '/') . '/';
	}

	$result['success'] = true;
	$result['message'] = 'Trailing slash policy evaluated.';
	$result['data'] = array(
		'redirect' => ($target != $request_path),
		'target' => $target,
		'original' => $request_path
	);

	return $result;
}