One class setting calling another's method

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
jbraxx
Forum Newbie
Posts: 4
Joined: Fri Mar 19, 2010 1:23 am

One class setting calling another's method

Post by jbraxx »

I have a Session class with a method called message. $session->message() stores a message in $_SESSION so that I can send a message from a form processing page back to the form page if some form data is missing or incorrect (i.e. if somebody skips a required field they'll be returned to the form with a message to fill in that field).

My form processing script is in my Customer class. It checks through the form data and if it catches an error it notes it in a field_errors array. At the end, if the array is empty, it returns true. If not, it redirects the user back to the form page. At least it's supposed to, but what's happening instead is I'm getting this message from PHP:

"Notice: Undefined variable: session in /Applications/MAMP/htdocs/rip/includes/customer.php on line 63

Fatal error: Call to a member function message() on a non-object in /Applications/MAMP/htdocs/rip/includes/customer.php on line 63"

The Session class is included before the Customer class, so I don't understand why it thinks session is undefined. Any idea how I can fix this? The relevant parts of the scripts are below.

Thanks!

--------------CUSTOMER CLASS----------------

Code: Select all

<?php

class Customer {
	public $name;
	public $addr1;
	public $city;
	public $state;
	public $zip;
	public $email;
	public $email_comp;
	public $field_errors = array();
	
	public function create() {
		if(!$this->name = trim($_POST['name'])) { $this->field_errors = "Please enter your name."; }
		if(!$this->addr1 = trim($_POST['addr1'])) { $this->field_errors = "Please enter your address."; }
		if(!$this->city = trim($_POST['city'])) { $this->field_errors = "Please enter your city."; }
		if(isset($_POST['state'])) { $this->state = $_POST['state']; } // not required
		if(isset($_POST['zip'])) { $this->zip = trim($_POST['zip']); } // not required
		if(!$this->email = trim($_POST['email'])) { $this->field_errors = "Please enter your email address."; }
		if($this->email != $this->email_comp) { $this->field_errors = "The email addresses you entered did not match."; }
		if(empty($this->field_errors)) {
			return true;
		} else {
			$session->message("...");
			redirect_to('index.php?page_id=5'); // This function is defined in a separate functions file and works in other contexts
		}
	}
?>
--------------SESSION CLASS----------------

Code: Select all

<?php

class Session {
	
	public $message;
	
	public function message($msg="") {
		if(!empty($msg)) {
			$_SESSION['message'] = $msg;
		} else {
			return $this->message;
		}
	}
	
	private function check_message() {
		if(isset($_SESSION['message'])) {
			$this->message = $_SESSION['message'];
			unset($_SESSION['message']);
		} else {
			$this->message = "";
		}
	}
	
	
}
?>
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: One class setting calling another's method

Post by requinix »

Relevant parts? How about customer.php around line, say, 63?
jbraxx
Forum Newbie
Posts: 4
Joined: Fri Mar 19, 2010 1:23 am

Re: One class setting calling another's method

Post by jbraxx »

I cut out parts at the top to save everyone from reading through code that isn't involved. I can post the whole thing if that's easier, but what was line 63 is now near the bottom of the customer class where it makes a reference to the Session class:

Code: Select all

else {
       $session->message("...");
       redirect_to('index.php?page_id=5');
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: One class setting calling another's method

Post by AbraCadaver »

That makes reference to a session object but you have not instantiated an object and it wouldn't make sense to do that there anyway. You either need to create a new session object in the main code and add it to a registry and then retrieve it in the user class, or you can use the session class statically (not sure why).
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
jbraxx
Forum Newbie
Posts: 4
Joined: Fri Mar 19, 2010 1:23 am

Re: One class setting calling another's method

Post by jbraxx »

The Session class gets instantiated at the top of every page, so I don't think that's the issue. I'll post the full version of the two classes here to make things clearer:

-------------------SESSION CLASS---------------------------

Code: Select all

<?php

class Session {
	
	public $message;
	
	function __construct() {
		session_name("RIP-session");
		session_start();
		if(isset($_SESSION['start_time']) && time() - $_SESSION['start_time'] > 3600) {
			$this->message("Your current session has expired and your cart has been emptied.<br />Please add items to your cart.");
			redirect_to('index.php?');
		} 
		if(!isset($_COOKIE['RIP-session'])) {
			redirect_to("error.php");
		}
		$_SESSION['start_time'] = time();
		$this->check_message();
	}
	
	public function message($msg="") {
		if(!empty($msg)) {
			// then this is "set message"
			// make sure you understand why $this->message=$msg wouldn't work
			$_SESSION['message'] = $msg;
		} else {
			// then this is "get message"
			return $this->message;
		}
	}
	
	private function check_message() {
		// Is there a message stored in the session?
		if(isset($_SESSION['message'])) {
			// Add it as an attribute and erase the stored version
			$this->message = $_SESSION['message'];
			unset($_SESSION['message']);
		} else {
			$this->message = "";
		}
	}
	
	
}
$session = new Session();
$message = $session->message();

?>
-------------------CUSTOMER CLASS---------------------------

Code: Select all

<?php

class Customer {
	protected static $table_name = "orders";
	public $order_id = "";
	public $name = "";
	public $addr1 = "";
	public $addr2 = "";
	public $city = "";
	public $state = "";
	public $province = "";
	public $zip = "";
	public $nation = "";
	public $phone = "";
	public $email = "";
	public $email_comp = "";
	public $card = "";
	public $card_no = "";
	public $exp_mo = "";
	public $exp_yr = "";
	public $ship_name = "";
	public $ship_addr1 = "";
	public $ship_addr2 = "";
	public $ship_city = "";
	public $ship_state = "";
	public $ship_province = "";
	public $ship_zip = "";
	public $ship_nation = "";
	protected $datetime;
	public $field_errors = array();
	
	public function create() {
		$this->datetime = strftime("%Y%m%d%H%M%S", time());
		if(!$this->name = trim($_POST['name'])) { $this->field_errors = "Please enter your name."; }
		if(isset($this->name, $this->datetime)) { $this->order_id = substr($this->name, 0, 4) . "-" . $this->datetime; }
		if(!$this->addr1 = trim($_POST['addr1'])) { $this->field_errors = "Please enter your address."; }
		if(isset($_POST['addr2'])) { $this->addr2 = trim($_POST['addr2']); }
		if(!$this->city = trim($_POST['city'])) { $this->field_errors = "Please enter your city."; }
		if(isset($_POST['state'])) { $this->state = $_POST['state']; }
		if(isset($_POST['province'])) { $this->province = trim($_POST['province']); }
		if(isset($_POST['zip'])) { $this->zip = trim($_POST['zip']); }
		if(!$this->nation = $_POST['nation']) { $this->field_errors = "Please enter your country."; }
		if(isset($_POST['phone'])) { $this->phone = $_POST['phone']; }
		if(!$this->email = trim($_POST['email'])) { $this->field_errors = "Please enter your email address."; }
		if($this->email != $this->email_comp) { $this->field_errors = "The email addresses you entered did not match."; }
		if(!$this->card = $_POST['card']) { $this->field_errors = "Please enter your card type."; }
		if(!$this->card_no = $_POST['card_no']) { $this->field_errors = "Please enter your credit card number."; }
		//$this->exp_mo = $_POST['exp_mo'] { $this->field_errors = "Please enter your city."; }
		if(!$this->exp_yr = $_POST['exp_yr'] && $this->exp_mo = $_POST['exp_mo']) {
			$this->field_errors = "Please enter your card's expiration date'.";
		}
		if(isset($_POST['ship_name'])) { $this->ship_name = trim($_POST['ship_name']); }
		if(isset($_POST['ship_addr1'])) { $this->ship_addr1 = trim($_POST['ship_addr1']); }
		if(isset($_POST['ship_addr2'])) { $this->ship_addr2 = trim($_POST['ship_addr2']); }
		if(isset($_POST['ship_city'])) { $this->ship_city = trim($_POST['ship_city']); }
		if(isset($_POST['ship_state'])) { $this->ship_state = $_POST['ship_state']; }
		if(isset($_POST['ship_province'])) { $this->ship_province = trim($_POST['ship_province']); }
		if(isset($_POST['ship_zip'])) { $this->ship_zip = $_POST['ship_zip']; }
		if(isset($_POST['ship_nation'])) { $this->ship_nation = $_POST['ship_nation']; }
		if(empty($this->field_errors)) {
			return true;
		} else {
			$session->message("...");
			redirect_to('index.php?page_id=5');
		}
	}
	
}

?>
User avatar
AbraCadaver
DevNet Master
Posts: 2572
Joined: Mon Feb 24, 2003 10:12 am
Location: The Republic of Texas
Contact:

Re: One class setting calling another's method

Post by AbraCadaver »

Right, so $session is a global var and isn't available in class or the method unless you define it global or access it as $GLOBALS['session'], which would totally negate using OOP. Look at the registry pattern. Add objects that you need application wide and then retrieve them where you need them: http://www.phppatterns.com/docs/design/the_registry

Another way, depending on how your app is designed, would be to create an application object or something that creates and stores these other objects.
mysql_function(): WARNING: This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQLextension should be used. See also MySQL: choosing an API guide and related FAQ for more information.
Post Reply