I serialized an object of PHP class in Laravel. Afterwards, I changed the class definition adding a new method and when I unserialize the old object and make a call to that newly implemented method, it works.
I wonder why and how?
Because serialization process keeps only state of the objects (fields) but not your methods with implementation.
Related
I have a custom operation that, once called, performs some more tasks than simply adding an entity.
The result of these operations is the creation of a new entity that is then persisted in the database.
Now, as a return value I'm currently using the IRI of the just created entity.
I generate the IRI using \ApiPlatform\Core\Api\IriConverterInterface.
This approach works but has a drawback: in the frontend I have to issue a new call to retrieve the data of the just created entity.
To avoid this call, I'd like to simply return the entity in the JSON format, but I don't find a way to immediately serialize it to return it.
In practice: I currently return simply the IRI of the entity: how can I return the fully serialized entity, according to its serialization configuration?
If your custom operation controller returns an instance (or a collection of instances) of an Api-Platform managed entity instead of a Response, the object will be automatically serialized with your desired serializer configuration (using the same serialization groups you've already defined, etc).
If you return instead an instance of Response, the SerializeListener will not serialize it and just return it unchanged. If not, it will serialize it. You can see it working here.
I am not sure, if you are just asking for the php-internal json-serialization:
https://www.php.net/manual/de/function.json-encode.php
Which can be included in any Model-class by just implementing the JsonSerializable Interface. Just return an alternative structure, which will be serialized.
https://www.php.net/manual/de/class.jsonserializable.php
You can use spl_object_hash() or spl_object_id(), see SplObjectStorage::getHash()
I'm writing a new PHP application against an existing database which has been designed rather poorly.
The older application has a custom Test class which has been instantiated and inserted in the database, then retrieved and unserialized, etc. Obviously poor design, but it's worked for them so far.
My new application needs to be able to deserialize these objects, so I copy-pasted the old class definition to the top of the file where I use unserialize, but I get this error:
The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "Test" of the object you are trying to operate on was loaded before unserialize() gets called or provide a __autoload() function to load the class definition
Since I've defined the class before I use it, I thought this would work. Is it a problem with namespaces? The old class definition had no namespace, but now it's in App\Foo\Bar. This is a Laravel project that uses autoloading.
I'm using the Symfony2 PHP framework with Doctrine ORM and mysql for storing data.
My goal is to populate Doctrine entities(PHP objects) by loading the data from a legacy database system which returns the data in key:value pairs.
I have many PHP objects('Company','Employee',etc.) that extend the same Abstract Class('AbstractDatabaseRecord').
My abstract class('AbstractDatabaseRecord') has a property('DatabaseTable') which tells me which table to use when loading data for each object('Company','Employee',etc.).
My abstract class implements an interface ('DatabaseLoadable') which requires a method called getColumns() which should return an array of the columns that make up the objects properties. The interface also requires a method called loadDatabaseData() which should process the array returned from the legacy system, and run the appropriate setters to populate the PHP object.
I have a Symfony2 service(PHP class) called LegacyDatabase that has a couple methods called findOne() and findAll().
findOne(AbstractDatabaseRecord $object, $id) accepts an object, uses the DatabaseTable property to determine which table to query, and then queries that table using the id. It then populates the object using its loadDatabaseData() method and returns the object to me so that I can use it.
I think this one is structured OK, but I am not sure how to implement the findAll() function.
findAll(AbstractDatabaseRecord) accepts an object, uses the DatabaseTable property to determine which table to query, and then selects ALL records from that table. I then loop through the results and ideally will populate a new object for each record found, place the objects in an array, and return the array of newly created objects for me to use.
However in the function I only have the one instance of the object. What would be the best way to create additional instances given that I do now know the Concrete Parent class that is passed in?
From my research it seems like I want to clone the object to get a shallow copy, and then populate that new copy and add it to my array of objects. Is this the best approach?
I am trying to persist a large class called an Authorizer which holds a reference to a database connection and a container of other objects representing the result of a complicated set of database queries. I want to serialize the expensive to build parts of this object in a session. Then when I need to ask the Authorizer a question I want to wake the Authorizer object up instead of building a new one for each page. I am writing a custom handler to temporarily store this object in a database table. I understand that the magic method __sleep() is usually used to handle choosing which parts of the object to store and then __wakeup() is used to restore the database connection.
This is where I get fuzzy. I think serialize() and unserialize() are supposed to work instead of the constructor and destructor, but I can't quite understand how they interact with __sleep() and __wakeup(). Then I got to the part of the manual describing the serializable interface and thought OK I will be able to implement this and be sure I have this right. Then I read that classes which implement this interface no longer support __sleep() and __wakeup()! That was the only part of this whole thing I really understood >:-{ I couldn't find any examples at all of how to properly implement this interface.
So my question is what is the preferred way to implement serialization in a completely object oriented system? Is the serializable interface meant to replace an older method? What is the purpose of having two different sets of functions (_sleep()/_wakeup() and serialize()/unserialize())?
__sleep and __wakeup are called by the default serialize/unserialize methods to prepare the object for serialization. This works in the case where the default PHP method does close to what you need and you simply need to perform some cleanup around the process.
If you're implementing the Serializable interface, then there's no need for these methods are you're declaring that you are implementing the entirety of the serialization process yourself. So any work which would normally be done in __sleep would be incorporated into serialize, and the same with __wakeup and unserialize.
I have in one project classes organized with ActivePattern (example : myObject->Load()) but now we need to implement some caching and caching is problematic.
To make it simples, the Load() method in every object call the DAL my giving the $this reference and the DAL fill up the object that all values. It works. But when we add some caching the object unserialized is a "new" object and the DAL cannot sent it back to the object because we have a reference to the object that need to be loaded. The only work around is to put the cache code inside the Load() of each object and to loop all properties from the caching object to Get the value and to Set it back to the real object.
Is there a better way to use caching with ActiveRecord Pattern?
If I understand correctly from your comment your problem is replacing this. What I would do is create a static "fetch" method on the active record class that would check cache, return if available, and if not return a new instance of the class. This will get you around having to replace this, and the only thing you have to change is the way you are loading the active record class.