Access Quercus PHP-Session from Java Servlets/Filters/Beans – Part 1

If you are integrating a PHP Application in your Java Environment, you’ll probably came across Quercus, a Java Implementation of PHP provided by Caucho Technologies.

As you are moving more and more into the Servlet world, you’ll probably will be using Servlet-Filters and normal Servlets todo some tasks.

If you then want to access Variables in a PHP Session, here’s how to do it:

The Quercus PHP-Session is not stored the same way as the normal Servlet HTTP-Session is stored. Quercus uses an own Session Manager that is capable of doing all this stuff that you know from PHP, like e.g. migrating Session-IDs (to prevent session-hijacking etc.).

To access this Session Manager, you first have to get a hand on the QuercusContext. In the current release (4.0.7) there is no easy way to get a hand on it if you are not inside a PHPModule or a PHP-Page. Thus I simply copied com.caucho.quercus.servlet.QuercusServlet to com.caucho.quercus.servlet.DCQuercusServlet and added this line to the end of the method:

1
2
3
4
5
6
  private void initImpl(ServletConfig config)
    throws ServletException
  {
....
      config.getServletContext().setAttribute("quercusContext", quercus);
 }

which exposes the QuercusContext as an Attribute in the ServletContext.

(Note: If you are running multiple QuercusServlets in your WebApp – which you probably shouldn’t – this might will be a problem)
(Note2: The package name com.caucho.quercus.servlet must be used, or else you will not have access to some package scoped properties used in the QuercusServlet)
Ok, so now we have access to the QuercusContext from every Servlet, Filter or JSF-Bean, horray 🙂

But how to use it?

Lets take a look at the following filter and its methods helping me to work with the PHP-Session:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public class LoginOutFilter implements Filter {
 
    QuercusContext context; // we store the reference to the quercusContext in the filter
    FilterConfig config; // the reference to the config 
 
... 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
    }
 
    // looks up the QuercusContext the first time it is accessed
    // Beware: will return null if no PHP page has been rendered yet and the quercusContext is not already set. 
    private QuercusContext getQuercusContext()
    {
        if(context == null)
        {
            context = (QuercusContext) config.getServletContext().getAttribute("quercusContext");
        }
        return context;
 
    }
 
    // find the PHP-Session Cookie in the array of Cookies provided by the browser
    public Cookie findPHPSessionCookie(Cookie[] cookies)
    {
        for(Cookie c : cookies)
        {
            if(c.getName().equals("PHPSESSID")){
                return c;
            }
        }
        return null;
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
     if(someCondition)
     {
                // clear a PHP-Session, e.g. when logging out a user
                Cookie c = findPHPSessionCookie(((HttpServletRequest) servletRequest).getCookies());
                if(c != null){
                    QuercusSessionManager mng = getQuercusContext().getQuercusSessionManager();
                    String phpSessionId = c.getValue();
                    mng.removeSession(phpSessionId);
                }
     }
 
     if(someOtherCondition) {
                        QuercusSessionManager mng = getQuercusContext().getQuercusSessionManager();
 
                        SessionArrayValue val;
                        Cookie c = findPHPSessionCookie(((HttpServletRequest) servletRequest).getCookies());
                        String phpSessionId;
                        if(c != null)
                        {
        // we found a session cookie
                            phpSessionId = c.getValue();
                            val = mng.getSession(null, phpSessionId, new Date().getTime()  );
                            if(val == null)
                            {
        // but the session does not exist on the server, so create it
                                val = mng.createSession(null, phpSessionId, new Date().getTime());
                            }
 
                        }else
                        {
          // we haven't found a php-session cookie, so create a new session
                            val = mng.createSession(null,null,new Date().getTime());
                            phpSessionId = val.getId();
          // and store the appropriate cookie
                            Cookie newCookie = new Cookie("PHPSESSID", phpSessionId);
                            ((HttpServletResponse)servletResponse).addCookie(newCookie);
                        }
     // storing data in the session
                      String username = "myUsername";
                        val.put("ludata_suserid", username);
                        val.put("ludata_nusernr", someService.getUserId(username));
                        val.put("ludata_nstatusnr", someService.getUserStatus(username));
                        val.addUse(); // This is required for saving, else an IllegalStateException will be thrown
                        mng.saveSession(null, val);
       }
     }

The above code shows how to erase a session and how to add values to a session. To get values from a session, simply use val.get(..).

Attention: This currently only works if the page after the filter is not a Quercus Page itself (e.g. a Servlet or a JSF Page). I’m working on a solution for this

Leave a comment

Your email address will not be published. Required fields are marked *