Jump to content

__wakeup() does it work?


Cep

Recommended Posts

Hi,

 

I have a class which creates an object with a database property. This property holds as you might of guessed a database connection object (mysqli to be precise).

 

Much like the following,

 

----- mydatabaseinclude.php -----
$db = new mysqli('server', 'user, 'password', 'database');

----- myscript.php -----
require_once("mydatabaseinclude.php");

$user = new User($db);

Class User {

public $db;

public function __construct($conn) {
$this->db = $conn;
}

 

If I then store the User object in a session variable (so I can traverse my scripts) this will cause my object to lose its database connection object. So I decided to use __wakeup() to re-establish the database connection when the User object is unserialized from the session.

 

---- extra function in User Class ----

public function __wakeup() {
require_once("mydatabaseinclude.php");
$this->db = $db;
}

 

The problem is, the magic method does not appear to be working. I am using PHP 5.2.5. Is this even the right way to do what I am trying?

Link to comment
Share on other sites

It does work, but you need to return an array in the __sleep() method. The array values are the properties which you wish to retain when serializing the object.

 

Example:

<?php
class WakeupTest
{
private $foo;

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

public function __sleep()
{
	echo "ZzZzZz...\n";
	return array('foo');
}

public function __wakeup()
{
	echo "Good morning\n";
}
}

$obj = new WakeupTest('bar');

$obj2 = unserialize(serialize($obj));

var_dump($obj, $obj2);
?>

 

Output:

ZzZzZz...
Good morning
object(WakeupTest)#1 (1) {
 ["foo:private"]=>
 string(3) "bar"
}
object(WakeupTest)#2 (1) {
 ["foo:private"]=>
 string(3) "bar"
}

Link to comment
Share on other sites

I see, thank you.

 

I am still not getting very far with this though and it may be a misunderstanding on my part.

 

As the example I show states, the object of class User has a property ($db) which contains the database connection object from another class (mysqli class).

 

Am I right in believing that if I assign the user object to a session or even instantiate to a session like this,

 

$_SESSION['myobj'] = new User($db);

 

This automatically serializes the object into the session variable? Or should I be explicitly calling the serialize function beforehand like this?

 

$myobj = new User($db);

$_SESSION['myobj'] = serialize($myobj);

 

And then when I move to another script I then unserialize the object from the session,

 

$myobj = unserialize($_SESSION['myobj']);

Link to comment
Share on other sites

Well using var_dump on the object on page1.php before it is assigned to a session, I get this for the output,

 

object(User)#8 (18) {
  ["db"]=>
  object(mysqli)#1 (0) {
  }
  ["group"]=>
  object(Group)#10 (4) {
    ["group_id:private"]=>
    int(2)
    ["group_name"]=>
    string(14) "Administrators"
    ["group_permissions"]=>
    string(1) "1"
    ["db"]=>
    object(mysqli)#1 (0) {
    }
  }
  ["user_id:private"]=>
  int(1)
  ["user_username:private"]=>
  string(6) "myuser"
  ["user_password"]=>
  string(40) "474ba67bdb289c6263b36dfd8a7bed6c85b04943"
  ["user_state"]=>
  int(1)
  ["user_status:private"]=>
  int(1)
  ["user_group_id:private"]=>
  int(2)
  ["user_group_name"]=>
  string(14) "Administrators"
  ["user_group_permissions:private"]=>
  string(1) "1"
  ["user_profile_id"]=>
  int(1)
  ["user_profile_css"]=>
  string( "main.css"
  ["user_profile_name"]=>
  string( "Standard"
  ["user_permissions:private"]=>
  string(1) "1"
  ["user_email"]=>
  string(30) "my.name@my-group.co.uk"
  ["user_ext"]=>
  int(335)
  ["user_displayname"]=>
  string(11) "My Name"
  ["user_warning"]=>
  NULL
}

 

On page two when I then var_dump the session and I get this,

 

object(User)#4 (18) {
  ["db"]=>
  object(mysqli)#5 (0) {
  }
  ["group"]=>
  object(Group)#6 (4) {
    ["group_id:private"]=>
    int(2)
    ["group_name"]=>
    string(14) "Administrators"
    ["group_permissions"]=>
    string(1) "1"
    ["db"]=>
    object(mysqli)#5 (0) {
    }
  }
  ["user_id:private"]=>
  int(1)
  ["user_username:private"]=>
  string(6) "myuser"
  ["user_password"]=>
  string(40) "474ba67bdb289c6263b36dfd8a7bed6c85b04943"
  ["user_state"]=>
  int(1)
  ["user_status:private"]=>
  int(1)
  ["user_group_id:private"]=>
  int(2)
  ["user_group_name"]=>
  string(14) "Administrators"
  ["user_group_permissions:private"]=>
  string(1) "1"
  ["user_profile_id"]=>
  int(1)
  ["user_profile_css"]=>
  string( "main.css"
  ["user_profile_name"]=>
  string( "Standard"
  ["user_permissions:private"]=>
  string(1) "1"
  ["user_email"]=>
  string(30) "my.name@my-group.co.uk"
  ["user_ext"]=>
  int(335)
  ["user_displayname"]=>
  string(11) "My Name"
  ["user_warning"]=>
  NULL
}

 

The interesting part is that these dumps are virtually identical except next to the objects the hash numbers change. Unfortunately these are the only part of the var_dump that I cannot translate so I have no idea what they mean :D

Link to comment
Share on other sites

Ah I see :) At least I now what they mean now.

 

However there still seems to be a problem with my script because even though these var_dumps appear to show identical information, when I then try to run a method from the object on page 2 which uses the database object it throws a number of mysqli related errors.

 

Warning: mysqli::prepare() [function.mysqli-prepare]: Couldn't fetch mysqli in C:\Inetpub\wwwroot\mom\lib\packages\system\class_group.php on line 106

 

It seems as though the mysqli references in the class cannot use the database object as if it does not exist. This is of course ridiculous because as we can see the database object is there and retains the same name. So why would the script throw these errors?

Link to comment
Share on other sites

No, this isn't why persistent connections were made. A persistent connection is just a MySQL thread that exists even when PHP is not connecting to it, after the intial creation. If a persistent thread is available PHP will utilise it, otherwise it will create a new one. This has nothing to do with the serialisation of the objects in question.

 

What's on line 106?

Link to comment
Share on other sites

aschk, forgive me for not understanding your tone. I actually think what he is trying to accomplish is the reason persistent connections are available. Maybe I wasn't clear.

 

Cep, http://us2.php.net/mysqli_pconnect

 

Unless there's a reason you would like to serialize a specific connection, I recommend the route of using a persistent connection. See it's benefits mentioned by aschk above.

 

 

 

Link to comment
Share on other sites

You know what keeB I never saw that when I went through the manual. :) However isn't there issues with using persistent connections?

 

I'm rather new to OOP so I am still getting my head around it but from what I gather I should be able to pass a database connection object to another objects properties and then serialise the object with sessions. This doesnt appear to work though, so I have had to create an include for my database connection in the __wakeup method in case the database property becomes vacant.

Link to comment
Share on other sites

Whether you used persistent connections or not wouldn't matter in this case. You'd still have to explicitly call the connect function anyways which means that the __wakeup() method would have to be called because the resource in the variable would be gone.

Link to comment
Share on other sites

Point taken, Daniel0, but I am (again) assuming he doesn't care about having to call connect() after a __wakeup(), but the reason he was previously not using this method was because he wanted to have a persistent connection to the database.

 

 

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.