Archive for August, 2007

PHP and Circular references

PHP, like most modern languages, has a garbage collection mechanism. It is supposed to destroy objects and variables as soon as there are no references to it anymore. To learn more about how it actually works, read this article. To summarize, PHP’s garbage handling is dumb, so any object that contains a circular reference will never be cleaned up.

Normally, this doesn’t matter because a typical PHP request only takes a short amount of time and creates only a few objects. But, lately I have been helping MikeT with a project he is working on. In this project, a request sometimes takes over 10s and creates close to 30,000 objects. The majority of these objects have circular references ….

Needless to say, memory usage was being destroyed by PHP. A single request would use around 90MB of memory. Even though PHP would clean up some of the memory after the request finished, there was still a large portion that wouldn’t be. This is completely unacceptable because a production server will run out of physical memory in a few minutes or less, start swapping, and eventually crash before FastCGI ever restarts the PHP process.

The solution was pretty simple but annoying. Basically, you have to write a custom destroy function that will unset all circular references. The __destruct() function can’t be used because it is only called when there are no more references to an object. After implementing a custom destroy function, memory usage per request dropped to about 16MB, which is a much more acceptable number. So, even though garbage handling is nice, anytime you have circular references, creating a custom destroy function to do your own memory management is probably a good idea.

The Death of MythTV

A few months ago, it occurred to me that I am no longer a college student, I am an adult. That being said, I realized I should start acting like one. While transforming into an adult, I began to understand there is really only one major change, high-definition TVs. I researched TVs for weeks, until I finally chose a Samsung 1080p 40″ LCD which I will blog about in the coming weeks. Then, as most of you probably gathered from a previous post, I got a satellite with HD programming. Needless to say, it has been an exciting time, but in a weird way a sad time.

As some of you might know, HD channels are compressed, mostly into the MPEG2 format, although a push towards MPEG4 is occurring. Anyways, satellite and cable providers go a step further and encrypt the compressed MPEG2’s. This is where the problem lies. While MythTV has the capability of ripping over-the-air (OTA) HD channels from an antenna, it can’t rip from a satellite or cable signal. The cable and satellite providers obviously want users to use their hardware, and not 3rd party hardware. While this sucks, it is understandable on many levels. I think that there should be some way to get the compressed MPEG2’s from the receiver, but currently there isn’t.

Some of you out there might be thinking, “Why can’t you just rip the digital signal on the DVI/HDMI cable?”. That’s what I thought at first, but that is too much data. Since that data is uncompressed, it is just too much for a computer to handle quickly, like MythTV needs to be able to do. Wikipedia gives the follow explanation:

A HDTV camera generates a raw video stream of more than one billion bits per second. This stream must be compressed if digital TV is to fit in the bandwidth of available TV channels and if movies are to fit on DVDs.

Without further ado, I announce that I have deleted all my MythTV recordings and reformatted the box. I love MythTV and will always enjoy the year I spent with it, but it can’t compete in the HD age. I really hope that one day, with technology advances, or new laws, MythTV + HD will be possible. Unfortunately, I can’t wait until then and will gladly use Dish Network’s HD-DVR, even though I will always know MythTV is a better product. I still plan on completing my MythTV guide on my blog, but its priority has taken a dive.

PHP Classes and NULL characters

Today I ran into an interesting problem with PHP. It boils down to PHP’s handling of protected and private members of classes. Basically, when serializing or typecasting, NULL characters precede the variable names. For instance:

1
2
3
4
5
6
7
8
9
10
11
12
class TestClass {
 
    private     $var1;
    protected   $var2;
    public      $var3;
}
 
$instance = new TestClass();
 
//print_r() to a string and escape special characters
$str1 = addslashes(print_r((array) $instance, true));
echo $str1;

Outputs:

Array
(
    [\\0TestClass\\0var1] =>
    [\\0*\\0var2] =>
    [var3] =>
)

As you can see, this is probably not what you expected. Protected variable names are preceded by a NULL character, *, and another NULL character. Private variables are preceded by a NULL character, the class name, and another NULL character. This is probably one of the most idiotic things I have ever seen PHP do.

  • Violates access restrictions to class members, although serialization has that inherent flaw as well
  • Why in the world would anyone want NULL characters in the array keys?
  • Inserting serialized strings into a DB is a pain

After pondering possible reasons for this, I have come up with nothing that makes that much sense. It makes typecasting to an array pretty worthless since all members must be public.