PHP class scope - php

I have several classes in an application that I am currently building, and I want to have one access some of the other's member functions but i can't seem to do it.
The first class is called MySQLDB:
class MySQLDB{
public $connection;
function __construct(){
//connects to database
}
function login($username, $password){
//queries database...
}
}
Then I have a class called Session:
class Session{
//variables
//constructor
function processlogin($username, $password){
$database->login($username, $password);
}
Then after this I have two class declarations:
$database = new MySQLDB();
$session = new Session();
No matter where i put these statements in relation to the classes I still get the same error:
PHP Notice: Undefined variable: database in C:\inetpub\wwwroot\cmu\include\session.php on line 52
PHP Fatal error: Call to a member function login() on a non-object in C:\inetpub\wwwroot\cmu\include\session.php on line 52
I have seen some suggestions that would suggest putting the new database object inside the Session class declaration but I want to avoid doing so because I use the database class several other places in the code and I don't want to open up multiple connections to the database.

since you want to have acces on a globally set variable, you can either gain access to it with global:
function processlogin($username, $password){
global $database;
$database->login($username, $password);
}
or use the variable as a parameter for the contructor and remember the database object reference in the class Session:
class Session{
private $database;
function __construct($database){
$this->$database = $database;
}
function processlogin($username, $password){
$this->database->login($username, $password);
}
}
and then you call:
$database = new MySQLDB();
$session = new Session($database);
this comes in handy, if you use more functions afterwords, that also need access to the database object.

you could pass a reference to the MySQLDB instance in the Session constructor.
class Session{
public $db;
function __construct(&$db=null){
if($db == null)
$this->db = new MySQLDB();
else
$this->db = $db;
}
// ....
}
$database = new MySQLDB();
$session = new Session($database);

You are creating two global variables. If you're doing such thing, you need to declare variables you want to use in function with "global" keyword:
function processlogin($username, $password){
global $database;
$database->login($username, $password);
}
Despite this will work, I highly recommend reading about Dependecy Injection mechanism in which you'd pass $database variable as a parameter to processlogin() method, or set it as a private member of that class in constructor / setter. That way database connection will be interchangeable and you'll get more flexibility in your code.

$database is not defined inside processlogin nor passed as parameter, hence the function has no access to it.
You could pass it as constructor parameter to Session:
class Session {
private $db;
public function __construct($database) {
$this->db = $database;
public function processlogin($username, $password){
$this->$db->login($username, $password);
}
}
$database = new MySQLDB();
$session = new Session($database);

Related

How to use an instance of a class within another class in PHP 7

I have what seems like a simple query but I have not found an answer elsewhere.
I have 2 classes, one called DB which essentially connects to the database and can then run queries. I instantiate it at the top of the document $db= new DB; and I can then run a series of queries on the database throughout the page.
The issue I am having is that I want to use this instance within another class I have called User.
I know I can either instantiate again but this does not make sense OR pass the instance of DB when instantiating User, for instance $user = new User($db); but considering the $db instance will be used by most classes I am going to create I am thinking there is a better solution to import it into other classes.
I have looked at the global route but I read it is bad practice + I am getting unexpected global error
class User{
global $db;
public function __construct()
{
var_dump($this-> db);
}//end constructor
}//end class
Since your DB client will be instantiated once and then used everywhere else my initial thought was to recommend passing it as a constructor parameter (dependency injection), but since you are not fan of this approach, I would recommend making your DB client a singleton class, which means it can only be instantiated once and any subsequent attempt would return the same instance everywhere.
You can see a detailed response about singleton classes in PHP at Creating the Singleton design pattern in PHP5.
As a quick example, your DB would look like similar to this:
final class DB
{
public static function getInstance()
{
static $inst = null;
if ($inst === null) {
$inst = new self();
}
return $inst;
}
private function __construct()
{
// your code here ...
}
// your code here ...
}
And then, on your User class you would just get the DB class instance:
class User {
// your code here ...
public function doSomething() {
$db = DB::getInstance();
// your code here ...
}
}
PHP does not handle scopes like Javascript does, your $db is undefined.
The scope of a variable is the context within which it is defined. For the most part all PHP variables only have a single scope. This single scope spans included and required files as well […] Within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope.
Source: http://php.net/manual/en/language.variables.scope.php
This means that there is only a global scope and a function/method scope in PHP. So, either pass the $db instance into the method as a collaborator
class User{
public function __construct() {}
public function getInfo(Database $db) {
$db->query( /* ... */ );
}
}
$user = new User();
$db = new Database();
$user->getInfo($db);
or pass it in the constructor (dependency injection)
class User{
private $db;
public function __construct(Database $db)
{
$this->db = $db;
}
public function getInfo() {
$this->db->query( /* ... */);
}
}
$db = new Database();
$user = new User($db);
$user->getInfo();

Call to a member function on a non-object with mysqli

I'm starting to learn how to use OOP within PHP and so far I want to create a Database class that looks like this:
class Database{
//Database connection variables
private $DBHost = "localhost";
private $DBUser = "username";
private $DBPass = "password";
private $DBName = "database3";
public $DBCon;
public function __construct(){
$this->DBCon = new mysqli($this->DBHost,$this->DBUser,$this->DBPass,$this->DBName);
}
public function con(){
return $this->DBCon;
}
public function __destruct(){
$this->DBCon->close();
}
}
And I'm trying to interact with that class from another one called Application:
include('Database.php');
class Application{
public $DB;
public function __construct() {
$DB = new Database();
}
public function InsertName($Username){
var_dump($this->DB->con());
if($this->DB->con()->query("INSERT INTO Test (name) VALUES ($Username);") === TRUE){
echo "Okay";
}else{
echo "Error";
}
}
}
But I get the error Call to a member function con() on a non-object
As a side note, is this an appropriate way to interact with a database in OOP?
Inside the Application class constructor, $DB is being assigned new Database().
This variable is considered a local variable in this case with its scope being the constructor function itself.
To properly assign the new database object to the public $DB property, you will need to access it via the object's $this reference.
public function __construct() {
$this->DB = new Database();
}
This way you will be able to access the proper assigned public property throughout your remaining class methods.

Execute Function on Constructor PHP

i have class called dbconnection. I want to call this connection function in the constructor. Usually in Java, i just declare:
private FileName variable = new Filename();
and assign the variable.logOn on any functions.
But now, in authenticate php class, i couldn't do that. So i think i can execute the connection in constructor, I've tried:
public function __construct(){
$conn = new Database();
}
but i couldn't access the $conn var because it's not global variable.
Another method i use is placing below code outside any function.
public $conn = new Database();
but it shows an error.
How properly calling the variable or executing another function from another class in php?
thanks.
You need to make $conn a field, and $this->conn to initialize it:
public $conn; // declare $conn field
public function __construct () {
$this->conn = new Database(); // initialize field
}
Do you mean like this?
public $conn;
public function __construct () {
$this->conn = new Database();
}

How can we access a one class object in another class?

I still have not been able to figure this out. How can we access a one class object in another class?
I am using the below code but I am getting and error:
class ListofRecord{
var $db;
function __construct(){
$db = global $db;
}
function record(){
$record = $this->db->SelectQuery("SELECT * FROM user order by UID ASC");
return $record;
}
}
You need to refer to the global $db variable first and then use it in a statement. You also have a minor syntax error in your constructor. You forgot to use the $this keyword when referring your your $db property.
function __construct(){
global $db
$this->db = $db;
}
It also is a better practice not to use global variables and instead pass any variables that you need as parameters to your method call. In this case it is your constructor:
function __construct($db){
$this->db = $db;
}
$list_of_record = ListofRecord($db);

What to use instead of global in php

Is there any other way instead of using global everytime I need to access a global variable inside a function?
$db = new ezSQL_mysql("root", "", "payroll", "localhost");
class employee{
function get_emp(){
global $db;
}
}
In normal global-scope functions, either use the global keyword, or $GLOBALS['db'] superglobal array (which is preferable for readability). The other alternative is to pass the global variable into the function as a parameter.
In your class, the best method is dependency injection. Your class constructor receives the $db as a parameter, which makes it available to all class methods:
// $db was created at global scope
$db = new ezSQL_mysql("root", "", "payroll", "localhost");
class employee {
public $db;
// $db already created in your script is passed as a dependency
// to the class constructor
public function __construct($db) {
$this->db = $db;
}
// Access it as $this->db inside the class
public function get_emp() {
do_something($this->db);
}
}

Categories