The class instance that I want to store in session holds an array of loaded DOMDocuments.
As noted in one of the answers here: PHP quirks and pitfalls, when you serialize an object containing XML, the XML structure does not survive the unserialize process. As I understand it PHP5 is supposed to automatically serialize session data, so what I need to know is how to make XML survive the serialize/unserialize process?
I've read about and it looks like it can't be done, plus the overhead involved in writing and reading the session file with the automatic serializing/deserializing seems to make it preferable to just read and write the XML files in the class instance on __sleep and __wakeup. Is that the case?
http://php.net/manual/en/function.serialize.php
This is useful for storing or passing PHP values around without losing their type and structure.`
The value to be serialized. serialize() handles all types, except the resource-type. You can even serialize() arrays that contain references to itself. Circular references inside the array/object you are serializing will also be stored. Any other reference will be lost.
what is php resources
list of php resources
perhaps you can consider to store the original data into memcache, database,
while your session is pointing to that (like memcache key, database row ID)
additional read-up
you might felt amuse for the following (maybe i was wrong) -
http://www.php.net/manual/en/simplexml.resources.php
http://www.php.net/manual/en/dom.resources.php
http://www.php.net/manual/en/session.resources.php
Why don't you simply export the DOMDocument as a string, then serialize this string?
Related
I'd like to know if there's a way by which a PHP object could be sent to another PHP page on a different machine?
For instance - I've implemented a class that constructs a Trie. Now after the Trie has been constructed , I'd like to send across the object to another PHP page so that it can access the object too.
Would probably packaging it into some sort of encoded JSON request and then sending it to a page which could relay it to the required page using jQuery , be a feasible option ?
I'm sorry I'm absolutely new to this !
Will Appreciate any help provided.
Cheers!
An object is an instance of a Class. Objects can't be sent around as they are. A "transmissible" object must be Serializable: make sure that your class implements Serializable
Once you've implemented the interface, just call the serialize and deserialize methods to get the object-string and to rebuild the object
Use php functions serialize() and unserialize(). When you unserialize the object, be sure to have its class defined.
personally I'd store the object in an object store rather than serialise memcache, APC even a session can be used, you can also use nosql style databases and key stores all of which are pretty much perfectly suited to object persistance as they're mostly very fast access data stores without the sql overhead. nosql-database.org
Just assign each object a key based off the key of the user browsing generate a new key for each new browser and store it in session/cookie to retrieve their personal "objects"
As already mentioned by STT you can serialise and store in the session thats perfectly fine although serialise is retarded to implement in php they should never have put that in.
Instead look at APC and SPL both are built in to php (APC is more suited for an object store especially since from 5.6 (I believe so onwards) its no longer an extension but built into the PHP core its self making it fully native so you get not only a simple object store but also op code cache which will seriously increase the speed of your php pages.
Note: APC is only really usable for object store when you run a single web / php server if you need multiple processing servers then you'll need a distributed object store in which case the best you can probably get is memcache
Lots of links mostly all on SO.
When should I use Memcache instead of Memcached?
Memcached vs APC which one should I choose?
http://php.net/manual/en/book.memcached.php
http://php.net/manual/en/book.apc.php
Is there a way in PHP to use persistent data as in Java EE? (sharing objects between PHP threads) without session nor cache/DB
The right way is to implement Serializable interface in the class of your object (if it doesn't yet) that pass it through some sort of transport between two servers.
Try to not send data trough client-side code unless you trust client or you don't care about data.
Suppose I'm loading a large number of objects from a database. These are normal, plain PHP objects, no inheritance from anything fancy. Suppose I might change a few of these objects and want to write them back to the database, but only use the fields that actually differ in the UPDATE ... SET ... query. Also suppose that I don't know in advance which objects are going to be changed.
I'm thinking that I need to make a copy of all the objects loaded, and keep around for reference and comparison, should I need to write objects back to the database.
I see two possible approaches:
I can either clone all the loaded objects and store in a separate list. When saving, look up the object in the list using an index, and compare the values.
Or, I can simply serialize everything loaded into a string, and keep around. When saving, find the serialized object in the string (somehow), unserialize it, compare the values, and there you go.
In terms of efficiency (mostly memory, but speed is also a consideration), which would be favorable?
Well you actually needs something to compare if the state of the object has changed or not. If you even want to track not only which object has changed but also which member, you need to have a state per member.
As you don't want to extend the original objects (e.g. they could have a flag they invalidate when they are changed), you need to track the state from the outside. I'd say serializing is probably the best option then. Cloning will take more memory.
As you know, when you store a class defination in SESSION serialized automatically, and are unserialized on each following pages.
I just started to write classes and I wonder that:
to store a class in session or a file with serializing is a good idea?
If yes, how can I STORE and then GET to use a class in PHP5?
You don't store a class in a session variable, but you can store an object. Take note that if your object has properties referring to resources like file handles and database connections, no amount of unserializing will bring them back.
Unless it's a tiny class, probably not (see this question for possible pitfalls with large sessions). In short, sessions are not designed to be a caching mechanism, and they don't perform too well when you make them into one.
Note that if you are using the default session handler, your sessions are stored on the hard drive - not very fast when you get many concurrent requests. Also (test and measure), serialization/deserialization may be slower than the normal methods of object creation - note that you'd probably be deserializing twice: from session to string, then string into object of that class.
If you want to go the serialization/deserialization route, try e.g. Memcached instead.
Storing object instances in the session has the following disadvantages:
Performance overhead: Even if you don't need some objects, the will be unserialized and instatiated on every request.
Strange bugs in development: Whenever you add or remove a property from an object, the instance from the session will not match the object definition.
Security: Typically the session data is stored separately from your application. Sometimes this location is not as access-protected and secure as the rest of your files.
Data duplication and wrong state: With sessions you may store the same objects over and over again for different users. Compared to a dedicated object cache, where each object is only stored once, this leads to increased storage needs and the possibility that an object has the wrong state because the state was changed in another session.
I'd rather store the objects in a dedicated cache. Have a look at the Zend Cache class as an example of a good cache library.
If your object uses resources (database connections, files, gd images) your class should implement the Serializable interface. You then have to add two methods that do cleanup and initialization stuff.
In a project I'm working on, I have an object that is a sort of Collection with a database back end. The exact results this Collection returns are dependent upon its configuration, which is itself dependent on a number of user inputs. I would like to have an element on the page that contains the records in the Collection and can be updated dynamically through an AJAX request. The idea has occurred to me to serialize() this object, store it in memcache, and include the memcache key as a parameter in my AJAX calls. I would then retrieve the string from memcahce, unserialize() it, and retrieve the next set of records from the collection.
Is this a good way to achieve the kind of object persistence I want to make this work? I considered storing just the configuration, but I feel like this is a better "set it and forget it" solution in the face of future changes to the user controls. My main concern is that there might be some pitfall with serialize that I'm not aware of that would make this solution not robust, unreliable, or not very fast. Do I need to be concerned in any of those regards?
serialize/unserialize works well enough with scalars, but can be more problematic when working with objects. I've had a couple of issues that highlight potential pitfalls.
If any of your object properties are resources, these can't be serialized. You'd need to use the magic __sleep and __wakeup methods to cleanly close the resource attribute and restore it again on unserialize.
If your collection contains objects with cyclic references (e.g. a cellCollection object is an array of cell objects, each of which has an attribute pointing back to the parent cellCollection object) then these won't be cleanly restored on unserialize... each cell's parent object will actually be a clone of the original parent. Again, __sleep and __wakeup need to be used to restore the true relationships (not a trivial task).
If the serialized objects are larger than just queries you are extracting from the database, and have had a lot of processing applied to them, then what you are proposing is actually a very good optimization.
Two reference in particular:
http://code.google.com/p/memcached/wiki/FAQ#Cache_things_other_than_SQL_data!
http://www.mysqlperformanceblog.com/2010/05/19/beyond-great-cache-hit-ratio/
Both promote using memcached as being beyond a "row cache".
here's a definition of marshaling from Wikipedia:
In computer science, marshalling
(similar to serialization) is the
process of transforming the memory
representation of an object to a data
format suitable for storage or
transmission. It is typically used
when data must be moved between
different parts of a computer program
or from one program to another.
I have always done data serialization in php via its serialize function, usually on objects or arrays. But how is wikipedia's definition of marshaling/serialization takes place in this serizalize() function?
What serialize doesn't do is transport class definitions. When unserializing an object, that object's class definition must be present (loaded from the code base), otherwise unserializing will fail. From the Wikipedia article you mention:
To "marshal" an object means to record its state and codebase(s) in such a way that when the marshalled object is "unmarshalled", a copy of the original object is obtained, possibly by automatically loading the class definitions of the object. You can marshal any object that is serializable or remote. Marshalling is like serialization, except marshalling also records codebases. Marshalling is different from serialization in that marshalling treats remote objects specially.
If I understand correctly, Serialize is definitely not 100% compatible with the definition of marshaling in that respect. I don't know a pre-defined mechanism that would do this in PHP. I guess you would have to combine the serialized data and all necessary class definitions into a package (a ZIP file for example).
Like Pekka mentioned above, PHP doesn't include the class definition, so it does not do marshaling. If the class for a serialized object is present, however, then the answer to your question is yes: serialization is as easy as serialize($abc).
The best way that I know of to take care of marshaling in PHP is to use a third party tool like Google Buffer Protocols or Facebook (Apache?) Thrift, which will serialize and marshal for you. Kind of a roundabout way of doing it (and as long as you have the class present, you don't need to marshal anyway), but they're probably the best solution to the problem.