Skip to content
← Back to Functions
Code

Username Policy Validator

Validates usernames for length, allowed characters, reserved names, and impersonation risks.

Function signature

ogValidateUsernamePolicy(username, options = array())

Categories

  • Forms and Validation

Parameters

usernameRaw username.optionsOptional min_length, max_length, and reserved names. Recognized keys: `max_length`, `min_length`, `reserved`.

Return value

Short public-safe status message.

  • username
  • normalized_username
  • errors

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

/**
 * Validates a username for length, allowed characters, reserved words, and impersonation risk.
 *
 * @param string $username Raw username.
 * @param array $options Optional min_length, max_length, and reserved names.
 * @return array Username validation result.
 */
function ogValidateUsernamePolicy($username, $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

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

	$min_length = 3;
	if (!empty($options['min_length'])) {
		$min_length = (int)$options['min_length'];
	}

	$max_length = 32;
	if (!empty($options['max_length'])) {
		$max_length = (int)$options['max_length'];
	}

	$reserved = array('admin', 'administrator', 'root', 'support', 'staff', 'moderator', 'phpog', 'system', 'null');
	if (!empty($options['reserved']) && is_array($options['reserved'])) {
		$reserved = array_merge($reserved, $options['reserved']);
	}

	$errors = array();
	$normalized = strtolower($username);

	if (strlen($username) < $min_length) {
		$errors[] = 'Username is too short.';
	}

	if (strlen($username) > $max_length) {
		$errors[] = 'Username is too long.';
	}

	if (!preg_match('/^[a-zA-Z0-9_\-]+$/', $username)) {
		$errors[] = 'Username contains unsupported characters.';
	}

	foreach ($reserved as $reserved_name) {
		if ($normalized == strtolower((string)$reserved_name)) {
			$errors[] = 'Username is reserved.';
		}
	}

	if (preg_match('/^(admin|support|staff)[_\-]?[0-9]*$/i', $username)) {
		$errors[] = 'Username may impersonate a site role.';
	}

	$result['success'] = empty($errors);
	if (empty($errors)) {
		$result['message'] = 'Username policy passed.';
	} else {
		$result['message'] = 'Username policy failed.';
	}
	$result['data'] = array(
		'username' => $username,
		'normalized' => $normalized,
		'errors' => $errors
	);

	return $result;
}