, templates, textareas and ), then puts them back * exactly as they were. Optimizers work on the masked text, so they cannot * touch code that merely looks like markup. */ class HtmlMask { /** A comment, or one of the protected elements up to its matching closing tag. */ const PATTERN = '#|<(script|style|noscript|template|textarea|head)\b[^>]*+>[\s\S]*?#i'; /** * Replace protected regions with placeholders. * * @param string $html Page HTML. * @param array $store Filled with placeholder => original text. * @return string|null Masked HTML, or null if the regex engine gave up (caller must then leave the page alone). */ public static function hide( string $html, array &$store ): ?string { $token = self::unused_token( $html ); $i = 0; $out = preg_replace_callback( self::PATTERN, static function ( $m ) use ( &$store, $token, &$i ) { $key = $token . '_' . $i++ . '_'; $store[ $key ] = $m[0]; return $key; }, $html ); return is_string( $out ) ? $out : null; } /** Put every protected region back. */ public static function show( string $html, array $store ): string { return $store ? strtr( $html, $store ) : $html; } /** A marker that does not occur anywhere in the page. */ private static function unused_token( string $html ): string { do { $token = 'vcmask' . bin2hex( random_bytes( 6 ) ); } while ( false !== strpos( $html, $token ) ); return $token; } }