3

I need to escape array's, I am using array_map with mysqli_real_escape_string.

I have multiple arrays like

$_post['countries'];
$_post['categories'];
.
.

How do I perform escaping on these arrays

I am doing this way

$countries=array_map('mysqli_real_escape_string', $_POST['countries']);
$categories=array_map('mysqli_real_escape_string', $_POST['categories']);
.
.

but it shows me error as Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in

also doing

$categories=mysqli_real_escape_string($connection, $_POST['categories']); 

gives error as

Warning: mysqli_real_escape_string() expects parameter 2 to be string, array given in

Please see and suggest a way or another better way to do this.

Thanks

  • mysqli_real_escape_string is a function and how are you using this. – Deep Kakkar Mar 11 '16 at 13:04
  • @Anant i tried this way first but it gives error as `Warning: mysqli_real_escape_string() expects parameter 2 to be string, array given in` –  Mar 11 '16 at 13:05
  • In mysqli almost aways ;) you need provide 2 arguments, first the connection and the 2nd the query etc – rray Mar 11 '16 at 13:05
  • Use prepared statement insted of escaping – rray Mar 11 '16 at 13:06
  • 2
    `array_map(function($arrayElement) use ($databaseConnection) { return mysqli_real_escape_string($databaseConnection, $arrayElement); }, $_POST['countries']);`.... but if you're already using MySQLi, then switch to using prepared statements with bind variables, and you won't need to escape these – Mark Baker Mar 11 '16 at 13:06
  • @MarkBaker I am using prepared statements with bind variables, doing this for extra security. –  Mar 11 '16 at 13:26
  • 2
    @TallboY - If you think this is extra security, it isn't..... using bind variables does this for you ___automatically___; what you'll end up doing this manual escaping as well is "double escaping" which isn't good – Mark Baker Mar 11 '16 at 13:28

2 Answers2

2

You need to wrap mysqli_real_escape_string() call with an anonymous function to use within array_map() like this:

// $connection_object is a mysqli object declared somewhere above

$countries = array_map(function($item) use($connection_object) {
  return mysqli_real_escape_string($connection_object, $item);
}, $_POST['countries']);
Max Zuber
  • 1,217
  • 10
  • 16
  • Yes, I thought it's supposed by your code. Can you add a result of print_r($_POST['countries']); call to your start topic? – Max Zuber Mar 11 '16 at 13:45
2

You have a lot of solutions here.

Considering you wanna stick to mysqli (PDO is now the recommanded way, but still a choice) and you want to keep using array_map on this context, you have to check the array_map prototype: http://php.net/array_map

array array_map ( callable $callback , array $array1 [, array $... ] )

So:

  1. Using dynamic arguments of array_map

    Note : this solution is a bad one, and was mistaken.

    Original answer : $myArray = array_map('mysqli_real_escape_string', $db, $myArray);

    Updated answer : $myArray = array_map('mysqli_real_escape_string', $myArray, array_fill(0, count($myArray), $db)); and that's a bad idea with mysqli object.

  2. Using array callable

    Because mysqli_real_escape_string is also a method of mysqli... $myArray = array_map(array($db, 'real_escape_string'), $myArray);

  3. Using closure

    $myArray = array_map(function($e) use($db) { return mysqli_escape_string($db, $e); }, $myArray);

    or

    $myArray = array_map(function($e) use($db) { return $db->real_escape_string($e); }, $myArray);

Lpu8er
  • 227
  • 1
  • 5
  • what is `$db` database or connection? –  Mar 11 '16 at 13:16
  • Neither database nor connection. That's the mysqli object. It may handle a connection, maybe to a database... or not. That's just the base object for mysqli to be used. You had to create it, probably using a new mysqli. – Lpu8er Mar 11 '16 at 13:19
  • getting error `Notice: Undefined variable: db` & `Warning: array_map(): Argument #2 should be an array` –  Mar 11 '16 at 13:20
  • Yes, you have to replace $db with your mysqli object, as I said earlier ;) mysqli always works with this object. You also have to replace $myArray by your array, obviously. – Lpu8er Mar 11 '16 at 13:22
  • what mysqli object, I don't get this. –  Mar 11 '16 at 13:24
  • When you use mysqli. You perform some steps, one of the first is to create the mysqli object, which will be used to perform queries. For example, `$db = new mysqli('localhost', 'root', 'mypassword'); $db->query('show tables');` – Lpu8er Mar 11 '16 at 13:30
  • I have this instead `$connection = mysqli_connect($host, $dbusername, $pass, $db)` –  Mar 11 '16 at 13:32
  • As the documentation states, mysqli_connect is in fact a deprecated alias of mysqli::__construct. So, the result of mysqli_connect IS the mysqli object you have to use :) In your case, so, the variable to use is $connection – Lpu8er Mar 11 '16 at 13:34
  • result is `$connection` and i am using this but the error `Notice: Undefined variable: db & Warning: array_map(): Argument #2 should be an array` –  Mar 11 '16 at 13:36
  • So... In your case, considering your edits on main post, you should use: `$countries = array_map('mysqli_real_escape_string', $connection, $_POST['countries']);` am I right ? Think about the PHP fondamentals, too : is $_POST['countries'] always exist ? Is it always an array ? – Lpu8er Mar 11 '16 at 13:38
  • yes I have done like this only, and $_POST['countries'] always exist and is array –  Mar 11 '16 at 13:39
  • the error is `Warning: array_map(): Argument #2 should be an array` –  Mar 11 '16 at 13:43
  • Yes, right, I'll update the answer. Don't use first solution, either 2nd or 3rd. – Lpu8er Mar 11 '16 at 13:43
  • array (size=2) 0 => string '5' (length=1) 1 => string '8' (length=1) –  Mar 11 '16 at 13:44
  • Answer is now updated. First solution is generally fine, but not in such a case. – Lpu8er Mar 11 '16 at 13:50
  • ok,out of 2nd and 3rd which is faster? –  Mar 11 '16 at 13:52
  • 2nd one is probably the most appropriate. 3rd is generic and rich, but closures should not be used unless necessary. – Lpu8er Mar 11 '16 at 13:56
  • I am using second one as I have lot of escaping to be done, Also thinking to just use prepaid statements as @MarkBaker has suggested. –  Mar 11 '16 at 14:01