Я создал этот класс с помощью функции query ():
Эта функция упрощает использование подготовленных операторов.Но
- Это безопасно?
- Имеет ли смысл использовать его таким образом?
Я уже тестировал его с sqlmap , и он хорошо выглядит.
Функцияобычным образом разбить обычную строку SELECT на несколько меньших строк, чтобы исключить входные значения.Сохраняются входные значения и сама строка.Сама строка будет заменена на?Чем нормальная функция подготовит заменяет?снова с введенными значениями.
class dbcon
{
public $con;
public function __construct()
{
$this->con = new mysqli( $host, $username, $password, $dbname );
}
public function query( $query )
{
//selcet
if( strpos( $query, "SELECT" ) !== false )
{
$types = ""; $to_replace = []; $values = [];
$query = explode( "WHERE", $query );
$query_where = explode( "ORDER BY", $query[ '1' ] );
$query_where[ '0' ];
if( isset( $query_where[ '1' ] ) )
{
$ORDERBY = explode("LIMIT", $query_where[ '1' ]);
}
if( isset( $ORDERBY[ '1' ] ) )
{
$LIMIT = $ORDERBY[ '1' ];
}
$SELECT = $query[ '0' ];
$where = str_replace( array( "(", ")", "[", "]" ), "", $query_where[ '0' ] );
$where = str_replace( array( "AND", "OR", "and", "or" ), "-|-", $where );
$where = explode( "-|-", $where );
for ($i=0; $i < count($where); $i++) {
$for_where = str_replace( array( "!=", "<=", ">=", "=", "<>", ">", "<", "IS", "NOT LIKE", "LIKE" ), "#|#", $where[ $i ] );
$for_where = explode( "#|#", $for_where );
$value = trim( $for_where[ '1' ] );
if( substr_count($value, "AND") <= 0 AND substr_count($value, "OR") <= 0 )
{
$value = "'?'";
}
$to_replace[] = $value;
$value_num = "values".$i;
$$value_num = $value;
$values[] = &$$value_num;
$types .= "s";
}
$WHERE = str_replace( $to_replace , " ? ", $query_where[ '0' ] );
$prepare = $SELECT . " WHERE " . $WHERE;
if ( isset( $ORDERBY ) )
{
$prepare .= " ORDER BY " . $ORDERBY[ '0' ];
}
if ( isset( $LIMIT ) ){
$prepare .= " LIMIT " . $LIMIT;
}
$stmt = $this->con->prepare( $prepare );
//$stmt->bind_param($types, $values['0'],$values['1']);
call_user_func_array( array( $stmt, "bind_param" ), array_merge( array( $types ), $values ) );
$stmt->execute();
return $stmt->get_result();
$stmt->close();
}
}
}
$db = new dbcon();
Вызовите функцию:
$id = $_GET[ 'id' ];
$my_query = $db->query("SELECT * FROM Users WHERE ID = '$id' ORDER BY created DESC");
while($row = $my_query->fetch_array()){
echo $row['NAME']."<br>";
}
ОБНОВЛЕНИЕ:
Старая функция не делаетмного смысла и совсем не безопасно.Это должен быть простой способ, но лучше.
public function query( $query, $types, $query_values )
{
$values = [];
for ($i=0; $i < count($query_values); $i++) {
$value_num = "values".$i;
$$value_num = $query_values[ $i ];
$values[] = &$$value_num;
}
$stmt = $this->con->prepare( $query );
call_user_func_array( array( $stmt, "bind_param" ), array_merge( array( $types ), $values ) );
$stmt->execute();
return $stmt->get_result();
$stmt->close();
}
вызовите функцию
$query = "SELECT * FROM _Users WHERE ID = ? ORDER BY created ASC";
$my_query = $db->query( $query, "s", array( $id ) );
while($row = $my_query->fetch_array()){
echo $row['title']."<br>";
}