When a user logs into my site, I create an instance of my User
class, fetch some user-related data and store the object in the SESSION
.
Some of the data I fetch from the database should be constant throughout the session AND I want the data to be accessible from other objects. I prefer using User::$static_value_in_class
to $_SESSION['static_value_in_session']
when using the value from within another object, but I'm open to persuasion.
The problem is, the values aren't remembered when I serialize my User
instance into the SESSION
, then load a different page.
Class definitions:
class User {
public $name;
public static $allowed_actions;
public function __construct($username, $password) {
// Validate credentials, etc.
self::$allowed_actions = get_allowed_actions_for_this_user($this);
}
}
class Blog {
public static function write($text) {
if (in_array(USER_MAY_WRITE_BLOG, User::$allowed_actions)) {
// Write blog entry
}
}
}
login.php:
$user = new User($_POST['username'], $_POST['password']);
if (successful_login($user)) {
$_SESSION['user'] = $user;
header('Location: index.php');
}
index.php:
if (!isset($_SESSION['user'])) {
header('Location: login.php');
}
Blog::write("I'm in index.php! Hooray!")
// Won't work, because Blog requires User::$allowed_actions
Should I implement Serializable
and write my own version of serialize()
and unserialize()
to include the static data?
Should I bite my lip and access the $_SESSION
variable from within the Blog
class?
Should I require a valid User
instance sent to the Blog
write()
method?
Or maybe the internets has a better idea...
EDIT: Writing my real use case (not full code, but enough to get the gist).
My site handles groups of users with shared budget accounts.
Users may spend group money on certain things the group agreed upon, and they report transactions by creating instances of the Transaction
class and sending it to the Bank
class for database storage.
Bank
class:
class Bank {
// Group-agreed reasons to spend money
public static $valid_transaction_reasons;
public function __construct(User $user) {
Bank::$valid_transaction_reasons = load_reasons_for_this_group($user->bank_id);
}
}
User
class:
class User {
public $bank_id;
public function __construct($username, $password) {
$query = "SELECT bank_id FROM users WHERE username=$username AND password=$password";
$result = mysql_fetch_array(mysql_query($query));
$this->bank_id = $result['bank_id'];
}
}
Transaction
class:
class Transaction {
public function __construct($reason, $amount) {
if (!in_array($reason, Bank::$valid_transaction_reasons)) {
// Error! Users can't spend money on this, the group doesn't cover it
}
else {
// Build a Transaction object
}
}
}
Actual code (login.php, or something):
$user = new User($_GET['uname'], $_GET['pword']);
$_SESSION['bank'] = new Bank($user);
// Some shit happens, user navigates to submit_transaction.php
$trans = new Transaction(REASON_BEER, 5.65);
// Error! Bank::$valid_transaction_reasons is empty!