253 || strlen($domain) < 3) { return false; } // Validate domain format // Allows: example.com, sub.example.com, example.co.uk // Pattern: alphanumeric with hyphens, dots between labels, valid TLD return (bool)preg_match('/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i', $domain); } /** * Validate text field length * * @param string $value Value to validate * @param int $max Maximum length * @param string $fieldName Field name for error message * @return string|null Error message or null if valid */ public static function validateLength(string $value, int $max, string $fieldName = 'Field'): ?string { if (strlen($value) > $max) { return "$fieldName is too long (maximum $max characters)"; } return null; } /** * Validate string is within min and max length * * @param string $value Value to validate * @param int $min Minimum length * @param int $max Maximum length * @param string $fieldName Field name for error message * @return string|null Error message or null if valid */ public static function validateLengthRange(string $value, int $min, int $max, string $fieldName = 'Field'): ?string { $len = strlen($value); if ($len < $min) { return "$fieldName is too short (minimum $min characters)"; } if ($len > $max) { return "$fieldName is too long (maximum $max characters)"; } return null; } /** * Sanitize text input (remove control characters) * * @param string $text Text to sanitize * @return string Sanitized text */ public static function sanitizeText(string $text): string { // Remove control characters (except tabs and newlines for text areas) $text = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $text); return trim($text); } /** * Validate array size is within limits * * @param array $array Array to validate * @param int $max Maximum number of elements * @param string $fieldName Field name for error message * @return string|null Error message or null if valid */ public static function validateArraySize(array $array, int $max, string $fieldName = 'Selection'): ?string { if (count($array) > $max) { return "$fieldName exceeds maximum of $max items"; } return null; } /** * Sanitize search query * * @param string $query Search query * @param int $maxLength Maximum length (default 100) * @return string Sanitized query */ public static function sanitizeSearch(string $query, int $maxLength = 100): string { // Remove control characters $query = self::sanitizeText($query); // Limit length if (strlen($query) > $maxLength) { $query = substr($query, 0, $maxLength); } return $query; } /** * Validate username format * * @param string $username Username to validate * @param int $minLength Minimum length (default 3) * @param int $maxLength Maximum length (default 50) * @return string|null Error message or null if valid */ public static function validateUsername(string $username, int $minLength = 3, int $maxLength = 50): ?string { if (strlen($username) < $minLength) { return "Username must be at least $minLength characters"; } if (strlen($username) > $maxLength) { return "Username must not exceed $maxLength characters"; } if (!preg_match('/^[a-zA-Z0-9_]+$/', $username)) { return 'Username can only contain letters, numbers, and underscores'; } return null; } /** * Validate URL format * * @param string $url URL to validate * @return bool True if valid, false otherwise */ public static function validateUrl(string $url): bool { return filter_var($url, FILTER_VALIDATE_URL) !== false; } /** * Validate email format * * @param string $email Email to validate * @return bool True if valid, false otherwise */ public static function validateEmail(string $email): bool { return filter_var($email, FILTER_VALIDATE_EMAIL) !== false; } /** * Validate numeric value is within range * * @param mixed $value Value to validate * @param int|float $min Minimum value * @param int|float $max Maximum value * @param string $fieldName Field name for error message * @return string|null Error message or null if valid */ public static function validateRange($value, $min, $max, string $fieldName = 'Value'): ?string { if (!is_numeric($value)) { return "$fieldName must be a number"; } $numValue = is_float($min) || is_float($max) ? floatval($value) : intval($value); if ($numValue < $min || $numValue > $max) { return "$fieldName must be between $min and $max"; } return null; } /** * Validate value is in allowed list (whitelist) * * @param mixed $value Value to validate * @param array $allowed Allowed values * @param string $fieldName Field name for error message * @return string|null Error message or null if valid */ public static function validateInList($value, array $allowed, string $fieldName = 'Value'): ?string { if (!in_array($value, $allowed, true)) { return "$fieldName has an invalid value"; } return null; } }