How to store instances of the same object in PHP (stateless)? - php

I was looking at "Pimple", Fabien Potencier's "simple service container" for PHP, and I was intrigued by the following comment:
By default, each time you get a service, Pimple returns the same instance of it. If you want a different instance to be returned for all calls, wrap your anonymous function with the factory() method.
Based on how PHP is executed, how on earth would this be possible? Wouldn't PHP give me a new instance of an object every time a PHP script was executed?
EDIT: Pimple link - https://github.com/fabpot/Pimple

Answering this, because nobody in my comments did. The answer - you can't! PHP over HTTP is stateless, and I took the pimple documentation out of context.
If you need to achieve this, you should look into a cache system (APC, memcached) or an object server (Redis).
Thanks for the clarification.

Related

pros and cons of making my auth system a singleton class

I am facing a dilemma regarding OOP design of my application. Should I make the auth class a singleton or not. I see that kohana framework and zend framework use their auth classes as a singleton. What are the disadvantages of making the authentification class a singleton? What are the pros? Also the application I am building will be an enterprise application and it needs to scale, so will my auth system also scale if it will be a singleton?
Here would be some cons:
extremely hard to test, because code is tied to name of class
introduction of global state
inability to determine causes for an effect - unrelated methods can affect each other
scattering of authentication requests all over codebase
violation of LoD
You might benefit a lot from examining, at what stage and how exactly you authenticate the user ( do not confuse with authorization ). Also, this topic might be of some interest to you.
Update:
Here are few videos you might be interested in:
Clean Code Talks: Unit Testing
Clean Code Talks: Global State and Singletons
Clean Code Talks: Don't Look For Things!
PHP UK Conference 2011: Advanced OO Patterns
Avoid using the singleton and use it only in the case when a hardware has the limitation on one object -> resource per application. If you incorporate the singleton you will unable to exchange the auth class with something else in your system you will be stacked with it. Consider that tomorrow you could receive a new requirement which say you that you need to implement the authentication using a different logic, different connection and so on. Also though about how to test your system after using the singleton how will you mock it??
Don't go for Singleton! It's no better than glorified object-oriented namespace, in fact Singleton almost just as bad as using Global variables and only slightly better than using global function libraries (which in itself is also bad). It's better to send the created object to your classes.
Since PHP 5 objects passed around to other objects are passed by reference by default. They don't create a new instance (unless using clone keyword). This allows any sort of session info to be just passed as an object to other objects that need it.
Best thing I can recommend is make a class 'Session' that carries session specific information. Send this class to your MVC objects. This allows you to test the system without Session being present (or you can create a mockup state for that purpose). While passing one object to another makes them more coupled than ideal, as long as the class is primitive enough it can be easily created in other systems or parts of the app that use the same classes.
It also makes it easier to transfer states or sessions at any given time, even within the same request.
In PHP, the object doesn't stays in the memory once the request is completed.
So even if you make your object as Singleton, every request will have its own instance of that class.
But the the difference will come when object is being accessed multiple times in a single request. In that case, singleton has following advantages:
Prevents creating multiple redundant instances, so lesser memory usage for requests.
Shares the same data across multiple accesses.
Eg: Codeigniter's get_instance function is an implementation of Singleton Concept, whereby only one Codeigniter instance is used in each request.

storing SoapClient for next request - php

I have an script which I call through a browser, in which I create a SoapClient object.
I want to store the SoapClient object such a way that I can use it again when I hit the script through browser.
All I want to achieve is avoiding connecting again and using the previous connection.
I tried storing it in session but the SoapClient object loosing values of attributes sdl.
explained here https://bugs.php.net/bug.php?id=36395
Is there any other way of implementing.
As the PHP manual page says:
Note that many built-in PHP objects cannot be serialized.
There are some exceptions but I don't think SoapClient is. Anyway I honestly can't think of a reason why you'd want to do it as performance-wise it will probably be less efficient doing the serialize/deserialize than instantiating the SoapClient class with every request.
Instantiating a SoapClient from a WSDL is pretty straightforward and you'd be better off just doing that. You can write some helper function to do that for you.

