I have a PHP class that stores database query results, but also contains a PDO object so that the results can be updated/re-inserted/etc on the fly. A makeshift ORM, if you will.
Problem is, I need to serialize this class but instances of PDO cannot be serialized. I'm ok with that; by the time the object gets serialized, I have no need for the PDO instance.
Is there a way to mark a variable for exclusion from serialization within a class, like there are with some other languages? I understand I could manually unset() the PDO variable before I want to serialize the class, but with the current structure of the code, that would be a bit of a nightmare.
My saving grace here would be a __serialize() method that could be overridden, but it doesn't appear anything like that exists.
There's __sleep() and __wakeup().
Alternatively, you could implement Serializable.
Starting with PHP 7.4, there is also __serialize and __unserialize (see the Documentation) as a more usable alternative.
The Serializable interface might also be deprecated, and generally the magic methods are preferred (see also this).
Related
I've done mostly procedural programming for years and am trying to wrap my head around OOP and PDO. I've started converting an application I've written to using classes instead of standalone functions (it's a nightmare, but I think it will be worth it..) and would like to use PDO instead of the regular mysql_* functions. I'm kind of flying by the seat of my pants, just learning as I go along, and I'm not sure how I should handle the PDO object(s).
I know it would be stupid to create a new PDO object every time I need to make a query, so that leaves two ways that I can see:
Creating a PDO object in each class (i.e. every time an object is created, call a member function to create a PDO for it to use).
Create PDO object at the beginning of my application and pass it to the constructor of every object that is created, and all the objects share the PDO object.
What is the best way to do this?
Thanks for your advice!
Don't make more than one. You'll go crazy trying to manage all the DB connections.
One good solution would to make a singleton object for data access and retrieve it via it's static accessor method whenever you want to use the DB. That way you only ever have one place that manages DB access and PDOs. If you want to be a bit more MVC about it, you can put all SQL code in there too.
Depending on the size of the application, you probably want to use a Singleton to handle your database connection. Essentially, this will be a class that wraps your database connection and has a static function that will return your PDO object. However, because it's a Singleton it will only ever create one (assuming you don't make it more sophisticated). This saves you both from having to continuously make objects and from having to pass one object into all your objects, properly decoupling persistence from business logic.
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.
Can someone please explain how overloading in PHP works? The manual doesn't do a very good job of it. I'm still thinking of overlaoding in the Java sense, but I know overloading in PHP is a completely different animal. All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this. Thanks in advance. Rylie
All the PHP manual says is that overloading provides a mechanism for adding new properties and methods to a class at runtime, but it doesn't explain how PHP achieves this.
The very manual page you linked to explains how the thing that PHP calls "overloading" works. You're pretty correct in that it has little to do with what the entire rest of the world calls overloading. In fact, the manual page says right at the top:
PHP's interpretation of "overloading" is different than most object oriented languages. Overloading traditionally provides the ability to have multiple methods with the same name but different quantities and types of arguments.
PHP has reserved a handful of special method names that you can optionally define in a class. They fall into two categories:
__get, __set, __isset and __unset are called when an instance variable (object property) is fetched, set, checked for existence, or unset respectively. All receive the name of the property as the first argument, and __set receives the new value as the second argument. These methods are only called when either the property does not exist or can not be accessed from the caller's scope (i.e. protected/private). It's worth noting that without these methods, PHP will silently create new instance variables on demand, when asked to.
__call and __callStatic are called when a method is called that, again, doesn't exist or can't be accessed from the caller's scope. The former is called for instance methods, the latter for class methods. The first argument is the name of the method called, and the second is an array of the arguments, by value (references are dereferenced).
These functions allow you to simulate adding methods to a class/instance after creation, though their use is clunky and awkward. Further, using them breaks autocomplete in IDEs.
Using anonymous functions might seem like a natural complement to this functionality, but it is currently not possible to bind an the instance ($this) to one at run time. This functionality was removed during the 5.3 beta because it couldn't be made clear and obvious. This has been corrected in PHP's current trunk, but it's unknown when the trunk will be stabilized for release.
Is there an Actionscript equivalent to PHP's __get() and __set() magic methods? I want to be able to override the behavior of getting/setting member variables.
There is no such thing, unfortunately.
All you can do is check for the existence of a specific property, by using either
myObject.hasOwnProperty (name)
on simple Objects or some variant of describeType() for Class instances, for example
describeType(myObject).accessor
to get an XMLList of all accessor methods or
describeType(myObject).variable
to get an XMLList of all variables.
describeType(), however, is quite expensive in terms of performance, so it pays to have some sort of type hash map to store the lists for each type and do lookups for types that have already been described once.
You could also use try/catch blocks around the parts where undefined properties might be accessed, but this also "eats" away a lot of performance, if many errors are thrown.
Found it.
Extending the Proxy class allows you to solve this problem.
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".