After some experiments I was create two functions for total clean SQL injections. In pair with prepared statements it works perfect.
// Cleanup outer SQL
protected static function escapeOuter( string $s ): string {
return preg_replace(
['/(\/\*\s*\w*\s*(?!.\/\*))/si', '/(\-\-\s*\w*\s*(?!.\-\-))/si', '/(or\s*\w*\s*=\s*\w(?!.*or)|\|\|\s*\w*\s*=\s*\w(?!.\|\|))/si'],
[';', ';', ''],
str_replace(
[ '+--', '--+', '"', "\x1a", '%', 'qq ', '--', '/*!',],
[ '', ';', '"', '\\Z', "\%", '--', '/*!'],
trim( $s )
)
);
}
// Cleanup inner SQL
protected static function innerEscape( string $v ): string {
// Secure stage means that inner SQL clauses fixed to be secure
$secureStage = str_ireplace(
['ASCII', 'UNION', ' OR ', '||', ' AND ', '&&', ' ON ', "'", '+--', '--+', 'qq', '"', '--', '/*!', ],
['', '', ' or ', ' || ', ' and ', ' && ', ' on ', '\'', '', ';', '', '"', '--', '/*!'],
addslashes(
htmlspecialchars( $v )
)
);
// Not available to use built in escape future when DB connection not established
if( isset( self::$dbx_lnk[ 1 ] ) ) {
if( (bool)self::$dbx_lnk[ 1 ]['CONNECTION'] ) {
return mysqli_real_escape_string( self::$dbx_lnk[ 0 ], $secureStage );
}
else {
return $secureStage;
}
}
else {
return $secureStage;
}
}
This functions is a part of my own DataBase driver.
For example you have to use innerEscape future for clean fields values and escapeOuter future to cleanup full MySQL query. After filtering you have to use prepared statement of PDO or MySQLi.