Reputation: 1753
Imagine you have a list of some objects. These objects are instances of various classes which are extending a base class. Now I'd like to save these objects in a database.
As an additional requirement, the number of classes which extends the base class can be quite big.
Is it good practice to save the class name as string in the database and fetch it like that:
<?php
class Page {
abstract public function foo($args);
}
class ChartPage : Page{
public function foo($args){
var_dump($args);
}
}
// other classes like ChartPage would be defined here
// fetched row from a MySQL database
$row = array("id" => 21, "title" => "Test", "class" => "ChartPage", "args" => "{}");
$object = new $row['class'];
$object->foo($row['args']);
?>
Are there any practices to do anything like that in a better way?
Upvotes: 0
Views: 116
Reputation: 63797
Unless you have a specific reason for writing your own functions for serialization/deserialization use those available natively in PHP:
You can read more about PHP's Object Serialization under the following link:
If the serialized data is to be shared with things outside of PHP you might choose another method of serialization, like JSON or XML. But if it's just a matter of storing objects for access later through PHP the standard serialization methods are more than sufficient.
Some sort of identifier must be stored with the serialized data, otherwise it will be impossible for you to determine what type an object really is.
Sure, I've seen deserialization methods where the keys of the serialized data has been used to search for the best matching object types, but this is not something I'd recommend since it isn't 100% accurate for all cases.
In your example snippet I assume that Page::foo
is to be used as a factory building your new class.
If you are going to write your own methods of serializing/deserializing the data and want to store all the data an object has you don't need to force the classes who inherit Page
to implement a factory.
Page
could just as well have a unified method of serializing arbitrary classes by looping through the key/value-pairs that the object contains. There is a slight problem with this approach though.
If a inherited object has a rather complex member (ie. not basic, for example a user-defined class) you might not want to store exactly that.
For example, if an object has an active mysql connection you'll only want to store the credentials to reopen such a connection, because how are you going to store the connection itself in your serialized data?
Then again, storing the file descriptor associated with the socket connection and keeping it open using a imaginary MySQLKeepConnAlive
object that's always running in the background would be cool, but it's often far som necessary.
Anyhow; If I was you I'd write a default method for serialization/deserialization available in the base object, if the inherited type is complex it's up to the developer to override these methods and provide his own methods.
I would store the object using a data structure as the below, which isn't that far from what you described earlier. '__PAYLOAD' will contain the members of the object, the other values should be defined in your base class.
'__PAYLOAD' will not look the same for two instances of different classes, but there will be an unified way of loading a object with a certain id and type, and finding out basic information regarding the object.
Of course you can add more "base" fields than the below, it's just an example of what I'm thinking.
$serialized_data = array (
'__TITLE': 'Test',
'__TYPE': 'CharPage',
'__ID': 21,
'__PAYLOAD': array (
'member_1' => 'foobar',
'member_2' => 'barbaz',
'member_3' => 'bazbir'
)
);
Upvotes: 1
Reputation: 1471
Try to look at object serialization. I think this might help you
http://php.net/manual/en/language.oop5.serialization.php
Upvotes: 0