Click to See Complete Forum and Search --> : PHP objects and memory use
Carth
09-15-2008, 12:13 PM
Hi, I'm using PHP4.
In the following example code.
class Something {
var $id;
var $whoDidIt;
function Something($id) {
$this->id = $id;
// get data from database
$whoDidIt = new User($userid);
}
}
class User {
var $id;
var $name;
// etc
}
Now, suppose two Somethings were done by the same User. If you change some data in the User of one Something, the other Something still has the old data in its User instance. When these Somethings are being created, I want it to reuse the instance of User created by the first one. Is there any way? Or... is there a better way of going about this?
chazzy
09-15-2008, 12:27 PM
I think first you need to explain whether:
$whoDidIt = new User($userid);
Actually creates a new instance of a User or if it's something you're pulling from the DB.
Ideally, they should point to the same instance, but it all depends on if it's practical or not.
NogDog
09-15-2008, 12:37 PM
What you should really do first is move to PHP5, both because its OOP support is much better, plus 4 is no longer supported.
Anyway, you may want to instantiate the User object, then pass it to each Something object that needs to use it. If using PHP4, you may need to pass it by reference, while in PHP5 passing by reference is the default behavior for objects.
<?php
class Something
{
var $whoDidIt;
function Something(&$user) // "&" passes by reference
{
$whoDidIt = $user;
}
}
class User
{
var $id;
var $name;
function User($id)
{
$this->id = $id;
}
}
$thisUser = new User(123);
$something_1 = new Something($thisUser);
$something_2 = new Something($thisUser);
Carth
09-15-2008, 12:55 PM
What you should really do first is move to PHP5, both because its OOP support is much better, plus 4 is no longer supported.
I know. :( I want to, and I use PHP5 on another server, but unfortunately this server still has 4 and the admin doesn't want to upgrade it.
<?php
class Something
{
var $whoDidIt;
function Something(&$user) // "&" passes by reference
{
$whoDidIt = $user;
}
}
class User
{
var $id;
var $name;
function User($id)
{
$this->id = $id;
}
}
$thisUser = new User(123);
$something_1 = new Something($thisUser);
$something_2 = new Something($thisUser);
The trouble with this is, it's the wrong way around. I find out who the user is from the Something class, I don't know beforehand. I don't think anything short of a global array of Users already created in the script will work, but I don't know if that is a good idea.
Maybe I need to rethink it entirely. I like to have a class for each database table because it makes my code simpler and easier to update. But I can't find a way to link them together. The parameter to the constructor is always a unique id, and I don't want duplicates from constructors called with the same id.
How do very large websites do things?
NogDog
09-16-2008, 09:05 AM
I'm not sure how to suggest anything without a better understanding of what the two objects are and how they are related. I was assuming that the ID passed to the "Something" constructor was the "User" ID. This would imply that you already know what the user ID is before either object is instantiated, so there would be no reason not to create the User object first, then pass it to any Something instantiation that needs to use that User.
However, you appear to be suggesting that this is not the case, so I guess I need a better explanation of what's going on, perhaps? (Even then, I won't claim I'm God's gift to OO Design, so who knows.)
Carth
09-16-2008, 12:10 PM
What if I had these database tables (not exact)
users
id INT PRIMARY KEY
name VARCHAR
projects
id INT PRIMARY KEY
name VARCHAR
startedby INT # id of a user
notes
logs
id INT PRIMARY KEY
project INT # id of a project
who INT # id of a user
logdate
notes
So the database stores projects, and each project has lots of log entries, and each entry is made by a certain user.
When I call $logentry = new Log(15); the number is the id of the log. After that I can call $logentry->getuser() and it gives me a User object... I want to be able to get a User object from a Log object and a Project object, and I also want to get a Project object from a Log object like $whichproject = $logentry->getproject(); $whichproject->getname()
Something like that...
NogDog
09-16-2008, 06:48 PM
All I can think of at the moment would be to create a sort of registry class for storing references to User objects. Then when another object wants to instantiate a User object, it first checks that registry object to see if there is already one instantiated for that user ID. If so, it grabs a reference to that object from the registry, otherwise it instantiates it and adds a reference to it to that registry object.
Carth
09-17-2008, 08:03 AM
Can you explain what a registry class would look like / how it would work please?
NogDog
09-17-2008, 12:14 PM
I was thinking of something along these lines:
<?php
class UserRegistry
{
var $users = array();
function getUser($id, &$userObj)
{
if(isset($this->users[$id]))
{
$userObj = $this->users[$id];
}
else
{
$userObj = new User($id);
$this->users[$id] =& $userObj;
}
return true;
}
}
class User
{
var $var = 0;
}
class Something
{
var $user;
var $userRegistry;
function Something($userRegistry)
{
$this->userRegistry = $userRegistry;
}
function someMethod($userid)
{
$this->userRegistry->getUser($userid, $this->user);
}
}
$userRegistry = new UserRegistry();
$test1 = new Something($userRegistry);
$test1->someMethod(123);
$test2 = new Something($userRegistry);
$test2->someMethod(123);
$test1->user->var = 99;
echo $test2->user->var;