Skip to content

Instantly share code, notes, and snippets.

@stemar
Last active February 16, 2026 04:16
Show Gist options
  • Select an option

  • Save stemar/e20d87f0205410e90b6038de290f26b8 to your computer and use it in GitHub Desktop.

Select an option

Save stemar/e20d87f0205410e90b6038de290f26b8 to your computer and use it in GitHub Desktop.
Polyfill for FILTER_SANITIZE_STRING deprecated as of PHP 8.1.0
<?php
function filter_sanitize_string($value, $flags = 0) {
if ($flags & FILTER_FLAG_EMPTY_STRING_NULL && $value === "") {
return null;
}
if (!(is_scalar($value) || is_null($value))) {
return false;
}
// Strip HTML tags and remove NUL bytes
$value = (string)$value;
$value = strip_tags($value);
$value = str_replace("\0", "", $value);
// Low/High ASCII handling (byte-by-byte to match legacy behavior)
$output = "";
for ($i = 0, $n = strlen($value); $i < $n; $i++) {
$char = $value[$i];
$ord = ord($char);
if ($ord < 32) {
if ($flags & FILTER_FLAG_STRIP_LOW)
continue;
if ($flags & FILTER_FLAG_ENCODE_LOW) {
$output .= "&#$ord;";
continue;
}
}
if ($ord > 127) {
if ($flags & FILTER_FLAG_STRIP_HIGH)
continue;
if ($flags & FILTER_FLAG_ENCODE_HIGH) {
$output .= "&#$ord;";
continue;
}
}
$output .= $char;
}
// Strip backticks; fixes bug PHP_VERSION < 5.5.24
if ($flags & FILTER_FLAG_STRIP_BACKTICK) {
$output = str_replace('`', '', $output);
}
// Legacy ONLY encoded ampersands if FILTER_FLAG_ENCODE_AMP was set
if ($flags & FILTER_FLAG_ENCODE_AMP) {
$output = str_replace('&', '&amp;', $output);
}
// Replicate legacy quote encoding exactly (&#39; and &#34;)
if (!($flags & FILTER_FLAG_NO_ENCODE_QUOTES)) {
$output = str_replace(["'", '"'], ['&#39;', '&#34;'], $output);
}
return $output;
}
@stemar
Copy link
Author

stemar commented Feb 14, 2026

Polyfill tests

$string = "It's a \"test\" \x02 <script> > & ©";
$sanitized = filter_var($string, FILTER_CALLBACK, [
     'options' => function($value) {
         return filter_sanitize_string($value, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
     }
 ]);
var_dump($sanitized);
$sanitized = filter_sanitize_string($string, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_sanitize_string(array(), FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_sanitize_string(null, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_sanitize_string(false, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_sanitize_string($string);
var_dump($sanitized);
string(42) "It&#39;s a &#34;test&#34;   > & &#194;&#169;"
string(42) "It&#39;s a &#34;test&#34;   > & &#194;&#169;"
bool(false)
string(0) ""
string(0) ""
string(35) "It&#39;s a &#34;test&#34;    > & ©"

Deprecated tests

$sanitized = filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_var(array(), FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_var(null, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_var(false, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
var_dump($sanitized);
$sanitized = filter_var($string, FILTER_SANITIZE_STRING);
var_dump($sanitized);
string(42) "It&#39;s a &#34;test&#34;   > & &#194;&#169;"
bool(false)
string(0) ""
string(0) ""
string(35) "It&#39;s a &#34;test&#34;    > & ©"

@stemar
Copy link
Author

stemar commented Feb 16, 2026

General filter flags to be applied at the 2nd arg of filter_var(), in 'flags' key value:

$sanitized = filter_var(array(), FILTER_CALLBACK, [
     'options' => function($value) {
         return filter_sanitize_string($value, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
     },
     'flags' => FILTER_NULL_ON_FAILURE,
 ]);
var_dump($sanitized);
NULL
$sanitized = filter_var(array(), FILTER_CALLBACK, [
     'options' => function($value) {
         return filter_sanitize_string($value, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_ENCODE_HIGH);
     },
 ]);
var_dump($sanitized);
array(0) {
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment