Mengatasi Permasalahan Library PHPXBase

Beberapa hari ini saya sedang disibukkan dengan pemakaian data dbf di dalam sebuah project. Sistem yang sedang saya bangun merupakan sistem monitoring berbasis web yang memanfaatkan data DBF dari sebuah aplikasi desktop. Untuk mempermudah pemantauan perkembangan dari perubahan data-data tersebut, dibuatlah sebuah sistem sebagai tempat kompilasi data dan menampilkan informasi yang diperlukan oleh subject matter secara online. Setelah googling, ada sebuah library PHP yang dapat menjembatani proses pembacaan dan penulisan file DBF, yaitu libary PHPXBase. Proses integrasi dan pemakaian secara umum dapat kawan-kawan lihat melalui artikel di sini.

Oke, untuk pembacaan file dan menampilkannya dalam browser tidak ada masalah. Sistem yg sedang saya buat membutuhkan sedikit modifikasi program untuk proses importing data dbf ke dalam database server (MySQL). Artinya, perlu di-generate syntax SQL supaya dapat dieksekusi oleh MySQL. Lebih jelasnya, saya harus membuat query insert untuk masing-masing row data dari DBF file. Nah, di sini mulailah muncul beberapa permasalahan yang lumayan membutuhkan waktu untuk memahami dan memperbaikinya.

1. Atribut _NullFlags

Permasalahan:

Secara default, ketika membaca seluruh kolom dari sebuah tabel file DBF, selalu ditambahkan atribut _NullFlags secara otomatis. Atribut ini sedikit mengganggu jika kita tidak memerlukannya.

Solusi:

Permasalahan ini tidak terlalu sulit karena kita hanya perlu menambahkan kode array_pop() untuk menghapus nama kolom dan value untuk atribut terakhir. Berikut contoh query insert yang saya buat. Terlihat di setiap kolom dan value kolom terakhir, saya tambahkan array_pop()

public function kompilasiItem($kdsatker)
{
	set_time_limit (0);

	$table = new XBaseTable(Yii::app()->basePath.'/../dbf/item/'.$kdsatker.'.dbf');

	$table->open();
    $kol= array();
    foreach ($table->getColumns() as $i=>$c) {
	    $kol[] = strtolower($c->getName());
    }
    array_pop($kol); //di sini
    $kol[] = 'flag';
    $awal = "INSERT INTO em_ditem (".implode(",", $kol).") VALUES ";
	$flag = time();

	$pdo = Yii::app()->db->pdoInstance;

	try{
		$l = 0;
		$sql = array();
		while ($record=$table->nextRecord()) {
			$l++;

			$rec = array();
			foreach ($table->getColumns() as $i=>$c) {
				$cell = addslashes($record->getString($c));
				if($cell=='') $rec[] = 'NULL';
				else $rec[] = "'".$cell."'";
			}

			array_pop($rec); //dan di sini
			$rec[] = $flag;
			$sql[] = ( "(" . implode( "," , $rec ) . ")" );

			if($l == 5000):
				$q = $awal . implode(",", $sql);
				$pdo->exec($q);
				unset($sql);
				$l = 0;
			endif;
		}

		if($l>0):
			$pdo->exec( $awal . implode(",", $sql) );
		endif;
	}
	catch(PDOException $e) {
		echo $e->getMessage();
        exit;
	}

	$table->close();

	$this->removeDuplicate('em_ditem', $flag);
}

2. Atribut dengan tipe datetime

Permasalahan:

Okelah, untuk tampilan di browser nilai dari atribut bertipe datetime secara otomatis akan tertulis dalam format yang user friendly seperti ‘Wed, 13 June 2012 +07:00 GMT’. Nah, permasalahannya query SQL tidak mengenali nilai tipe data datetime dengan format seperti itu. Format datetime dalam MySQL adalah ‘2012-06-13 12:00:00’.

Solusi:

Setelah buka code library PHPXbase, saya temukan fungsi getDateTime mengembalikan nilai dari fungsi date(“r”, $value). Fungsi tersebut yang ternyata membentuk format data lebih user friendly. Untuk membuatnya bisa terbaca oleh mysql, baris kode tersebut perlu diubah menjadi date(“Y-m-d H:i:s”). Sebenarnya cara ini kurang baik, karena mengubah library secara langsung. Akan lebih baik jika kita menambahkan parameter untuk memilih format apa yang hendak ditampilkan. Tapi karena sedang malas, cara frontal saya gunakan, hehe..

3. Tipe data currency

Permasalahan:

