views:

52

answers:

5

I am trying to set up a MySQL connection in a main script, and then call various functions depending on what I want to do. I am having trouble passing the connection information to the function.

I have a class "queries" which contains various functions, all which return an array. This is what the code looks like in my main script (calling function normal)

$mysqli = new mysqli($db_host, $db_user, $db_pass, $db_name) or die (mysql_error());
$stats = $queries->normal($mysqli);

And then inside of the queries resource, I have this code:

class queries {
    function normal($mysqli) {
        $query = "SELECT number, first, last FROM roster";
        $roster = $mysqli->query($query);

Then I proceed to do what I need. I cannot get this to work though. I get the error

Call to a member function normal() on a non-object

on the line that I call the function in my main file.

This is similar to these questions, but I can't quite figure it out.
http://stackoverflow.com/questions/241311/passing-database-connection-by-reference-in-php
http://stackoverflow.com/questions/394113/ensuring-mysql-connection-works-in-php-function

Thank you

+5  A: 

$queries is not an object, much less a queries object. Figure out what you assigned to it instead, and assign the right thing to it :)

Ahh, I think I get it now. queries is a class, not an object. You need to make an object that is an instance of the class.

$queries_obj = new queries;
$queries_obj->normal($mysqli);
Matchu
What exactly do you mean? Are you saying that I probably already assigned a variable to $queries?
phoffer
@phoffer Have you assigned anything to the variable $queries?
George Marian
@phoffer It means that you should have created an instance of queries as $queries, i.e. as per the comment on your question - $queries = new queries()
Cez
@phoffer - edited, see if that helps you understand :)
Matchu
the last line of your new code should start $queries_obj->normal...
Scott Saunders
@Scott Saunders - thanks, fixed it within a few seconds of the initial edit ;)
Matchu
@Matchu That absolutely makes sense (after the edit), and that is exactly what the problem was.
phoffer
@phoffer - glad it helped :) Be sure to click the check mark next to the answer once StackOverflow will let you!
Matchu
I actually fixed my code based off Scott's answer (before you edited yours), but I upvoted your answer and one of your comments too...I'm still new here, so I am trying to help everyone (since everyone helped me). Thank you very much!
phoffer
@phoffer - gotcha - I'm not one for scrolling, it would seem xD Glad to help :)
Matchu
+2  A: 

"Call to a member function normal() on a non-object" means that you are trying to call normal() on a variable that is not an object. Probably you meant to do this:

$queries = new queries();
$stats = $queries->normal($mysqli);
Scott Saunders
That's exactly what the problem was, thank you Scott.
phoffer
+1  A: 

Think of your class definition as a recipe and the object as the actual dish you made using that recipe.

As stated by others, you likely haven't instantiated (created) an object of that class.

George Marian
A: 

I would really not recommend structuring your code like this. Passing around the mysql connection can make your function signatures incredibly cluttered. Two other options are:

  • Singleton Pattern: Encapsulate your database interaction functions into a single class, and then every time you need to call one of them, you grab an instance of that class. What's nice about this method is that you always get the same db connection, instead of opening many request. If you're not using heavy OO (lots of procedural php, or lots of global functions), this is really helpful. For example:
public function foo() {  
  $results = Db::getInstance()->query("SELECT * FROM bar");  
  // Do other stuff
  return $results;
}
  • Inheritance: This pattern is really helpful if you're working in something like MVC, or you need to have objects share functionality. Combined with a singleton, you keep a single db connection per request, and the easy access of the db instance in a member variable.
class DB {
  public function __construct() {
    $this->conn = Db::getInstance();
  }
}


class Foo extends DB {
  public function foo() {
    $this->conn->query("SELECT * FROM bar");
  }
}
Chris Henry
A: 

Whilst i could agree that passing database handlers around in methods/functions isn't probably the best idea, it's not dirty to pass database objects through to classes via the constructor, especially if you have multiple connections.

corrodedmonkee