I am coding my first CodeIgniter application (very familiar with PHP, but not CI) and have the following setup:
I have a controller, Signup, that controls a signup process. Every function of the controller is the next step in the process. I have an object, Did, that I am currently loading as a library. This object's properties/variables are updated as the signup process moves along.
The issue I'm having is that the properties from one function of the Signup controller do not carry over to the next function. It is as if the class is re-constructed with every function.
Is there a way to reuse the class throughout the controller without it having to be re-instantiated? I'd rather not have to serialize and store in a session, either.
Thanks in advance.
As always, there are many solutions to the same problem. Please disregard this if it doesn't fit well with your implementation.
Keeping the signup steps in an object is a good idea- however, every time you load a new page CI rebuilds all the objects. In order for data to persist it should be stored in the session, but that doesn't mean you have to be working with session variables in your controller.
How are you transferring data to your application? Is it via forms or ajax?
One way you can do it is by unserializing the object from the session and storing it as an object in your controller's constructor. That way you can still run $myObj->function() against it and use a $myObj->save() function to reserialize and store it.
Hope that helps!
The problem you are having is that you are depending on the in-memory state of your application to remain from request to request.
You're expecting your class to use the same instantiation of your Did object between requests.
This is not how PHP/HTTP works. Each request is handled individually and is it's own instance of your application. So each request creates a new Did object.
To persist the state you need to either use Sessions to carry information between requests, use a database to handle your persistent state, or a combination of both.
Codeigniter Sessions
Codeigniter Database Class
Related
Is it safe to create google_client object and store it in $_SESSION variable.
Can we then use same google_client object from $_SESSION variable on multiple pages to do google stuff. Or, do I have to make new client on every page?
Most of the tutorial or example on internet use only one page, how to use google_client on multiple pages is what I trying to figure?
Keep creating it, but all the auth process and rest of the CLIENT_ID and other important information can be stored in variables for future use. Just instance it every page, re-auth with refresh token with every page change and you're good to go. Also you could do a specific GoogleConnection.php header kind of style and stop worrying of having it to type it every time you add a new page.
I believe your approach to the problem you're facing could be replaced with a different implementation pattern.
It sounds like your just trying to create the Google_Client object once, and have it persist throughout the application; probably to minimize the need to refactor code. I would recommend you find an appropriate location in your code, that's hit on every page load, and instantiate the object there.
If you're using a framework, it's very likely you can hook into a Bootstrap mechanism. If this is a custom build, then just find the most suitable centralized location you can.
But to answer your question, I would definitely not recommend putting your Google_Client object in a session variable.
I have searched and searched and found tons of examples but it seems that everyone has a different opinion about how and when to use session, some use it some say it is evil...
Here is my use case.
I have a Class that has several variables that will need to be used on every page in my application. These variables values are set by making a SOAP call to an API that I am working with. The SOAP call is relatively quick but I am trying to understand how to avoid making a call to the API on every page. I would much prefer to make the call once and then "store" the values somewhere.
I would think that I would just create an Instance of my class on some say Init.php page, make the SOAP calls and then store the whole class in session. Then on all of my pages include the Init.php page. In that page I would do a check to see if the Class existed in the session and if so then pull it form the session.
I know I have to serialize\deserialize the class to do this but I am looking for some feedback here on weather this is the right way to satisfy this use case or if there is a better option?
I am kinda new to PHP, mostly a .NET guys and in .NET the session is generally the best way forward.
All input is appreciated.
thanks
I assume when you stay "serialize\deserialize the class," you really mean you want to serialize/deserialize a class instance (an object) in the session, not the actual class definition. Be careful when using the terms class, instance, and object, since they are not interchangeable and can lead to confusion.
An object can be easily stored in a PHP session. PHP automatically serializes the object at the end of the request and deserializes it when the session data is read on the next request.
session_start();
if (!isset($_SESSION['soap'])) {
$_SESSION['soap'] = doSoapRequest(); // Returns an instance of your class.
}
When an object is serialized, only the variables defined in the class are saved along with the name of the class. When it is unserialized, the class definition must be available (that is, either autoloader or explicitly included into the script). Unserializing will create a class instance with the same data as the object that was previously serialized.
Imagine that I want to login a user. The user sends the validation data, and my controller gets the POST request so it calls a User Repository method in order to registered him.
I'd like to start the user Session with the user data. But how should I start the session? Should it start in the controller or the model? I think it should be the model, since it's my business logic who says that session have to be started. But how? Should I pass the session object to my Repository?
Im using Doctrine for the model layer, and my own framework for the rest. I use dependency injection but I don't see how to get access to the Session from the entities / repositories layer.
The only solution I've got right now is to call the repository method passing the session as a parameter, but it doesn't feel right.
I think session handling should be done in the controller, but just personal opinion. If you are trying to have a clean separation of concern, it should defiantly be done it the controller. It doesn't make a lot of sense to make Doctrine (which has a very strong focus on abstraction and independence) dependable on the session.
Make a controller which calls a method from model to register the user. The model method returns the user specific data, which you pass to the Session (from controller). You will probably use session in a lot of places, not relevant to model. Why make it stretch to two levels, if you can encapsulate it in one?
I am working on this app that accesses session variables in the model layer. This just seems wrong but am willing to be proven wrong. Maybe not wrong but, in most places in app, session variables are handled in controller and passed in as arguments but, in other places, the session value is just accessed. Am I wrong that this seems like bad practice?
edit:
one reason I don't like sessions in models is that it seems to make it more complex to test. Keep it as just params passsed to functions and then recordset passed back.
thx
It depends.
The way I think about this is such:
A Model represents your data layer.
most of the time that data layer will be DB Table based
The Session is just another data storage medium.
Conclusion: If the data that your model represents is stored in the Session, than it is OK to access that data from within the model
An example is a Session based shopping cart. My cart's objects are models of my session data.
Controller shd do a check weather session exist or not before using the model which uses that session inside it .
No it shouldn't. The storage type, should be apart from your business logic. For example:
I have one simple plug-in that perform the access check and put the user object on the registry. So, instead of access session, the model have access to the registry, which is well defined.
$User = Zend_Registry::get('User'); // User model object
From the theoretical point of view, everything should be accessed through data mappers. In the future, if you change from session storage to something else, you'll need to update it just in one place. Your models do not need to know from where the data came from.
If you are taking more than one path to get your data, probably this will cause some problems when your application get large.
The OOP and layered systems approach suggestion is to created specialized objects and layers and keep things simple preventing specific actions to be spread all over the code.
But again, you do not need to change that unless you see advantages.
Keep in mind that sometimes refactoring is more efficient than try to predict everything.
What's stored in the session variables? If it's simply 'logged in? Y/N', then they probably don't need to be part of the model layer. If, however, it's more complex than that, they are probably inextricably linked to your business model and should be treated as such.
The examples at the bottom of the Zend Test documentation show how to test the full MVC using a login function. Presumably you could do the same when testing models?
What options are there to implement an own session management in PHP?
Is there a nice way to implement a component which performs all session tasks?
How can i construct a class which receives the HTTP Request and Response during one request process?
I only found the option "session_save_handler" which seems to define the storage handler. What I need is to replace the whole session management.
Is there another way using the PHP configuration or do I have to implement my own controller which receives all requests and calls my session management?
Thanks for your help
Regards Michael
No, I'm sorry to say, there is no interface to switch the built in 'modules' to your own. There are some hooks ( e.g: session_save_handler(), set_error_handler() ), and that's unfortunately it.
The $_SESSION is a 'super global' and should IMO not be set directly either way if you're working on a bigger projects. Then it would be better to use a custom class responsible for handling sessions. Will make the code easier to debug and such on.
I am not sure, what you want to achieve. It seems more like you want to abstract away from the $_SESSION variable than that you want to change the storage.
Take a look at the way the Zend or the Solar framework handle the Session access.
http://www.phpeveryday.com/articles/Zend-Framework-Session-Introduction-P571.html
http://solarphp.org/manual:sessions
How can i construct a class which receives the HTTP Request and Response during one request process?
I don't know, what you mean by receiving the response, but the frameworks have front-/page-controllers which route to the chosen action, then call a method that can access the Session (read/write) and Request (read) objects and generates a Response object which is then rendered through a template.
For automatic testing you can construct your own Request and Session objects and pass them to the page controller.
You said it yourself in one of the comments. Just wrap the $_SESSION in a class. I don't think you can replace it, but you can certainly build your own interface to it.
You could, for example. Build a class that is constructed first thing and call session_start() inside the constructor
Using the session_save_handler() function allows to handle how the session information is stored and retrieved.
By default PHP stores the session information in temporary files located somewhere on your web server. You can define callback functions using the session_save_handler() function where you can have this information stored in a database table instead.
Even if you handle sessions with your own defined functions with the session_save_handler() function you would still access the information with the superglobal variable $_SESSIONS.
Check out this page from the php online manual. Has lots of useful information with regards to your question. Hope it helps.
You could create a session implementation with cookies and a database. You set a cookie on the client's machine. Then, you run a lookup on a database, something like this:
+--------+------+
| sessid | data |
+--------+------+
Where sessid contains a reference to the cookie (probably some king of md5 or SHA hash), and data is something like a JSON or Serialized array.
The functions:
You can use the function runkit_function_redefine(), which is part of the Runkit API, to redefine the session_xxxx functions.
Note: Runkit is part of PECL. That is, NOT BUNDLED WITH PHP. You will have to install it yourself.
The session variable:
$_SESSION = &SessionClass->data;
Simplicity itself: just make $_SESSION as a reference to YOUR data.