* * @param string|null $string The string to escape * @param int $flags htmlspecialchars flags (default: ENT_QUOTES | ENT_HTML5) * @return string Escaped string */ public static function h(?string $string, int $flags = ENT_QUOTES | ENT_HTML5): string { if ($string === null) { return ''; } return htmlspecialchars($string, $flags, 'UTF-8'); } /** * Escape string for HTML attribute context * * Use for values inside HTML attributes. * Example: * * @param string|null $string The string to escape * @return string Escaped string */ public static function attr(?string $string): string { if ($string === null) { return ''; } // More aggressive escaping for attribute context return htmlspecialchars($string, ENT_QUOTES | ENT_HTML5 | ENT_SUBSTITUTE, 'UTF-8'); } /** * Encode data as JSON for JavaScript context * * Use when embedding data in JavaScript. * Example: * * @param mixed $data The data to encode * @param int $flags json_encode flags * @return string JSON encoded string (safe for script context) */ public static function json($data, int $flags = 0): string { // Use HEX encoding for safety in HTML context $safeFlags = JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | $flags; return json_encode($data, $safeFlags); } /** * URL encode a string * * Use for values in URL query strings. * Example: * * @param string|null $string The string to encode * @return string URL encoded string */ public static function url(?string $string): string { if ($string === null) { return ''; } return rawurlencode($string); } /** * Escape for CSS context * * Use for values in inline CSS. * Example:
* * @param string|null $string The string to escape * @return string Escaped string (only allows safe characters) */ public static function css(?string $string): string { if ($string === null) { return ''; } // Only allow alphanumeric, hyphens, underscores, spaces, and common CSS values if (!preg_match('/^[a-zA-Z0-9_\-\s#.,()%]+$/', $string)) { return ''; } return $string; } /** * Format a number safely * * Ensures output is always a valid number. * * @param mixed $number The number to format * @param int $decimals Number of decimal places * @return string Formatted number */ public static function number($number, int $decimals = 0): string { return number_format((float)$number, $decimals, '.', ','); } /** * Format an integer safely * * @param mixed $value The value to format * @return int Integer value */ public static function int($value): int { return (int)$value; } /** * Truncate string with ellipsis * * @param string|null $string The string to truncate * @param int $length Maximum length * @param string $suffix Suffix to add if truncated * @return string Truncated and escaped string */ public static function truncate(?string $string, int $length = 100, string $suffix = '...'): string { if ($string === null) { return ''; } if (mb_strlen($string, 'UTF-8') <= $length) { return self::h($string); } return self::h(mb_substr($string, 0, $length, 'UTF-8')) . self::h($suffix); } /** * Format a date safely * * @param string|int|null $date Date string, timestamp, or null * @param string $format PHP date format * @return string Formatted date */ public static function date($date, string $format = 'Y-m-d H:i:s'): string { if ($date === null || $date === '') { return ''; } if (is_numeric($date)) { return date($format, (int)$date); } $timestamp = strtotime($date); if ($timestamp === false) { return ''; } return date($format, $timestamp); } /** * Check if a string is safe for use as a CSS class name * * @param string $class The class name to validate * @return bool True if safe */ public static function isValidCssClass(string $class): bool { return preg_match('/^[a-zA-Z_][a-zA-Z0-9_-]*$/', $class) === 1; } /** * Sanitize CSS class name(s) * * @param string|null $classes Space-separated class names * @return string Sanitized class names */ public static function cssClass(?string $classes): string { if ($classes === null || $classes === '') { return ''; } $classList = explode(' ', $classes); $validClasses = array_filter($classList, [self::class, 'isValidCssClass']); return implode(' ', $validClasses); } } /** * Shorthand function for HTML escaping * * @param string|null $string The string to escape * @return string Escaped string */ function h(?string $string): string { return OutputHelper::h($string); }