2008-12-04 19:16(Un)packing and (un)zipping in PHP and RubyI like to think of myself as experienced in many computer languages, even if some of those experiences are unpleasant, and what better example of the variety of languages (and experiences) than PHP and Ruby. It seems that everyone skilled in one those languages has a strong preference for one or the other, so perhaps it would be helpful for me to contribute a comparison of how the two languages can be used to solve the same problem. My personal opinion is that while Ruby (and Rails sites) may fail spectacularly, PHP sites fail based on the quality of the programmer, and there are more PHP programmers out there (with a wider range of abilities) to pick bad examples of code from. Really, though, this blog post (and my whole blog) should not be about wading into the current argument of the day, and Ruby has its places and I’m happy to use it in those places, so I should make it clear that the comparison below is to aid interoperability. This was in fact what motivated me to write this code, actually, as there was a web service that needed implementing in both languages and the implementations were disagreeing on how the zipping stage should work. There are also a couple of gotchas just getting either language to zip or pack something, so hopefully the example code will be useful for someone trying to spot a bug in their own code. PHP<?php $text = "abc"; echo "$text\n"; $zipped = gzcompress($text); echo "$zipped\n"; echo chunk_split(bin2hex($zipped), 2, " ") . "\n"; $packed = pack("C*", 0x78, 0x9C, 0x4B, 0x4C, 0x4A, 0x06, 0x00, 0x02, 0x4D, 0x01, 0x27); echo chunk_split(bin2hex($packed), 2, " ") . "\n"; $unzipped = gzuncompress($zipped); echo "$unzipped\n"; $unzipped = gzuncompress($packed); echo "$unzipped\n"; ?> The above code outputs: abc x�KLJM’ 78 9c 4b 4c 4a 06 00 02 4d 01 27 78 9c 4b 4c 4a 06 00 02 4d 01 27 abc abc What is happening, if you want to follow line by line, is that PHP using the built-in Rubyrequire ‘zlib’ text = "abc" puts text zstream = Zlib::Deflate.new zipped = zstream.deflate(text) zipped << zstream.finish zstream.close puts zipped puts zipped.unpack("C*").collect {|c| sprintf("%02X", c&0xff)}.join(’ ‘) packed = [0x78, 0x9C, 0x4B, 0x4C, 0x4A, 0x06, 0x00, 0x02, 0x4D, 0x01, 0x27].pack(‘C*’) puts packed.unpack("C*").collect {|c| sprintf("%02X", c&0xff)}.join(’ ‘) zstream = Zlib::Inflate.new unzipped = zstream.inflate(zipped) zstream.close puts unzipped zstream = Zlib::Inflate.new unzipped = zstream.inflate(packed) zstream.close puts unzipped which produces an almost identical output: abc x�KLJM’ 78 9C 4B 4C 4A 06 00 02 4D 01 27 78 9C 4B 4C 4A 06 00 02 4D 01 27 abc abc The things to notice are the use of included libraries (Zlib in this case) and accessing its functions using the ConclusionIt looks so simple, but the fact that other people on the net have different answers suggests there’s more to getting it right than meets the eye. Fortunately the rest of implementing the web service was easy in both languages and completely compatible, so to avoid blaming either of the languages we could just unfairly blame Zlib. Another deciding factor, of course, is support from hosting providers for the languages, where of course PHP wins, but with that attitude Groovy on Grails would never win. If all software were written with loosely-coupled web service APIs, would we then have the freedom to code in whatever language we wanted? Trackbacks
Trackback specific URI for this entry
No Trackbacks
|
QuicksearchCategoriesSyndicate This BlogBlog Administration |