Zend AMF custom dispatcher

Is it possible to use a custom dispatcher when using Zend_AMF?
I know I can pass either a class name or an object to setClass() for Zend_AMF.
However, when I pass an object to setClass, it does not seem to store a copy of that object. Instead it worksout the class name and then instantiates a copy of the object itself.
This is a problem as I use the yadif dependency injection container. Objects should be instantiated with constructor dependencies and/or property dependencies.
Since the Zend_Amf dispatcher does all the instantiating, I am not able to inject constructor dependencies and other dependencies to my objects.
If anyone has a strategy as to how I can overcome this without touching any of the code in Zend_AMF, that would be great :)
The solution is to basically build a wrapper around Zend_Amf. The way it is written means that I had to copy most of the code in the handle and _handle() methods. I then had to modify some called methods to point to an instance of Zend_Amf I have created.
Finally, the dispatching was changed so that my own dispatcher was called, and the results returned.
Obviously not the most elegant solution, but hopefully they will rework Zend_AMF to be a bit more extensible in the future and allow us to hook into it much easily.
At the moment, I can still easily drop in an updated version of Zend_AMF into my "vendors" folder without modifying any of the code.

Calling multiple functions with Zend AMF and one NetConnection?

I have Zend AMF working great in my application, but I'm trying to figure out how to call multiple asynchronous functions with a single connection. For example, let's say I have a service called "MyService" and two functions called "init" and "getData". Can I create a connection, call "MyService.init" THEN "MyService.getData" within the same remote object? If so, how...if not, what is a better solution?
Of course, in this scenario, I can just combine init and getData into one function...but, the problem in the actual scenario is that there are many more methods that will need to run after "init". Thanks!
I have an unanswered question that I asked here I believe for the same reason as yours. I would love to know how to call multiple methods or even better, classes over one connection.
Anyway, in your case where you are talking about methods, with no answer on how to call them from the flex side, I would either make a 3rd method that calls those two, or allow some kind of object or parameter passing for init and let init call getData.
Another thought - maybe you need to consider what is happening in init and whether you really need it or need to call it directly from the client - for example, in order to getData (or put or etc), you always have to have been initialized? So getData should probably check to see if it has been initialized and init if it has not.

My logger keeps getting destructed while I am trying to log errors and exceptions

I am just now switching back to PHP after enterprise open-source Java development for three years. Now I am tasked with updating our platform for better logging.
I now understand better how the PHP object lifecycle regarding when objects are garbage collected and have trapped my problem. I am trying to invoke the logger after its already been destructed, when a fatal error occurs. My question is, how do I fix this? How can I stop an object from being destroyed until the end of the request?
Ideally I would like to keep this logger around in memory like I would in Java but is that even possible with PHP? Is there anything shared between two different threads or requests?
With PHP, each request is processed by a different process -- which means you quite cannot keep some object arround between requests (you could serialize it and store it in a file or something like that, and un-serialize it when another requests comes ; but that's not really the way things are generally done)
This means each time your PHP script receives a request, you have to re-instanciate your logger.
Now, if you want to use your logger from several different classes/methods/functions in the same script, you have to know that variables are not global "by default" in PHP : a variable declared outside of a function is not accessible from inside a function, unless you said so using the global keyword.
In this kind of situation, when you want one and only one instance of a specific class (your logger) available from anywhere in your application, people often use the Singleton Design Pattern.
It'll allow to use something like this :
My_Logger_Class::log('blah');
From any portion of your code, and the log method will deal with :
instanciating the class if there was not already one existing instance
the actual logging
And, yes, the first time this method is called for one HTTP request, it'll have to re-open the log file (if logging to a file).
As a sidenote : there are already some existing great logging components, like PEAR::Log or Zend_Log.
Maybe using one of those might help you spend less time re-inventing some wheel ?

Categories