Pernah membuat aplikasi dan diharuskan membuat resi / bon / bukti pembayaran / kwitansi yang diharuskan adanya kalimat terbilang nominal-nya?

Bila mencari fungsi bawaan dari PHP tentu saja tidak akan menemukannya, tapi ada banyak implementasi terbilang yang dapat digunakan, seperti halnya Class LibTerbilang yang Saya buat dan saya pakai untuk bermacam-macam kebutuhan aplikasi yang dibangun dengan bahasa PHP.

Class atau Library ini mendukung sampai hitungan triliun yang sebenarnya jarang sampai digunakan untuk aplikasi seperti POS atau laporan-laporan bukti pembayaran lainnya. Jadi Saya bisa bilang Library ini lebih dari cukup untuk keperluan apapun.

Terdiri dari satu class yang sederhana, dan disusun dengan mindset untuk performa dan ketepatan hasil. Berikut adalah source code dari Class LibTerbilang, yang dapat di copy dan digunakan seperlunya:

<?php
/*
 * Copyright 2022 Ahmad Amarullah (https://amarullz.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

class LibTerbilang
{
    private static function charAt($s, $i)
    {
        return substr($s, $i, 1);
    }
    private static function getValidityNaN($str, $from, $to, $min = 1, $max = 9)
    {
        $val = false;
        $from = ($from < 0) ? 0 : $from;
        for ($i = $from; $i < $to; $i++) {
            if (((int) LibTerbilang::charAt($str, $i) >= $min) && ((int) LibTerbilang::charAt($str, $i) <= $max)) $val = true;
        }
        return $val;
    }
    private static function getTerbilang($i, $str, $len)
    {
        $numA = array("", "satu", "dua", "tiga", "empat", "lima", "enam", "tujuh", "delapan", "sembilan");
        $numB = array("", "se", "dua ", "tiga ", "empat ", "lima ", "enam ", "tujuh ", "delapan ", "sembilan ");
        $numC = array("", "satu ", "dua ", "tiga ", "empat ", "lima ", "enam ", "tujuh ", "delapan ", "sembilan ");
        $numD = array(0 => "puluh", 1 => "belas", 2 => "ratus", 4 => "ribu", 7 => "juta", 10 => "milyar", 13 => "triliun");
        $buf = "";
        $pos = $len - $i;
        switch ($pos) {
            case 1:
                if (!LibTerbilang::getValidityNaN($str, $i - 1, $i, 1, 1))
                    $buf = $numA[(int) LibTerbilang::charAt($str, $i)];
                break;
            case 2:
            case 5:
            case 8:
            case 11:
            case 14:
                if ((int) LibTerbilang::charAt($str, $i) == 1) {
                    if ((int) LibTerbilang::charAt($str, $i + 1) == 0)
                        $buf = ($numB[(int) LibTerbilang::charAt($str, $i)]) . ($numD[0]);
                    else
                        $buf = ($numB[(int) LibTerbilang::charAt($str, $i + 1)]) . ($numD[1]);
                } else if ((int) LibTerbilang::charAt($str, $i) > 1) {
                    $buf = ($numB[(int) LibTerbilang::charAt($str, $i)]) . ($numD[0]);
                }
                break;
            case 3:
            case 6:
            case 9:
            case 12:
            case 15:
                if ((int) LibTerbilang::charAt($str, $i) > 0) {
                    $buf = ($numB[(int) LibTerbilang::charAt($str, $i)]) . ($numD[2]);
                }
                break;
            case 4:
            case 7:
            case 10:
            case 13:
                if (LibTerbilang::getValidityNaN($str, $i - 2, $i)) {
                    if (!LibTerbilang::getValidityNaN($str, $i - 1, $i, 1, 1))
                        $buf = $numC[(int) LibTerbilang::charAt($str, $i)] . ($numD[$pos]);
                    else
                        $buf = $numD[$pos];
                } else if ((int) LibTerbilang::charAt($str, $i) > 0) {
                    if ($pos == 4)
                        $buf = ($numB[(int) LibTerbilang::charAt($str, $i)]) . ($numD[$pos]);
                    else
                        $buf = ($numC[(int) LibTerbilang::charAt($str, $i)]) . ($numD[$pos]);
                }
                break;
        }
        return $buf;
    }

    /**
     * Dapatkan nilai terbilang dari suatu bilangan
     * Contoh:
     * $val = LibTerbilang::terbilang("2000");
     *   menghasilkan: dua ribu
     *
     * @param string $nominal Bilangan yang akan dibaca
     * @return string String Terbilang
     */
    public static function terbilang($nominal)
    {
        $buf = "";
        $str = $nominal . "";
        $len = strlen($str);

        for ($i = 0; $i < $len; $i++) {
            $buf = trim($buf) . " " . (LibTerbilang::getTerbilang($i, $str, $len));
        }
        return trim($buf);
    }
}

Untuk menggunakannya, dapat dengan cara yang sederhana:

<?php
include "libterbilang.php"; /* include Class LibTerbilang */

$a = 5478200;
echo "Terbilang untuk {$a} = " . (LibTerbilang::terbilang($a));

Output pada kode di atas adalah:

Terbilang untuk 5478200 = lima juta empat ratus tujuh puluh delapan ribu dua ratus

Hanya dengan mengakses fungsi statik LibTerbilang::terbilang dengan argumen nilai yang akan dijadikan kalimat terbilang, maka fungsi tersebut akan memberikan return string berupa kalimat terbilang yang dapat digunakan selanjutnya.

Contoh lain penggunaan library adalah seperti berikut:

<?php
include "libterbilang.php"; /* include Class LibTerbilang */

/* nilai */
$a = "83956712400";

/* Gunakan ucwords untuk kapital tiap kata */
$kalimat = ucwords(LibTerbilang::terbilang($a));

echo "Anda membayar sebesar: {$kalimat} Rupiah";

Output pada kode di atas adalah:

Anda membayar sebesar: Delapan Puluh Tiga Milyar Sembilan Ratus Lima Puluh Enam Juta Tujuh Ratus Dua Belas Ribu Empat Ratus Rupiah

Dengan menambahkan ucwords, maka semua huruf di awal kata akan dijadikan kapital.

Source code dapat didownload di Github Gists:

https://gist.github.com/amarullz/393efc78ba779526dfaebd821afd4007

Penutup

Class ini Saya code sudah sangat lama, dimana penggunaan bracket untuk mengambil satu karakter $string{$n} pada string masih belum deprecated di php. Class ini dirapihkan ulang untuk keperluan kontent ini dan keperluan open-source.

Mudah-mudahan bermanfaat, Terima Kasih.