2

i have a php page which has some variables regarding database i.e server address, username and password etc.

config.php will include

<?php 
  $dbserver="";
  $username="";
  $password="";
  $database=""; 
?>

i have a class which contains all the functions required for my website. How can i import my php page variables into this class to be used for the database connectivity?

my class

<?php
    class a{
      include("config.php");
      function db_connect(){
        mysql_connect($dbserver,$username,$password);
      }
    }
?>
booota
  • 1,231
  • 5
  • 17
  • 36

3 Answers3

2

usually for this purpose, Constants exist.

But if you want to use variables, all you have to do is to require_once(yourFile), then when you want to use these variables (which are global) inside a method of a class, simply refer to them as global $myVar; (as if you're declaring it). Only need to do this once for each global variable you want to use in the context.

Example:

settings.php:

$conn = 'my connection';

MyClass.php:

class MyClass
{
    function DoSomething()
    {
        require_once('settings.php');
        global $conn;
        doSomethingWith($conn);
    }
}
AlexanderMP
  • 13,118
  • 5
  • 37
  • 58
  • Using constants is the way to go. – Hammerite Nov 11 '10 at 10:26
  • the `global` keyword should be avoided. It will make `MyClass` depend on the global scope which makes your application harder to maintain and unittest. – Gordon Nov 11 '10 at 10:57
  • thanks for the kind response. my php page eg config.php will include my class class a{ function db_connect(){ mysql_connect($dbserver,$username,$password); } } I think i am more clear now. How will i use the variables listed in config.php into my class a? – booota Nov 11 '10 at 11:01
  • Gordon, it's as simple as it can get, under these conditions. They can of course be public members of a class, then you'd have to create a settings object each time, which is much more bloated and ugly. Always compromises. – AlexanderMP Nov 11 '10 at 11:17
  • @Alexander It's not a matter of compromises. It's [poor](http://stackoverflow.com/questions/3169303/php-global-variables) [design](http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html). – Gordon Nov 11 '10 at 11:35
  • @Gordon. Please write an answer. – AlexanderMP Nov 11 '10 at 12:09
  • @Alexander the answer is: use Dependency Injection – Gordon Nov 11 '10 at 12:25
  • @Gordon let me get this straight. You propose that when calling each function, the programmer has to write a ton of parameters. Or that the programmer must carry a $SettingsObj object through every context? Now, I understand that there may be a lot of different ways to do this, but the more CORRECT you do this, the more you complicate yourself, even when it's not needed. Go ahead and use DI. But you'll get what you get - a slower, larger, harder to read, bloated code, that writes "Hello world". I do agree that in certain cases this is necessary, but I don't think it's this case here. – AlexanderMP Nov 11 '10 at 13:02
  • @Alexander Yes, this is exactly what I propose, just that your assumptions about it are wrong. It's neither slower, nor harder to read, nor bloated. In fact, it is easier to read because when using DI your API will clearly say "invoke fnX with arguments a,b,c" while your approach only says "invoke fnX", which is a lie because fnX will not work if there isnt a file settings.php on the include path that defines a variable $conn. How would you UnitTest your fnX? You cannot without creating the settings.php file. It's code like this that turns applications into maintenance and debug horrors. – Gordon Nov 11 '10 at 13:29
  • 1
    @Gordon: Exactly. I currently have to maintain 3 projects i inherited where a "simple" style with a lot of globals was preferred. It's a horrible mess and slow as hell. I'd propably give both my hands for PHP removing globals alltogether so i can give a good reason for rewriting everything. – Morfildur Nov 11 '10 at 13:56
2

Update

For a Database class that requires configuration options, the simplest way would be to use the config values as parameters (example 1 of my original answer below).

A more complex, though also more flexible approach would be a Config-Class.

class Config
{
  private $config = array();

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

  public function Register($key, $value)
  {
    $this->config[$key] = $value;
  }

  public function Get($key)
  {
    if (!isset($this->config[$key])) return null;
    return $this->config[$key];
  }
}

Your DB class would look something like this:

class Database
{
  private $config = null;

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

  public function Connect()
  {
    do_connect_stuff($this->config->Get('host'), $this->config->Get('user'), .....);
  }
}

File config.php

<?php

$config = new Config(
  array(
    "host" => "localhost",
    "user" => "user",
    ...
  )
);

/*
alternative:
$config = new Config();
$config->Register('host', 'localhost');
$config->Register('user', 'user');
...
*/
?>

File that requires the database:

<?php

$database = new Database($config);
$database->Connect();

?>

As a side hint: Use PDO, it's far better than the old mysql_* functions.


Original Answer

The proper style would be to pass the variables to the functions as parameter or pass them when creating the object. You can also use Init methods to pass the parameters.

Examples:
(Which of the following code you should use depends on what you already have and how your code is designed, the 'cleanest' way would be an object for which you transmit the variables when calling the ProcessAction method)

Assuming that in your script you have a Variable $action which you get from $_GET or some other way.

Using an Object

class Controller
{
  public function ProcessAction($action, $some_other_parameter, $and_yet_another_parameter)
  {
    [...]
  }
}

You then call it with

$action = do_some_stuff_to_get_action();
$controller = new Controller();
$controller->ProcessAction($action, $other_parameter, $second_parameter);

Using a static class

class Controller
{
      public static function ProcessAction($action, $some_other_parameter, $and_yet_another_parameter)
      {
        [...]
      }
}

Called with:

$action = do_some_stuff_to_get_action();
Controller::ProcessAction($action, $other_parameter, $second_parameter);

Passing the parameters before calling the function

Object

class Controller
{
  private $action = "";
  private $some_other_parameter = "";

  public function __construct($action, $some_other_parameter)
  {
    $this->action = $action;
    $this->some_other_parameter = $some_other_parameter;
  }

  public function ProcessAction()
  {
    if ($this->action == 'do_stuff')
    {
      [...]
    }
  }
}

Called with:

$action = do_some_stuff_to_get_action();
$controller = new Controller($action, $other_parameter);
$controller->ProcessAction();

Static methods

class Controller
{
      private static $action = "";
      private static $some_other_parameter = "";

      public static function Init($action, $some_other_parameter)
      {
        self::$action = $action;
        self::$some_other_parameter = $some_other_parameter;
      }

      public static function ProcessAction()
      {
        if (self::$action == 'do_stuff')
        {
          [...]
        }
      }
}

Called with:

$action = do_some_stuff_to_get_action();
Controller::Init($action, $other_parameter);
Controller::ProcessAction();
Morfildur
  • 12,196
  • 6
  • 32
  • 54
  • +1 for dependency injection. The static class is not an option though as it effectively creates the same tight coupling as using globals would. Try to mock that static controller in some class that uses it. It's just painful. – Gordon Nov 11 '10 at 10:54
0

I used the database configuration in the constructor of the class. I think that was the only solution not including any third page in the scenario.

booota
  • 1,231
  • 5
  • 17
  • 36