0

I am using this library and when I put on my OOP project, it gave me an error https://github.com/lincanbin/PHP-PDO-MySQL-Class

Notice: Undefined variable: DB in E:\Laragon\www\shop\include\category.php on line 13

Fatal error: Uncaught Error: Call to a member function query() on null in E:\Laragon\www\shop\include\category.php:13 Stack trace: #0 E:\Laragon\www\shop\admin\category.php(8): Category->getAllCategories() #1 {main} thrown in E:\Laragon\www\shop\include\category.php on line 13

on my category class

<?php

require_once('../vendor/autoload.php');

class Category {
    function __construct()
    {
        $DB = new Db('localhost', '3306', 'shop', 'root', '');
    }
    
    public function getAllCategories()
    {
        $query = $DB->query("SELECT * FROM categories");

        return $query;
    }
   ...
}

and in my php frontend

<?php
    
    require_once('../include/category.php');


    $test = new Category();

    var_dump($test->getAllCategories());
?>
4
  • 2
    $this->DB instead of $DB. You need to define it first. Basic OOP pattern. Commented Apr 30, 2019 at 6:15
  • 1
    Possible duplicate of How Do I define properties for a class in php? Commented Apr 30, 2019 at 6:18
  • It is worth looking into dependency injection (DI) which would mean passing in the connection to the class. (Link is just the first link I found) Commented Apr 30, 2019 at 6:37
  • You should not use closeConnection at all (maybe only when you really know you should). Closing connection require you to open it again for next query so it will run much slower. When PHP script finishes it closes connection automatically anyways. Commented Apr 30, 2019 at 6:38

3 Answers 3

2

When you create a new variable in a class method, it will only exist in that scope, so when creating the $DB variable in the constructor, it will go out of scope when you reach the end of the constructor.

To store the variable in the class as a member field, you will have to set it to the $this object, preferably defining it before hand:

class Category {
    private $DB;
    function __construct()
    {
        $this->DB = new Db('localhost', '3306', 'shop', 'root', '');
    }

    public function getAllCategories()
    {
        $query = $this->DB->query("SELECT * FROM categories");

        return $query;
    }
   ...
}

That way, the class will store the variable as a member and make it available in all it's methods.

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

7 Comments

is it okay to close the connection every function? $DB->closeConnection(); like bottom of $query. or when do I need to close the db connection?
It's always good to close the connection when it's not needed anymore, but I'm not sure how the internal logic of the Db class works, so unsure if you should close it. Personally I'd recommend that you create ONE db object for the whole page and then pass it into the constructor of the class, then you can keep it open through the whole runtime and not use more handles than needed.
you mean on the view file? sorry I'm too noob, I've updated my description with added yours.
@StormSpirit - Don't close the connection in every method. It's better to have one single connection that you reuse. Connecting to the database is costly so you don't want to do that more often than you really have to. PHP will actually close the connection for you when the script ends. If you want to make sure it's closed, you can always close it in the class destruct-method.
As @MagnusEriksson says, php will close it, so you don't need to care too much about the actual connection. The other part is more of a optimization, as I always say: make it work, then make it good, so start with making the script run as you wish, then you can look at making it better :)
|
0

Please define $DB as a class variable and then use it.

<?php   
require_once('../vendor/autoload.php');
class Category {
 private $DB; // Define it here.
 function __construct() {
  $this->DB = new Db('localhost', '3306', 'shop', 'root', ''); // Set value here
 }
 public function getAllCategories() {
  $query = $this->DB->query("SELECT * FROM categories"); // Get value here
  return $query;
 }
 ...
}

Comments

0

Change your class to this :

class Category {

protected $DB;

function __construct()
{
    $this->DB = new Db('localhost', '3306', 'shop', 'root', '');
}

public function getAllCategories()
{
    $query = $this->DB->query("SELECT * FROM categories");

    return $query;
}

... }

4 Comments

$this->DB, not $this->$DB
You might also want to add an explanation so the OP knows why they should change their code to this.
They should change their code to this ,Because he wants to solve his problem.
When posting an answer, you need to explain what they've done wrong and what you've changed to fix it. If not, the OP (and future visitors) won't know what the actual solution was, and can't apply the same solution on other similar problems they might have. They will then come back and post similar questions again and again. That's not constructive to anyone.

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.