แก้ปัญหา PHP-ExcelReader ใน 64Bit system

ตัว PHP-ExcelReader เป็น PHP Class ที่นำมาใช้อ่านไฟล์ Excel 97-2003 ได้ดีมากตัวนึง และแม้จะไม่ได้ update มาตั้งแต่ปี 2007 ก็ยังทำงานได้ดีบน PHP 5.2.8 ซึ่งบนระบบ Development Environment นั้นไม่มีปัญหา ซึ่งบนเครื่องผมเป็น Core 2 Duo ที่ทำงานบน Windows XP Pro 32bit ซึ่งทำงานได้ปรกติดี แต่แล้วพอเอาขึ้น Production Environment มันก็เกิดปัญหาขึ้นที่ function GetInt4d ซึ่งผมควานหาปัญหาและไล่ว่ามันเกิดจากตัว code เองหรือเปล่า หรือว่ามีปัญหากับ function พื้นฐานต่าง ๆ จาก Extension ของ PHP เองหรือเปล่า ซึ่งผมก็ว่าไม่ใช่ และพอเอาไปทำงานบน Production ตัวนึงที่เป็น 32bit CPU กลับไม่มีปัญหา ซึ่งลง Extension เหมือน ๆ กันด้วย –_-‘

แต่สุดท้ายผมก็ไล่ไปเจอสิ่งที่ผมคิดว่ามันเป็นเรื่องที่ทำให้ผม งง แต่มันก็เกิดขึ้นก็คือ [ 1487371 ] AMD64 dead loop fix สรุปง่าย ๆ ว่าเป็นปัญหาของ bitshift ใน OS 64bit ที่ bit ตัวแรกจะได้ค่าไม่ตรงกับใน OS 32bit ทำให้เกิดความผิดพลาด

ตัว error ที่พบคือ

Notice: Uninitialized string offset: -138 in /home/www/public_html/excel/oleread.inc on line 27
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 71 bytes) in /home/www/public_html/excel/oleread.inc on line 133

ซึ่งแก้ไขได้ง่าย ๆ ด้วยการเปลี่ยนแปลง function GetInt4d ใหม่ตามด้านล่าง ก็สามารถทำงานบน OS 64bit ได้แล้ว

แก้ไขในไฟล์ oleread.inc

function GetInt4d($data, $pos) {
    // Hacked by Andreas Rehm 2006 to ensure correct result of the 24 block on 32 and 64bit systems
    $_or_24 = ord($data[$pos+3]);
    if ($_or_24>=128) $_ord_24 = -abs((256-$_or_24) << 24);
    else $_ord_24 = ($_or_24&127) << 24;

    return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24;
}