1

I'm having problem with global variable in PHP. I have mysqli config file which contains only following data:

$mysqli = new mysqli("localhost", "user", "pass", "db");
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

I have the following class on another file:

class user{

function username_exists($username){
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username FROM users WHERE username=?")) {
        $stmt->bind_param("s", $username);
        $stmt->execute();
        $stmt->store_result();
        $count=$stmt->num_rows;
        $stmt->close();
    }
    return ($count > 0 ? true : false);
    }

    ...
    some more functions
    ...

    }

Now this works fine, but in my previous question on SO, i was told that it is a bad practice to access global variable like I'm doing in above class. So, I'm trying to pass the global variable in the constructor, in following way:

private $mysqli;
      function __construct()
      {
        global $mysqli;
        $this->mysqli = $mysqli;
      }

    function username_exists($username){
    //global $mysqli;
    if ($stmt = $this->mysqli->prepare("SELECT username FROM users WHERE username=?")) {

And I get the following error:

Fatal error: Call to a member function prepare() on a non-object in...(line number)

Can you please tell me whats problem with it and how this can be fixed? Thanks. Edit: Sorry for the spelling mistake of __construct. It was only mistake typing here, and the error isnt because of that.

1
  • why u write private $mysqli; on last code block Commented Mar 7, 2011 at 13:09

7 Answers 7

3

Well... having global in your constructor kindof beats the point. Consider passing it in as a parameter __construct($mysqli).

  public function __construct($mysqli)
  {
    $this->mysqli = $mysqli;
  }

What you're trying to do here is called dependency injection.

Sign up to request clarification or add additional context in comments.

Comments

1

I think the problem is you misstyped __construct try changing your __cuntruct to the right name for the constructor.

The global in username_exists is also useless.

You should also write a constructor which takes the variable as argument and avoid using global completly :

class User {
     var $mysqli;

     function __construct($mysqli) {
         $this->mysqli = $mysqli;
     }

     [ ... some functions ... ]
}

You must create your object like this :

$myuser = new User($mysqli);
$myUser->prepare();

2 Comments

Thanks for your reply. I'm sorry I mistyped the construct, but that was not the problem. I tried using the method you described and i get 2 errors, first Warning: Missing argument 1 for user::__construct(), called in ... and the second error is same which i mentioned in my original post. Can you please have a look the code of my config file which I have put in original file. Thanks again.
You must pass your $mysqli variable when you create your object. I think you should read the PHP documentation about objects : php.net/manual/en/language.oop5.basic.php It seems to me that you don't really understand what you're doing. BTW, I updated my post with a little example on how you should create the object
1

Your constructor is not getting called because it is not the constructor at all

__cuntruct

should be

__construct

2 Comments

Probably someone trying to cancel my upvote so their answer ranks higher... Your answer is correct and was the quickest at being so.
I am facing this problem on SO that someone downvote and did not respond why he did? Downvote, it is okay but care to leave comment
1

Couple of things. I think it would work OK if you changed __cuntruct to __construct.

You're still using the global declaration inside the username_exists function. Why not just pass the $mysqli variable in the constructor?

function _construct($mysqli) {
    $this->mysqli = $mysqli;
}

then you have no globals in the class.

1 Comment

Thanks for the reply, however the spelling mistake was only typing here, sorry for that. I've fixed that, and also tried passing the variable in the constructor, it still gives same error. If you see my config file code above, Do i need to change anything in that? Thanks.
1

The code as written was not really what the others on SO were attempting to encourage you to do.

function __construct($mysql_handler){
  $this->mysql = $mysql_handler;
}

This is passing in the parameter into the object scope at construction. When you create an instance of your object, you would pass in the MySQL handle.

$mysqli = new mysqli("localhost", "user", "pass", "db");
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$u = new User($mysqlli);

Then you should be able to call mysqli member functions on the property itself.

Your constructor is also misspelled. It will only work properly with the magic method name __construct().

Comments

-1

Remove global $mysqli; in the function username_exists(), it does not makes sense.

The global $mysqli; is not required/does not makes sense since you want this variable to store the reference the connection IN THE CONTEXT of your object.

Comments

-1

change __cuntruct() to __construct()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.