Library PHPXBase tidak mengenal tipe data currency. Saya juga kurang tahu, mungkin ini tipe data yang diberikan pada DBF versi terbaru. Kebetulan di dalam file DBF yang akan saya gunakan terdapat tipe data currency. Walhasil, ketika membaca nilai dari atribut ini terjadi error karena library tidak mengenalinya (T_T). Untungnya, error memberi tahu bahwa tipe data yang tidak dikenali adalah tipe data “Y”. Di dalam DBF file, masing-masing tipe data diwakili oleh beberapa huruf abjad. Setelah googling baru saya ketahui tipe data Y ada currency.

Solusi:

Tipe data currency sebenarnya mirip dengan tipe data float di dalam mysql. Makanya dalam mengatasi permasalahan ini, saya memanfaatkan pemrosesan data dengan tipe float di library PHPXBase. Yang perlu ditambah adalah baris kode berikut:
Tambahkan definisi variabel tipe data Y di dalam class XBaseRecord.php.

define ("DBFFIELD_TYPE_CURRENCY","Y");	// Currency

Masih di dalam file yang sama, tambahkan sebuah case di dalam fungsi getObject

case DBFFIELD_TYPE_CURRENCY : return $this->getCurrency($columnObj);

Buat fungsi baru seperti di bawah ini (saya hanya copas dari fungsi getFloat)

function getCurrency($columnObj) {
	if ($columnObj->getType()!=DBFFIELD_TYPE_CURRENCY) trigger_error ($columnObj->getName()." is not a Float/Currency column", E_USER_ERROR);
        $s = $this->forceGetString($columnObj);
        if (!$s) return false;
        $s = str_replace(",",".",$s);
        return floatval($s);
 }

4. intval

Permasalahan:

Jika atribut di dalam file DBF menggunakan tipe data numeric, library PHPXBase hanya bisa membaca value yang kurang dari sama dengan 2147483647. Awalnya saya bingung karena nilai di dalam file DBF adalah 40.000.000.000, tapi waktu diinsert kok hanya 2147483647. Saya coba-coba dulu dengan mengganti nilai menjadi 30.000.000.000, tapi kok masih sama. Setelah saya ganti nilainya menjadi 1.000.000, akhirnya mau menuliskan dengan benar. Dari sini saya mulai curiga dengan penggunaan tipe data integer.

Solusi:

Setelah saya cek fungsi getInt, ternyata benar. Fungsi mengembalikan nilai dari fungsi intval() yang maksimum 2147483647. Setelah diganti dengan strval($s) baru deh ga ada masalah lagi.

Hoahmm.. capek nih tadi nulis di notepad habis nonton Euro. Baru diupload pagi ini. Semoga bermanfaat dan happy coding :)

farid

Selamat datang dan salam kenal. Penulis merupakan lulusan Sekolah Tinggi Ilmu Statistik Jakarta jurusan Komputasi Statistik. Menekuni pemrograman web khususnya PHP dengan Yii Framework. Penggemar musik instrumen dan film Doraemon. Berasal dari Kota Lumpia Semarang dan pernah bertugas menjadi Staf Produksi dan IPDS di BPS Kabupaten Melawi. Sejak tahun 2016, mulai bertugas sebagai Staf Pengolahan Data di BPS Provinsi Kalimantan Barat

You may also like...

  • Yakin

    bagus banget tutorial nya, sy mo tanya sedikit, kalo mo tulis file dbf, tetapi file nya dalam kondisi terbuka, gimana ya

    • farid

      maaf,kalau menulis file dbf saya belum pernah coba πŸ˜€

  • kampungkali

    Buat miftachul jannah yg tadi nanya via email, ga masalah kalau ga pakai Yii. Sebelumnya, untuk tipe selain currency sudah tampil dan benar kan? Coba di-trace satu persatu. Misal di fungsi getCurrency langsung direturn floatval($s) – nya.. Begitu terus sampai ketahuan mulai error di mana. Asumsi sy, cara-cara di atas sudah benar diimplementasikan.

  • miftachul

    kalau yang lainnya sudah tampil dengan benar pa, di returnnya juga sudah sesuai yg ada di tutorial ini pa,, apa perlu menambahkan setCurrency jga pa?

    • http://www.facebook.com/faridfadhlan Muhammad Farid Fadhlan

      setCurrency dipakai untuk membuat file dbf-nya. Kalau untuk membaca cukup di fungsi getCurrency saja. Kalau di-return $s-nya saja, apa yg keluar?

      • miftachul

        kalau di-return nya hanya $s nya yang keluar “null” atau simbol-simbol seperti €zΓΎΒΆ

  • Sumi

    gan, mau tanya nih, gmna cara mengatasi panjang filed yang ke potong..
    contohnya gini di script gw tulis $ra->setObjectByName(“tgl_selesai_kkk”,$r[“tgl_selesai_kkk”]);
    tp pas diliat di dbf Viewer kolom nya cuma tgl_selesai (11 digit yang ke ambil)