5

We have a need to keep a collection of socket objects around that are associated with different client browser sessions, so that when the client's browser makes a subsequent request, we can use the existing socket connection/session to make a request on their behalf. The socket is to something that is not HTTP. Is there a way to store objects like this in PHP that will survive across page requests?

Keith Hill
  • 194,368
  • 42
  • 353
  • 369
  • This loosk like essentially the same question as [Is there a way to share object between PHP pages?](http://stackoverflow.com/questions/908108/is-there-a-way-to-share-object-between-php-pages), which was on the top of the related questions list. –  May 05 '17 at 22:55
  • Thanks for the pointer! Looks like the answer is, sadly, no. – Keith Hill May 06 '17 at 20:33
  • 1
    check this http://stackoverflow.com/questions/6863494/storing-objects-between-requests-in-php-without-serialising –  May 08 '17 at 11:14
  • Are these domain sockets? Because if they're local sockets you could open them on disk and store the socket path in a session variable to be shared across requests. – Matt S May 08 '17 at 17:52
  • @MattS They are local sockets. Interesting idea. I'll give this a try. – Keith Hill May 08 '17 at 19:30
  • To be fair, the last question is almost 8 years old, and the PHP world has changed somewhat. – haz May 10 '17 at 05:01

4 Answers4

4

Is there a way to store objects like this in PHP that will survive across page requests?

No.

To quote zombat's answer to a very similar question:

In PHP, there is no concept of page instances. Every request to the web server is a fresh start. All the classes are re-loaded, so there is no concept of class sharing, nor is there a concept of resource pooling, unless it is implemented externally. Sharing sockets between web requests therefore isn't really possible.

If the objects were serializable, you could use PHP's serialize() and unserialize() in conjunction with MySQL memory tables to solve this issue. Other than that, I don't think there's much else you can do.

Community
  • 1
  • 1
Amal Murali
  • 75,622
  • 18
  • 128
  • 150
2

This isn't a complete answer; but it steps towards an answer.

As has been pointed out ad nauseum elsewhere, the standard, classic model of using PHP, via a web server (Apache, Nginx, etc) does not allow you to do this, because each page hit starts with an entirely fresh set of variables.

Three thoughts:

  1. You need a persistence layer. Obviously this is where you store stuff in a database, or use APC (APCu in PHP7+), Redis, or something similar.

Your problem, however, is that you specify "unserializable."

  1. My next suggestion would be, perhaps you could persist the elements necessary to construct the object, and re-initialise the object for each PHP request. It won't be as amazingly performant as you'd like, but it's the most useful solution without having to rewrite eveything. Perhaps you've already tried it.

  2. The next step is to do something completely out-there. One of the advantages the NodeJS infrastructure has is that the entire server loop persists.

So you could try one of the alternate methods of running PHP, like ReactPHP or PHP FastCGI. (There are others, but I can't remember them off the top of my head. I'll edit this if I remember.)

This involves an entirely different way of writing PHP--as different as NodeJS programming is from stuffing around with jQuery inside your browser. It wouldn't run within Apache. Rather, it would run directly as an app on your Unix server. And you'll have to cater for things like garbage collection so you don't have memory leaks, and write nice tight event loops.

The plus side is, because your thread persists and handles each subsequent request, you're able to handle requests in exactly the way you're after.

haz
  • 1,549
  • 15
  • 20
2

In php script dies after page load so there is no way to do it. Hovewer you can create a long-living daemon which will open all required by process sockets and keep it opened between page reload. Of course you'll need to isolate these sockets by some kind of access key to make sure different sessions won't have access to other user's sockets. Also you need to keep in mind that it will die at some moment so make sure you have logic to restart all the sockets which were opened. But it can be achieved for sure.

Thanks.

Ilya Kovalyov
  • 484
  • 2
  • 10
-1

Your comment mentions these are local sockets. And it sounds like the PHP application acts as a socket client. So the only thing which is needed by the PHP session is a common identifier, such as a user ID, and for the sockets to be named consistently.

So, for example:

<?php 
$userid = $_SESSION['userid'];
$fp = stream_socket_client("unix:///tmp/socket-" . $userid, $errno, $errstr, 30);
if ($fp) {
    fread...
}
Matt S
  • 14,976
  • 6
  • 57
  • 76