Jul
24

Maintaining PHP session when using CURL.

Working now on some iGoogle like dashboard for the system I’m developing.

I was trying some stuff out with CURL and was having a hard time to maintain my current session when making a curl request to another page. I needed to stay authenticated in order to retrieve my widget.

Here is my initial code:

$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';     
$ch = curl_init($rssFeedLink); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie ); 
$response = curl_exec($ch); 
curl_close($ch); 

The problem with that piece of code is that it was generating a new session id instead of sending my current session.

The solution? Put session_write_close() before you make the CURL request.

$strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=/';

session_write_close();
     
$ch = curl_init($rssFeedLink); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie ); 
$response = curl_exec($ch); 
curl_close($ch); 

What does session_write_close() do? It, ends the current session and store session data. Apparently, PHP does not like when multiple scripts play around with the session, so, it locks it. Putting session_write_close makes sure that your current session is stored so you can retrieve it and use it.

This little issue had my head spinning for a few hours, so, I hope this article helps you.

41 Comments to “Maintaining PHP session when using CURL.”

  • Hi,

    I’m having trouble maintaining the session with PHP curl running in Linux.

    Here is an example that successfully logs into Amazon then should reload a homepage to demonstrate the use of cookies to maintain the session on the server.
    http://jgeewax.wordpress.com/2007/01/03/using-php-curl-to-sign-in-to-amazoncom/

    The first part of the script does log into Amazon, but it doesn’t return my name in the homepage refresh.

    Any advice is much appreciated.
    Cheers
    J

  • James,

    It would help if you gave me a little bit more info regarding the issue. What response do you get when it logs into amazon? are you sure the cookies are being stored into a cookies files?
    I would suggest you verify the content of the cookies file generated by cURL.

  • Julian,

    I have tried the script from the above link in two ways, both all contained in the same file and seperating the two CURL instances into seperate files. Both received the same results.

    Here is the contents of the cookie file after the successful Amazon logon:
    # Netscape HTTP Cookie File
    # http://curlm.haxx.se/rfc/cookie_spec.html
    # This file was generated by libcurl! Edit at your own risk.

    .amazon.com TRUE / FALSE 1252566000 session-id-time 1252566000l
    .amazon.com TRUE / FALSE 1252566000 session-id 191-4393894-7071610

    Here is the contents of the cookie file after the homepage request, which failed:
    # Netscape HTTP Cookie File
    # http://curlm.haxx.se/rfc/cookie_spec.html
    # This file was generated by libcurl! Edit at your own risk.

    .amazon.com TRUE / FALSE 1252566000 session-id-time 1252566000l
    .amazon.com TRUE / FALSE 1252566000 session-id 191-4393894-7071610

    Cheers
    J

  • Julain,

    Here is a dump of the source code. I’d appreciate it if you could try and run and let me know what you think.

    http://pastebin.ca/1553723

    Cheers

  • I am searching for a solution to the same issue. You’ve shown a very good solution. But, I’m wondering how this works.

    I’ve got 3 separate curl scripts that connect to a site to post data for a separate conclusion. If the code was all in one file everything would probably work fine, but I’m thinking that the separate curl handles makes for unexpected issues.

    Do you put this line of session_write_close in every file? Do you call something else?

    Thanks for your post!

  • @James – I’m sorry I didn’t get back to you sooner, I was out of town. I will try the code out and let you know my findings.

    @David – Are the 3 separate script files in the same project? meaning will they carry the same session? I would try putting it in all 3 scripts, and see what the outcome is!

  • Good to know that after a few hours of trying different things, I was simply missing session_write_close(). Thanks for posting this!

  • No Problem Mike. I’m glad to hear it helped you..

  • owsome, should be a google's sticky search

  • I believe you just solved my troubles! Thanks for dropping some wisdom.

    • Awesome Joe!
      it's great to hear that my post helped you solve your troubles.

  • great!!! it works sooo good….
    THANK YOU SO MUCH

  • please give to all good example of usage this block code… it’s very hardly to find something good in the internet

  • I might not working on something that related with IGoogle, but your solution here helps me dealing with curl with session problem. Thanks man!

    • Willy that's why I posted it. :) I knew that it was not a problem specific to what I was trying to do, but more of a cURL thing. I'm glad that the article helped you resolve your issue.

  • Perfect !!! It solved my problem !

  • For a more generic write (incase of different session paths, session ids on different PHP configs) you might want to use this….

    $strCookie = session_name()."=".session_id()."; path=".session_save_path();

    • It works perfectly! Thanks

    • Thanks Adam for your contribution.

  • Thanks a lot for this post, it helped me out quite a bit!

  • Thanks a lot. It saved my life.

  • Thank you very much!
    It helped me A LOT!

  • Thanks, this helped alot! :)

  • Thanks a lot, this "session_write_close();" solve my session lock problem.

  • I had the same problem. Thank you very much! It helped me a lot

  • hello im trying to access a page for scraping using CURL but im geting error of session id not found on server here is my code
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, "http://travel.travelocity.com/flights/InitialSearch.do?Service=TRAVELOCITY&last_pgd_page=ushpnbff.pgd&entryPoint=FD&pkg_type=fh_pkg&flightType=oneway&subnav=form-fow&leavingFrom=BOM&goingTo=CCU&dateTypeSelect=exactDates&leavingDate=08%2F08%2F2012&dateLeavingTime=Anytime&departDateFlexibility=3&departure_dt=Aug&returningDate=mm%2Fdd%2Fyyyy&dateReturningTime=Anytime&returnDateFlexibility=3&arrival_dt=Dec&adults=1&children=0&seniors=0&minorsAge0=%3F&minorsAge1=%3F&minorsAge2=%3F&minorsAge3=%3F&minorsAge4=%3F");

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt ($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Windows NT 6.1; rv:14.0) Gecko/20100101 Firefox/14.0.1');
    curl_setopt($ch, CURLOPT_HEADER, 1);
    if (preg_match('/Set-Cookie: JSESSIONID=(.*?);/',$output = curl_exec($ch), $matches))
    {
    $cookieVal = $matches[1];
    // echo $cookieVal;
    }

    curl_setopt($ch, CURLOPT_COOKIE,'JSESSIONID='. $cookieVal.'; Path=/');
    session_write_close();
    $output = curl_exec($ch);
    print_r($output);

  • Depending on your context, you might need to call session_start(); again after curl_close()…great insight, thanks so much!

  • Thank you SO much. I had been struggling with this for hours today. Finally was able to get my script working. THANK YOU.

  • someone can past again the code, because the URL its invalid…im trying make a session whit curl..If someone help, im appreciate.

  • great post

  • Hello Julian,
    I stuck at this point, and you saved my life. It's working perfectly well.
    I spend 5 hours solving this issue, add 10 to 15 extra lines to solve, with no luck. But only two lines of code solved my issue.

    Thanks a lot.
    (sorry for my bad english)

  • in case curl does not allow you to redirect, here is a recursive work around http://pastebin.com/kbeqiM9j

  • Thanks a lot for this article, it helped me lot, and give me solution which I was looking from last 2 days.
    Actually I wanted to call and api and wanted to provide admin credentials with it for other project on same server (in sub folder). So that when one user logged in on main project it gets automatically logged on other projects also.
    Here is my code it might help others,
    $url = "{$path}api/login.php?username=admin&pwd=admin";
    session_write_close();

    $ch = curl_init();
    $strCookie = 'PHPSESSID=' . $_COOKIE['PHPSESSID'] . '; path=//';

    curl_setopt($ch, CURLOPT_USERAGENT, "BotBrowser");
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_setopt($ch, CURLOPT_HTTPGET, 1);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_COOKIE, $strCookie );

    $res = curl_exec($ch);
    curl_close($ch);

  • [...] is the best way i found to do this link [...]

  • Good post! You should add @Adam's comment to the main content, because he is right.

  • I just wanted to tell you thanks, you saved me, like 99% other comments on here :)

  • I have a apache and tomcat working together, sharing the same session, but I can't keep the same session calling a Java Restful method. Unfortunately, it didn't work for me. Anyway thanks for the help!

  • This is a time saver… thanks for the tutorial. I works perfectly for my purpose

  • Thanks alot! This realy helped me!

  • I encountered this problem, and this post solved it. thanks. it should be on stackoverflow..

Leave a comment