Just another Perl shrine | |
PerlMonks |
Using Sessions between perl and php.by jryan (Vicar) |
on Jan 20, 2002 at 01:07 UTC ( [id://140131]=perlmeditation: print w/replies, xml ) | Need Help?? |
A very common web technique nowadays is the use of sessions. Most programming languages have support for sessions; however, what happens when you need more than one language able to access the same session? Well, it gets messy. At my most recent place of employment, we ran into the problem where we needed php and perl sessions to communicate with each other. My co-worker (a certain Steve Stetak, an awesome programmer who unfortunately isn't a perlmonk) and I eventually came up with a solution using Apache::Session::MySQL and some hacking of php's serialization. How do I use it?1. What are sessions?Sessions are a method to hold state variables between different scripts or different instances of a script. For example, when I log into Hotmail. I give the first page my username and password. These values are then stored internally by the server, and accessed everytime I go to a new page. Only when I hit the logout link are these values destroyed. 2. How do they work?When you first start a session, the script first creates a cookie on the client browser with the session ID. The session ID is a unique 32 character string that identifies each session. You scripts then register "session variables" which are stored in a MySQL database. The variables are then accessable as long as you have the session ID. 3. What are some limitations of our system?Due to the amount of PHP and Perl scripts on the server that would need to use sessions, we must come up with a universal way to access sessions in both languages. Unfortunately, this eliminates some of the functionality of sessions. For example, the only session variable that can be used is the PHP associative array "$session" and the Perl hash "%session" 4. How do I use sessions with PHP with our system?To begin a session with PHP, you must first require the session handler file at the beginning of all the scripts that use sessions.
Then, to begin the session, call the function
This function first checks to see if there is a cookie defined with the session ID. If there is, it uses that ID to load the session variable. If there is no cookie, it creates a new, random session ID and places it in a cookie. It then creates an empty session. If there is no session defined already, then you must register the session variable. To do this, you must first define the associative array, and then register it to the session.
You can now use the $session variable throughout your script. All members of the $session array will be available for all the scripts using the same session. When you are finished with the session (i.e. when the user logs out) you must call the session_destroy() function do destroy the session and remove the cookie. 5. How do I use sessions with Perl while using the system?Unfortunately, using sessions with Perl is slightly more complicated. First, you must include the following lines at the beginning of your script:
The CGI modules is used to access the cookie, because, unlike PHP, Perl sessions do not handle cookies for you, while the Apache modules are used to access the MySQL database and store the session data there. Next, you must initialize the CGI instance and get the cookie ID.
Now, you can begin you session, by tieing the %session hash to the MySQL database. If $sess_id is undef then it will create a new session, with a new session ID.
You can now save your session variables in the hash. Note that if you pass a session ID to the tie function that does not exist, for example, from an old cookie whose data has been deleted, the script will die. See the sample Perl script for a workaround to this problem. Note also that the session ID is stored in $session{'_session_id'} If you have created a new session, you must set a cookie.
When you are done with a session (i.e. the user logs out) you should destory the session. Do this with:
6. How do I use sessions with PHP and Perl?Using the above method, your sessions should work with both PHP and Perl. One condition is that, after creating a session in PHP, you must initialize the session ID variable, using the line:
7. What are some things to remember?
How does it work?Perl and PHP each use a different method to serialize the data. Serialization allows the languages to "flatten" the data. Basically, it takes all the variables you want to store and puts the data necessary to recreate these variables into a string. Perl uses the functions Freeze and Thaw from the module Storable, while PHP uses its own, native serialization function. It is not possible to modify how the language serializes the session data. However, we can modify the way PHP stores the data and we can use Perl to emulate the PHP serialization functions. So, no modifications have been made to the Perl side of the sessions. On the PHP side, however, we have to install custom storage handlers. The first step to doing this is to modify the etc/php.ini file, setting session.set_save_handler = user; This tells PHP that we will be using custom handlers. Unfortunately, it is not possible to use custom handlers in one script and PHP's default handlers in another. So, all PHP scripts that use sessions must use the same method. Next, we have our custom handlers. The first is mysql_sessions_handler.php:
These functions define how the PHP scripts open, close, read, write, and destory the session. As you can see, the open and close functions are empty. Normally, we would open and close a connection to the MySQL database. However, all of that work is done in the Perl scripts. Let's look at the read and write functions. Notice that they both call a perl script from the command line. The read function is passed a session ID and return serialized data. The Perl script below handles the data.
The Perl script takes a single argument, the session ID. It then opens the MySQL database and returns the data. Remember, that the data in the MySQL database will always be "frozen", meaning serialized by the Perl functions. So, next the script will thaw the data. The script now has a Perl reference to the session data. It then uses the serialize function which emulates PHP's serialization function.. Notice also, that the script prepends "session|" This is due to differences in the freezing and serialization functions. So, this script outputs the serialized session data, and gives it to the custom handler, which feeds it back to PHP. On to the write function. The write function gets passed a session ID and serialized data to store. Since the data is already serialized, there is another Perl script to unserialize, freeze, and store the data.
The first step is to remove "session|" from the beginning of the serialized data, so that it will freeze/thaw properly. The script then unserializes the data and freezes the reference, and then stores it in the MySQL database; Sample PHP Script
Sample Perl Script
Back to
Meditations
|
|