Problem with classes

I am trying to display items in cart.I created two classes cart.php,database.php.both are in different directories.When i execute cart.php page i get the error.

Notice: Undefined variable: db in C:\ runk\library\classes\cart.php on line 12

Fatal error: Call to a member function find_by_id() on a non-object in C:\ runk\library\classes\cart.php on line 12

cart.php code

require_once('c:\	runk\\library\\configuration\\paths.php');
var_dump($db);
class Cart
{
	var $items=0;
	var $price=0;
	public function add_item($p_id)
	{
		$query='SELECT product_name,product_price FROM products WHERE product_id='.$p_id;
		$item=$db->find_by_id($query);
		echo $item->product_name;
	}
	
}
$shopping_cart=new Cart();
$p_id=$_GET['p_id'];
switch ($_GET['action'])
{
	case 'add_item':
		
		$shopping_cart->add_item($p_id);
}

Database.php code

class Database
    {
        public $connection;
		
        public function open_connection()
        {
            $this->connection=mysql_connect(DB_SERVER,DB_USER,DB_PASS);
            if(!$this->connection)
            {
                die("Database Connection Failed".mysql_error());
            }
            else
            {
                $db_select=mysql_select_db(DB_NAME,$this->connection);
                if(!$db_select)
                {
                    die("Database not found".mysql_error());
                }
            }
        }
        public function find_by_id($query)
        {
            $result_set=mysql_query($query,$this->connection);
            $result_set=$this->fetch_assoc($result_set);
            $result=(object)$result_set;
            return $result;
        }
        public function fetch_assoc($result_set)
        {
            return mysql_fetch_assoc($result_set);
        }
  }
    $db=new Database();
    $db->open_connection();

I can able to access the $db object in the previous page of cart.php.How to solve it?

^ Agreed. Globals shouldn’t be floating around everywhere because it allows anything anywhere in the application to cause one hell of a problem. For example, say a newbie programmer didn’t realise $db was used before in the function and had something like:

class Cart{
    public function add_item($p_id){
        global $db; 
        /* some code */
        $db = $_POST['db']; //using post in classes is also not a good idea, but this IS a newbie ;)
    }
}

For the rest of the application $db is now, well and truely, useless.

If you give objects access to a variable passed down to them, the scope is limited to the method itself, and any methods said method calls later on down the chain. If it were overridden, the variable would be kept safe for any code run separately from the class in question. Of course, methods to change the object would be run, so keep important life-saving (maybe not…) methods private and only allow database calls through the database. If you want to use a different connection, you can simply create a new database object and, as far as I know, the original would be conserved for parent methods.

I would post a code snippet but it wouldn’t be much different from Anthony’s code, so use that to play around with :slight_smile:

Global variables ($db) are not directly accessible from inside of methods. I know it’s a bit counter intuitive.
http://ca3.php.net/manual/en/language.variables.scope.php


class Cart
  public function add_item($p_id)
    global $db;

Global is not the way to go, check out Dependency Injection. :slight_smile:


<?php
class Cart
{
  protected
    $storage = null;
  
  public function __construct(CartStorage $storage){
    $this->storage = $storage;
  }
}

class CartStorage
{
  protected
    $database = null;
  
  public function __construct(Database $database){
    $this->database = $database;
  }
}

class Database
{
  public function query($sql){
    
  }
}
?>

Unless I’m missing something I do not see a declaration of the Database class in your cart code.