tags:

views:

367

answers:

4

I'm trying to use the new PHP mysqli extension. I've got a function (safe()) that recursively uses mysql_real_escape_string to make strings safe. How do I use my mysqli connection inside this function to call the mysqli::escape_string() function?

Example:

$db = new mysqli($host,$user,$password,$database_name);


function safe ($data) {
  if(!is_array($data)) {
     if(!get_magic_quotes_gpc()) {
       $data = **mysqli::escape_string($data)**
       return $data;
    }
  } else {
    return array_map('safe',$data);
  }
}

Where I have mysqli::escape_string() inside safe() how do I call that? Outside of a function it would be $db->escape_string() but I can't find a way to call it insde. I've tried passing $db to the function, making $db global etc. The alternative is to use the procedural mysqli_escape_string() but that requires the mysqli link resource to be explicitly passed to it, but I can't find a way to access that.

+5  A: 

pass your DB object in to the function.

 function safe ($data, $db) {
  if(!is_array($data)) {
     if(!get_magic_quotes_gpc()) {
       $data = $db->escape_string($data);
    }
  } else {
    return array_map('safe',$data);
  }
}
Ilya Biryukov
+1  A: 

I would extend the mysqli class:

class mysqliA extends mysqli{
    function escape_string($data){
        if(!is_array($data)) {
            if(!get_magic_quotes_gpc()) {
                $data = $this->escape_string($data);
                return $data;
            }
        } else {
            return $this->escape_string($data);
        }
    }
}

that way you just have to call

$db = new mysqliA();
$db->escape_string($data);
SeanJA
A: 

I don't want to encourage you to use globals, but if you wanted to access $db from the safe function you would have to put global $db; at the beginning of the function.

Resulting in:

$db = new mysqli($host,$user,$password,$database_name);

function safe ($data) {

  global $db;

  if(!is_array($data)) {
     if(!get_magic_quotes_gpc()) {
       $data = $db->escape_string($data);
       return $data;
    }
  } else {
    return array_map('safe',$data);
  }
}

Please note that globals are considered evil and shouldn't be used.

What should you use then? Well, for your use case the registry pattern(keep that in mind for later) probably would fit best. But to get you started with object-oriented programming you should try the following for now:

class myClass {

    protected $db;

    public function __construct() {
        $this->db = new mysqli($host,$user,$password,$database_name);
    }


    function safe ($data) {

      if(!is_array($data)) {
         if(!get_magic_quotes_gpc()) {
           $data = $this->db->escape_string($data);
           return $data;
        }
      } else {
        return array_map('safe',$data);
      }
    }
}

I urge you to read more about object-oriented programming as it will help you write better and more reusable code.

Hope I could help.

André Hoffmann
A: 

if I extend the class I get:

Notice: Undefined variable: db in *file path* on line 22

Fatal error: Call to a member function escape_string() on a non-object in *file path* on line 22

line 22 being where the function is

If I pass the mysqli object I get:

Warning: Missing argument 2 for safe() in *file path* on line 17

Notice: Undefined variable: db in *file path* on line 22

Fatal error: Call to a member function escape_string() on a non-object in *file path* on line 22

My function call is:

        $item[$form] = safe($item[$form],$db);

so clearly no missing second var

And I can't build a class around the function and initialise a new mysqli connection (which seems like the height of inefficiency at any rate) becuase I have to make safe() a Static function to make it a valid callback for array_map() and no syntax seems to work for this line:

$data = $this->db->escape_string($data);

Have tried

$data = $this->db->escape_string($data);
$data = self::db::escape_string($data);
$data = self::db->escape_string($data);
speerross
Fatal error is because you blindly copied the code, if you look at line 22, it says $db-> instead of $this->
SeanJA
It should be $db-> because I'm passing an object, not using it within the context of the class itself
speerross
I meant when you are extending the class
SeanJA