Access variable inside constructor function to create database link

I have the following class inside a file called dbconfig.php

<?php
define('DB_SERVER','localhost');
define('DB_USER','sandmannz123');
define('DB_PASSWORD','password');
define('DB_NAME','dbtuts');

class DB_con
{
	function __construct()
	{
		$conn = mysqli_connect(DB_SERVER,DB_USER,DB_PASSWORD,DB_NAME); // Check connection
	if (mysqli_connect_errno())
	  {
	  echo "Failed to connect to MySQL: " . mysqli_connect_error();
	  }
	}
}

and then want to use the connection to the database inside a different class inside a file called class.crud.php. The following attempt to read data from the database fails giving me an undefined variable db error. Obviously I am not accessing the database connection properly - so how do I fix this? (I have taken out most of the code from the class.cruid.php file leaving just the essential lines causing the problem).

<?php
include_once 'dbconfig.php';

class CRUD
{
	public function __construct()
	{
		$db = new DB_con();
	}
	
	// function for read
	public function read()
	{
		return mysqli_query($db->conn, "SELECT * FROM users ORDER BY user_id ASC");
	}
	// function for read
	
}
?>

Try to make global the $db as you are inside a function

function __construct()
{
global $db;
...
}

Store $db as an internal property.

class CRUD
{
    private $db;
    public function __construct()
{
	$this->db = new DB_con();
}
// function for read
public function read()
{
	return mysqli_query($this->db, "SELECT * FROM users ORDER BY user_id ASC");
}

It can be useful to become familiar with: http://php.net/manual/en/language.oop5.php

And once you get things running you might take a look at dependency injection.

PS - Tabs are evil!

Thanks for the help but still getting a problem occuring. After making the suggested changes I am getting: Warning: mysqli_query() expects parameter 1 to be mysqli, object given in C:\wamp\www\dbtuts\inc\class.crud.php on line 22.

Any ideas?

The line 22 at what exactly line of code it refers?

Is this some kind of homework assignment? If so, perhaps the instructor can help.

If not, you really need to spend some time understanding the basics of objects. The link I gave you is a good starting point.

Hint: Think about the changes you made to CRUD and why they were needed. Then figure why similar changes need to be made to DB_con.

Hi …
No this is not a homework assignment. While I appreciated your suggestions I will say that nothing is more frustrating when posting a question, where I have spent considerable time trying to figure out a solution, only to be told to go away and figure it out myself. I would not have posted the question in the first place if I could do that. So thanks but perhaps you might want to consider for a moment what the purpose of a forum is - for me it is a place where I can get full solutions for things i can’t figure out and in doing so I hopefully can then learn where i went wrong.

Line 22 is: return mysqli_query($this->db, “SELECT * FROM users ORDER BY user_id ASC”);

i see no need for this kind of abstraction here, especially for beginners - just provide a plain PDO object to the objects you build, like

<?php // dbconfig.php

define('DB_SERVER','localhost');
define('DB_USER','sandmannz123');
define('DB_PASSWORD','password');
define('DB_NAME','dbtuts');



<?php // crud.php

class CRUD
{
	public function __construct(PDO $PDO)
	{
		$this->PDO = $PDO;
	}
	
	// function for read
	public function read()
	{
		$stmt = $this->PDO->prepare("SELECT * FROM users ORDER BY user_id ASC");
		$stmt->execute();
		return $stmt->fetchAll();
	}
	// function for read
	
}



<?php // index.php

include_once 'dbconfig.php';
include_once 'crud.php';

$PDO = new PDO('mysql:dbname='.DB_NAME.';host=127.0.0.1'.DB_SERVER, DB_USER, DB_PASSWORD);
$CRUD = new CRUD($PDO);
var_dump($CURD->read());
1 Like

Ask yourself why you spent considerable time on what should be a trivial problem. In this case it is because you have no understanding of how objects work. Hence the suggestion that you learn a bit about them.

Yes I (or maybe someone else) could post a solution and you could copy/paste it and it might work for this tiny bit of code. But as soon as you tried to do the next step you would be stuck again. Is that really better for you?

Take a look at this thread: How to fetch data from database and insert inside of div tag to see the kind of train wrecks that happen when trying to help someone who fundamentally does not understand what is happening and just wants something that works.

1 Like

That’s because your DB_con class is useless. Use raw mysqli which is already a class.

class CRUD
{
public function __construct($db)
{
	$this->db = $db;
}

// function for read
public function read()
{
	return mysqli_query($db->conn, "SELECT * FROM users ORDER BY user_id ASC");
}
// function for read
}
$mysqli = new mysqli(DB_SERVER,DB_USER,DB_PASSWORD,DB_NAME);
$crud = new CRUD($mysqli);
$result = $crud->read();

Now you are just being cruel :slight_smile:
http://php.net/manual/en/mysqli.query.php

Given that while ($row = mysqli_fetch_assoc($result)) is the only known to them way to output the returned data, the method makes perfect sense.

I called it cruel because you have two obvious errors and the original poster has already demonstrated the inability to debug. Here is something that works.

class CRUD
{
    private $db;
    public function __construct($db)
    {
        $this->db = $db;
    }
    // function for read
    public function read()
    {
        return mysqli_query($this->db, "SELECT * FROM users ORDER BY id ASC");
    }
}
$mysqli = new mysqli('localhost','root','noyb','ng2016');
$crud = new CRUD($mysqli);
$result = $crud->read();
$row = mysqli_fetch_assoc($result);
var_dump($row);

And yes, I had to actually execute the code to get it working. mysqli is so much fun.

1 Like

Ok, I got one with $this->db but can’t get which is another typo.

You had $db->conn which should have been $this->db. I called it two because the original question had problems with accessing class properties as well as accessing a conn object.

Hi …
Here’s my fundamental problems with the way you have approached this situation. First of all you know nothing at all about me and my level of programming knowledge. Instead of simply giving some help - which initially didn’t work as suggested - you then decide to put the focus back on me saying I didn’t know what i was doing. Sure, I admit I didn’t know what i was doing - that was why I posted the question in the first place! I have no problem with your reference to where i could find out more information - what I do have a real problem with is the attitude that is behind your response which basically says - “I’ve given you all the help I’m going to (bearing in mind what you initially suggested didn’t work) - go and find out the rest yourself”.

The problem is that in both your classes you’re trying to access variables which just exist within the scopes of the constructor functions ($conn and $db respectively). To make them available both inside (private) and outside (public) of classes, you’ll have to define them as class member variables; leaving aside the database details, it should like something like

class DB_con {

  public $conn;

  public function __construct() {
    $this->conn = "My connection";
  }
}

class CRUD {

  private $db;

  public function __construct() {
    $this->db = new DB_con();
  }

  public function read() {
    echo "Reading from " . $this->db->conn;
  }
}

$crud = new CRUD;
$crud->read();

Although you’d usually define $conn as a private property as well and provide a getter function, like

class DB_con {

  private $conn;

  public function __construct() {
    $this->conn = "My connection";
  }

  public function getConn() {
    return $this->conn;
  }
}

class CRUD {

  private $db;

  public function __construct() {
    $this->db = new DB_con();
  }

  public function read() {
    echo "Reading from " . $this->db->getConn();
  }
}
1 Like

Thanks, much appreciated.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.