paylike / php-api

A PHP client for accessing the API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ReactPHP and Singleton Client

visitek opened this issue · comments

This implementation is very dangerous and absolutely useless...
ReactPHP bootstraps only once for application. There is not shutdown in the end of request.. It waits for another request for another user. API key is still in memory..

Sorry, but we can not use this library. It is wrong approach for PHP

We can use only Adapter class 👍

Hi @visitek,

I'm not sure I understand correctly, but:

The API key is not different from request to request (it's per merchant/application) so I can't see the problem in having a singleton that spans multiple requests. You do not want to instantiate using the API key for each request at least.

Problem is in singleton generally ... it drains memory while using ReactPHP ... it can not be easily flushed from memory.
ReactPHP works like this:

  1. bootstrap - load application into memory
  2. wait for request
  3. handle request
  4. clean services and close session

[2-4] is repeating until server restart or release new version of app ...

when we are using singleton, object stay in memory, but it shouldn't in this case :) Yes, it is something new with PHP

Client::setKey();

can not be used, beacause Adapter is static and saved for slave process for a week .. for example

I agree that in general you would want to avoid singletons.

it can not be easily flushed from memory

Why do you want to flush it between each request? Does ReactPHP not support having database connections, configuration, etc. on an inter-request level?

Yes, but is is all handled by frameworks.. In our case it is ZendFramework3 (Singleton is restricted pattern in frameworks). Frameworks are ready to handle more request simply by dispatching with possibility to reset internal state. That's it.. flush internal state. But what about singleton? It can not be reset, can it?

dirty solution

setAdapter(null);

but Client is still alive... when it is instantiated, it is flushed after request with gc_collect_cycles() or unset

Yes, but is is all handled by frameworks

So the framework is a singleton in itself, and seems to be keeping singletons for you as well.

The Paylike client is like the framework: there is no reason to create a new instance between requests, that would be suboptimal, just like a database connection.

However, even if you pretend that the client is not a singleton, I can't imagine it would behave any different in regards to either memory or behaviour, as long as you only use a single API key.

I'm really interested in learning why you think this is a security implication?

The API key will be in the memory for the lifetime of your application. You could possibly have the application read it from somewhere external on each use, but given that the application then must have read-access to that place, I would regard it as less or just as secure as the memory of the application.
If you have separate threads (or similarly independent contexts) for each request and don't want the key in the memory of the requests' context, there is nothing about a singleton preventing you from that.

I'm aware of that - I've read some of the documentation and it looks heavily inspired by Node.js, which I've been using for the past five years.

I still see nothing wrong in keeping the singleton "alive" alongside your framework, DB and whatever. It will not leak memory or keys because of that. It's actually how it should be in my opinion - keeping it in the outer scope and not introducing it to each scope of the requests.

If you have some code snippets (gists maybe?) it might be easier for me to understand your concern?

We use our own API for that. closing

I've opened a separate issue for just the singleton pattern #12.