Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#2982 closed patch (fixed)

mythweb session.php

Reported by: anonymous Owned by: xris
Priority: minor Milestone: unknown
Component: mythweb Version: head
Severity: low Keywords:
Cc: jcrandall@… Ticket locked: yes

Description

I am using the latest SVN version of mythweb.

The page(s) seem to fully render and at the bottom of every mythweb page I get this:

Fatal error: Call to a member function query() on a non-object in /var/www/mythweb/includes/session.php on line 60

After discussion on irc I was told to file this bug.

I see no errors in the apache2 log. Ubuntu Linux version 2.6.20-5-generic PHP5

Other than the error message which seems to indicate a 'session' issue mythweb seems fully functional.

Attachments (1)

ticket2982.patch (696 bytes) - added by jcrandall@… 12 years ago.
Patch to fix this bug by adding a destructor to the Database object which restores the global $db reference and calls session_write_close.

Download all attachments as: .zip

Change History (13)

comment:1 Changed 12 years ago by jcrandall@…

Severity: lowmedium

I am at revision 12642 and I can confirm this error exactly.

I am using: PHP v5.2.0 Apache 2.2.3 Mysql 5.0.30

For me, though, this bug is more serious as it seems to cause a javascript error which means my browser does not load the recorded program list.

comment:2 Changed 12 years ago by xris

Resolution: worksforme
Status: newclosed

There's nothing wrong with the code. Please make sure that your svn checkouts updated the db object files properly (there's a new directory, etc). If you have to, delete the entire includes/ directory and run svn update to restore it properly.

comment:3 Changed 12 years ago by anonymous

Deleting the includes directory and running svn update worked for me.

comment:4 Changed 12 years ago by jcrandall@…

Resolution: worksforme
Severity: mediumlow
Status: closedreopened

I first tried deleting just the includes directory, then blew away everything under mythweb, and did svn update to get a fresh copy. This solved the problem that my browser didn't load the recorded program list, but I still see the error message on the bottom of every screen.

xris: what software versions are you using? I note in the mythweb/INSTALL document, it says that the developers are using PHP 5.1.x, and I am using 5.2.0 -- could this possibly be a PHP version issue?

comment:5 Changed 12 years ago by xris

Yeah, it could be. Undo revisions [10527] and [10544] (php5->php4 on the db objects) and let me know if that changes anything.

comment:6 Changed 12 years ago by mythtv@…

Hi,

I am experiencing the same problem, and updating the source from svn doesn't help. I'm using the stable 0.20 branch for mythplugins, and I'm not entirely sure what I'm running on the MythTV side of things because I justed used apt-get to install it.

Anyway, I've had a look at the code. On line 60 in includes/session.php, inside function sess_write, it does:

global $db;

Unfortunately, after this point, $db is null. However, under sess_read for example, its there. I've tried to debug by going to the end of the code (modules/welcome.php, right before exit;), and print_r'ing $db there, and it exists. sess_write is being called after this point though, and therefore I can't get any further. I can see that session_set_save_handler is being used, but I'm not familiar with how this works and don't have the time now to look into it. I assume that PHP is calling the write session function after everything is done.

I have solved this problem by commenting out the unset on line 140 in includes/init.php, and then adding:

        $db = Database::connect($_SERVER['db_name'],
                                $_SERVER['db_login'],
                                $_SERVER['db_password'],
                                $_SERVER['db_server'],
                                NULL, 'mysql');

in the place of global $db; in includes/session.php.

I am in no way suggesting that this is a good solution, I just wanted to hack something together tonight to get this working. Tomorrow I might have some more time to look at it. If anyone out there wants to contact me about this, just send me an email.

comment:7 Changed 12 years ago by jcrandall@…

I tried to back out [10527] and [10544] but there seem to have been too many changes to the Database objects since then to apply it. Anyway, I pursued alternate debugging approaches and I now believe I understand this bug.

Checking the PHP5 documentation for session_set_save_handle (http://us2.php.net/session_set_save_handler) I noticed the warning:

"Write and Close handlers are called after destructing objects since PHP 5.0.5. Thus destructors can use sessions but session handler can't use objects. In prior versions, they were called in the opposite order. It is possible to call session_write_close() from the destructor to solve this chicken and egg problem."

I believe what is happening here is that sess_write is now being called after the database object is destroyed. I have confirmed that a workaround for this is to call session_write_close(); just before the PHP script calls exit;.

The only reason I can think of why other people are not seeing this error is that perhaps they have error_reporting set to something else than we do. Mine is set to:

error_reporting  =  E_ALL & ~E_NOTICE

in my system php.ini file.

I am having a problem locating the most appropriate place in the code to put the session_write_close(); call. I currently have it in modules/_shared/tmpl/default/footer.php, just after the code block for displaying footnotes and before the end of the PHP. That works fine, but IMO is not really where it belongs, since it is certainly not a "display" element. It could also be added to the end of each module, between the template call and the exit; but that is kind of a mess too, since it needs to be all over the place.

A better place to put it might be in the destructor for the database classes, but I am having trouble getting that to work for some reason (I'm not a PHP guy and the PHP5 classes are totally new to me). Ideally it would be in the Database object and would be inherited by each of the database implementations, but I'm not clear on whether an abstract class can have a destructor implementation...

xris, with this explanation, can you recommend a change that fixes it cleanly?

Alternatively, if you think it's ok to just add the session_write_close(); before exit; in each of the modules, I can submit a patch that does that and that is working just fine for me.

Changed 12 years ago by jcrandall@…

Attachment: ticket2982.patch added

Patch to fix this bug by adding a destructor to the Database object which restores the global $db reference and calls session_write_close.

comment:8 Changed 12 years ago by jcrandall@…

Cc: jcrandall@… added
Type: defectpatch

Ok, I figured out why my destructor solution wasn't working, and have fixed it.

The patch has been attached. Please review.

comment:9 Changed 12 years ago by xris

Resolution: fixed
Status: reopenedclosed

(In [13083]) Merge the object-destruct handler from simech's code, which should hopefully resolve the issues some people are having with php destroying objects too early. closes #2982

comment:10 Changed 12 years ago by felixfurtak@…

Hi, this may be a stupid question, do any lines need to be deleted in Database.php when inserting this patch? Or is it just inserted at line 80? Thanks, Felix.

comment:11 Changed 12 years ago by xris

It's all checked into svn. No need to apply any patches.

If you want to run it in .20, then you can probably just grab Database.php from svn and use it. The bugfix to support php 5.2 touches a couple of other places, though, so wouldn't be as easy to apply.

comment:12 Changed 12 years ago by xris

Ticket locked: set
Note: See TracTickets for help on using tickets.