Reputation: 129
I have 2 files. One is index.php, which checks for a user login In this file i create a dbManager class which handles a database. If dbManager can validate login data, i forward the user to lobby.php (via header).
In lobby.php, i create a Manager class which manages the lobby. I would like to be able to use the Manager class to forward a query to the DB Manager like this:
index.php
$dbManager = new dbManager();
$userid = $dbManager->validateLogin(($_POST["name"], $_POST["pass"];
if ($userid){
$_SESSION["userid"] = $userid;
header("Location: lobby.php");
}
lobby.php
session_start();
if (isset($_SESSION["userid"])){
$manager = new Manager($_SESSION["userid"]);
$manager->getGames();
}
Class dbManager {
things
}
Class Manager {
public userid;
function __construct($id){
$this->userid = $id;
}
function getGames(){
$ret = $dbManager->queryDB($this->userid);
}
}
I am getting the following notices:
Notice: Undefined variable: dbManager in D:\SecureWAMP_Portable\htdocs\projectX\gameManager.php on line 11
and
Fatal error: Call to a member function getGamesForPlayer() on a non-object in D:\SecureWAMP_Portable\htdocs\projectX\gameManager.php on line 11
What am i doing wrong ?
Upvotes: 1
Views: 95
Reputation: 4680
You should define each class in a new file and include those files (good practice is using autoloading). If you only require one object of a class, you should take a look at the Singleton pattern, as you will always get the same class instance.
For that you define a static protected variable which will hold our class instance and use a static public method to return the class instance and if necessary, create a new class instance. We will define the constructor of each class as private, so the static public method has to be used.
If you have arguments you pass to the constructor, define them for the static public method too and pass the arguments to the constructor in the static public method.
The file DBManager.php will define the class DBManager and will use singleton pattern, as this class will handle connections to the database.
Class DBManager {
static protected $instance = NULL
private __construct() {
//Write the code you want to execute when a new class instance is requested
self::$instance = &$this; //Put a reference to this instance in our static variable
}
//Our static public method to retrieve a class instance
static public app() {
if(self::$instance === NULL OR !is_a(self::$instance, 'DBManager')) { //With is_a we are making sure our self::$instance variable holds a class instance of DBManager
$instance = new DBManager();
}
return self::$instance;
}
/* All your other methods... */
}
Our Manager.php will hold the class Manager and to retrieve a class instance of DBManager we will call our static public method app(). It is valid to also make the class Manager singleton, but only if always only one class instance should exist.
Class Manager {
public userid;
function __construct($id){
$this->userid = $id;
}
function getGames() {
$ret = DBManager::app()->queryDB($this->userid);
}
}
Now our basic index.php just instead of using new DBManager()
we will use the static method to return a class instance.
require_once 'DBManager.php';
$dbManager = DBManager::app();
$userid = $dbManager->validateLogin($_POST['name'], $_POST['pass']);
if($userid) {
$_SESSION['userid'] = $userid;
header("Location: lobby.php");
}
In our lobby.php we will use the new Manager class for the first time.
session_start();
require_once 'DBManager.php';
require_once 'Manager.php';
$dbManager = DBManager::app();
if(isset($_SESSION['userid'])) {
$manager = new Manager($_SESSION['userid']);
$manager->getGames();
}
Upvotes: 1
Reputation: 92904
A good practice is to declare each class in separate file.
After that, you need to include the needed class into a file in which you are planning to use that class functionality.
Create file DBManager.php:
Class DBManager {
things
}
Create file Manager.php which will contain Manager
class declaration:
include('DBManager.php');
Class Manager {
public userid;
function __construct($id){
$this->userid = $id;
}
function getGames(){
$dbManager = new DBManager();
$ret = $dbManager->queryDB($this->userid);
}
}
Include your classes where they are needed:
index.php
require_once 'DBManager.php';
$dbManager = new DBManager();
$userid = $dbManager->validateLogin(($_POST["name"], $_POST["pass"];
if ($userid){
$_SESSION["userid"] = $userid;
header("Location: lobby.php");
}
lobby.php
session_start();
require_once 'Manager.php';
if (isset($_SESSION["userid"])){
$manager = new Manager($_SESSION["userid"]);
$manager->getGames();
}
Upvotes: 1
Reputation: 559
You seem to have a misconception about how php code is distributed and used over multiple files and how these files are used.
For example if you use include()
or require()
instead of header()
, you can refer to the data you have defined so far.
A more advanced approach is to use __autoload()
or [spl_autoload_register()](http://php.net/manual/de/function.spl-autoload-register.php)
to load classes into your script and have an index.php
that starts your script.
(Also read the link @blacksheep_2011 provided)
Upvotes: 1
Reputation: 1143
you should not use global vars because it is bad style and will make your life really hard when the application gets bigger.
In your case you want to use the dbManager in different classes. Since db transaction are likely to be used often, look at the singleton pattern, so there can be only one instance of this class.
But be aware that you should keep the number of singletons as low as possible.
Look into this page to see how the singleton pattern can be implemented in PHP: http://www.phptherightway.com/pages/Design-Patterns.html
Upvotes: 1