Check For Loaded PHP Extensions

Sometimes you want to make sure a certain PHP extension is loaded or not. These extensions can be curl, xmlrpc, or ldap. After all, when you move your application from one server to another the configuration is not necessarily the same. So here’s how to check for loaded extensions using get_loaded_extensions().

1
2
3
4
5
6
7
8
9
10
$extNeeded = array('ldap', 'mysql', 'xmlrpc', 'ron_ext');
$loadedExtension = get_loaded_extensions();
foreach ($extNeeded as $ext) {
    if (!in_array($ext, $loadedExtension)) {
        echo 'The application cannot start properly, '.$ext.' extension is missing.
        The following extensions are needed: '
.implode(', ', $extNeeded).'.
        Terminating application ...'
;
        die;
    }
}

A few useful additions.

For checking just one extension, extension_loaded() is more direct than scanning the array returned by get_loaded_extensions():

1
2
3
if (!extension_loaded('curl')) {
    die('curl extension is required.');
}

It’s a one-liner, doesn’t allocate the full extension list, and reads a little nicer at call sites. Use get_loaded_extensions() when you genuinely need to iterate over many at once (like the original example does), and extension_loaded() for single checks.

You can also collect all the missing ones into a single message instead of bailing on the first one — better feedback for the operator:

1
2
3
4
5
6
$required = ['curl', 'ldap', 'mbstring', 'pdo_mysql'];
$missing  = array_filter($required, fn($ext) => !extension_loaded($ext));

if (!empty($missing)) {
    die('Missing required PHP extensions: ' . implode(', ', $missing));
}

If you’d rather not write any PHP at all, the command line gives you the same answer:

1
2
3
php -m | grep -i curl
php -m              # full list of compiled-in + loaded modules
php --ri curl       # detailed runtime info for one extension (version, settings)

php -m shows what your CLI php binary has loaded; if you’re chasing a problem that only shows up under the web server, you’ll want to run phpinfo() from a web request instead — the CLI and FPM SAPIs load different php.ini files and can have different extensions.

One note on the original example: two of the four extensions listed (mysql and xmlrpc) are no longer part of modern PHP. The mysql extension was removed in PHP 7.0 — use mysqli or pdo_mysql instead. xmlrpc was unbundled in PHP 8.0 and is effectively unmaintained; if you still need XML-RPC, the php-xmlrpc PECL package is technically available, but most projects move to JSON-RPC or REST these days. The check pattern in the post is still correct — it’s just that the specific extension names you’d put in $extNeeded have evolved.

Posted in PHP, Web Development | Comments Off on Check For Loaded PHP Extensions

Extending an Existing Javascript Function

This is how you extend an existing javascript function. Assuming that you want to preserve the existing function and the “added algorithm” is somewhat only needed to be executed based on a certain environment only.

1
2
3
4
5
6
7
8
9
10
11
12
function abc(){
  alert('abc is called');
}
var abcOrig = abc;
abc = function(){
  abcOrig();
  alert('abc has been extended!');
}
alert('test 1');
abc();
alert('test 2');
abc();

2026 update — the technique has a name, and a couple of gotchas. 🐛

What this pattern is called is monkey-patching — you save a reference to the original function, then replace it with a wrapper that calls the original plus your extra logic. It’s still useful, especially when you need to extend a third-party function you can’t edit.

Gotcha 1: it won’t work in module / strict scopes if you use const. The 2011 example uses var and an unscoped function abc(), so reassigning the global abc is fine. In a modern ES module — or anywhere you’ve declared the function with const or let — you can’t reassign it. Patch a property on an object instead:

1
2
3
4
5
6
7
8
9
10
11
12
13
const api = {
  fetchUser(id) {
    console.log('fetching', id);
  }
};

const original = api.fetchUser;
api.fetchUser = function (...args) {
  console.log('before');
  const result = original.apply(this, args);
  console.log('after');
  return result;
};

Gotcha 2: the original example silently drops arguments, this, and the return value. The line abcOrig(); calls the original with no arguments, no this binding, and throws away whatever it returns. That’s fine for an alert, but breaks the moment you patch a real function. The robust version forwards everything:

1
2
const result = original.apply(this, args);
return result;

Or as a one-liner using rest/spread: return original.call(this, …args);

Gotcha 3: you only get one shot per scope. If two pieces of code both monkey-patch the same function, the second one wraps the first — the order matters, and untangling it later is painful. For anything beyond a quick local override, prefer composition (a wrapper function with a different name) or class inheritance with super.

Use monkey-patching sparingly — it’s a sharp tool. But when you need to slip in an extra console.log on a function you don’t own, this is still the move. 💡

Posted in javascript, Web Development | Comments Off on Extending an Existing Javascript Function

Map Network Drive using DOS command

Create a batch file named mapdrive.bat and put the following inside it:

1
2
3
4
REM Map network drives
net use j: \\server1\john_music
net use p: \\server2\pdfs
pause

Explanation:

  • Line 1 is a comment.
  • Line 2 (and similarly line 3) maps the network share \\server1\john_music to drive J:.
  • Line 4 pauses the DOS window so it doesn’t close automatically.

A few useful additions.

If you want the mapping to survive a reboot, add the /persistent:yes flag. Without it, the mapping is gone the next time you log in:

1
net use j: \\server1\john_music /persistent:yes

If the share requires credentials, pass them with /user: — the password is prompted for if you omit it (which is the safer habit; embedding it in a batch file leaves it readable to anyone with access):

1
net use j: \\server1\john_music /user:DOMAIN\jdoe

To remove a mapping later:

1
2
net use j: /delete
net use *  /delete /yes        REM remove all mappings without prompting

And to see what’s currently mapped:

1
net use

The PowerShell equivalent. If you’re on a modern Windows and want a more scriptable approach, New-PSDrive covers the same ground:

1
2
New-PSDrive -Name J -PSProvider FileSystem `
  -Root \\server1\john_music -Persist

The -Persist flag is the equivalent of net use … /persistent:yes. Note that New-PSDrive without -Persist creates a mapping that’s only visible to the current PowerShell session, which is sometimes exactly what you want for a script that shouldn’t leave drive letters lying around afterward.

Posted in DOS | Comments Off on Map Network Drive using DOS command

Super Powerful Debugging Function in Javascript

Super powerful debugging function in JavaScript. This function will output your variable in question to the Firebug console or the HTML page. With it you can debug anything from an Object, array, string, integer, etc. It is also recursive-safe.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/**
 * @author: Ronald Pringadi, 2011
 * @desc: to debug a JavaScript Object
 * @usage: debug(yourObject);  
 * or debug(yourString);
 * or debug(yourArray);  
 * @param object vTraceObject
 * @param string vPadding
 * @param object vPadding
 *
 */


function debug(vTraceObject, vPadding, vPreviousTraceObject) {
    'use strict';

    function getObjectClass(vObj) {

        if (vObj && vObj.constructor && vObj.constructor.toString) {
            var arr = vObj.constructor.toString().match(/function\s*(\w+)/);
            if (arr && arr.length === 2) {
                return arr[1];
            }
        }
        return undefined;
    }
    function typeOf(vObj) {

        var vResult = typeof vObj;
        if (vResult === 'object') {
            try {
                if (vObj.length !== undefined) {
                    vResult = 'array';
                }
            } catch (e) {
            }
        }

        return vResult;
    }  
    function print(vPadding, vType, vValue) {

        if (vPadding === undefined) {
            vPadding = '';
        }
        if (vType === undefined) {
            vType = '';
        }
        if (vValue === undefined) {
            vValue = '';
        }
        try{
            console.log(vPadding + ' (' + vType + '): ' + vValue + "\n");
        }catch(e){
            document.write(vPadding + ' (' + vType + '): ' + vValue + "\n");
        }
       
    }  

    if (vPadding === '' || vPadding === undefined) {
        vPadding = '';
    }
    if (typeOf(vTraceObject) === 'object'
            && typeOf(vPreviousTraceObject) === 'object') {
        if (getObjectClass(vPreviousTraceObject) === getObjectClass(vTraceObject)) {
            print(vPadding, 'ERROR', 'RECURSION EXISTING ...');
            return null;
        }
    }

    var vType = typeOf(vTraceObject);
    if (vType === 'object' || vType === 'array') {
        if (vPadding === '') {
            print(vPadding, vType, '...');
            vPadding = '----';

        }
        try {
            var vTempType = '';
            var variable = '';
            for (variable in vTraceObject) {
                vTempType = typeOf(vTraceObject[variable]);
                if (vTempType === 'object' || vTempType === 'array') {
                    print(vPadding, vTempType, variable);
                    debug(vTraceObject[variable], vPadding + '----',
                            vTraceObject);
                } else {
                    print(vPadding, vTempType, variable + ' : '
                            + vTraceObject[variable]);
                }
            }
        } catch (e) {
            print(vPadding, 'ERR', 'EXCEPTION');
        }
    } else {
        print(vPadding, vType, vTraceObject);

    }


}

function objA() {
    this.varA1 = 'a1';
    this.varA2 = 'a2';
    this.myCars = new Array();
    this.myCars[0] = "Saab";
    this.myCars[1] = "Volvo";
    this.myCars[2] = "BMW";
}

function objB() {
    this.varB1 = 'b1';
    this.varB2 = 'b2';
    this.varB3 = new objA;

}
instanceB = new objB;

Output:

1
2
3
4
5
6
7
8
9
10
(object): ...
---- (string): varB1 : b1
---- (string): varB2 : b2
---- (object): varB3
-------- (string): varA1 : a1
-------- (string): varA2 : a2
-------- (array): myCars
------------ (string): 0 : Saab
------------ (string): 1 : Volvo
------------ (string): 2 : BMW

A note from later — what the modern browser console gives you for free.

When this post was written, Firebug (the Firefox extension) was where serious JavaScript debugging happened, and a recursion-safe pretty-printer like the one above filled a real gap. Firebug was discontinued in 2017 once Firefox’s built-in DevTools caught up, and the modern browser console can do most of what this function does without any helper code. 🦊

A few one-liners that cover the common cases:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const car = { make: 'Saab', model: '900', year: 1995 };

// 1. Object shorthand — Chrome/Firefox/Safari all label the value with its name.
console.log({ car });
//   { car: { make: 'Saab', model: '900', year: 1995 } }

// 2. console.dir — walks the object as an interactive, expandable tree.
console.dir(car, { depth: null });

// 3. console.table — best when you have an array of similar objects.
console.table([
  { make: 'Saab', year: 1995 },
  { make: 'Volvo', year: 2001 },
  { make: 'BMW',   year: 2010 },
]);

// 4. JSON.stringify with indentation — copy-pasteable, great for logs and bug reports.
console.log(JSON.stringify(car, null, 2));

Each of those has its niche: { var } shorthand is what you reach for inside a function ten times a day, console.dir is for poking at DOM nodes and large objects interactively, console.table turns arrays into actual tables (a small everyday joy 🎉), and JSON.stringify(obj, null, 2) is what you want when the output needs to land in a file or a chat message.

One thing the modern console doesn’t automatically protect you from is circular references — JSON.stringify throws on them. If you need a copy-pasteable dump that survives cycles, you still need a helper. A modern, smaller version of the same idea as the original function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function safeStringify(obj, indent = 2) {
  const seen = new WeakSet();
  return JSON.stringify(obj, (key, value) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) return '[Circular]';
      seen.add(value);
    }
    return value;
  }, indent);
}

const a = { name: 'a' };
const b = { name: 'b', ref: a };
a.ref = b; // circular!

console.log(safeStringify(a));
// {
//   "name": "a",
//   "ref": {
//     "name": "b",
//     "ref": "[Circular]"
//   }
// }

So the original function is no longer the tool of choice in 2024+, but the idea behind it — “give me a recursion-safe, copy-pasteable dump of anything” — is just as useful today. The modern toolbox just hands you most of it in two lines instead of fifty. 🛠️

Posted in javascript, Web Development | Comments Off on Super Powerful Debugging Function in Javascript

Storage Speed Benchmark Using CrystalDiskMark

I have always been an enthusiast in computer hardware benchmark. Lately I been trying to increase my overall PC performance (both laptop and desktop).
A speedy and responsive system does not only take a fast processor, but also enough RAM and good harddrive.
CrystalDiskMark is one of the free benchmarking tool that you can download from http://crystalmark.info.

I have benchmark various storage media with CrystalDiskMark, my hard drives, USB flash drives, SD cards. And the table below will show you the result.
Most of the time my CrystalDiskMark setting is set at max 50MB test and run 3x. CrystalDiskMark will avarage the result

Type Maker Unit Capacity Sequential Read (MB/s) Sequential Write (MB/s) Random Read 512KB (MB/s) Random Write 512KB (MB/s) Random Read 4KB (MB/s) Random Write 4KB (MB/s)
SD Card AData 2GB 4.223 1.319 4.207 1.132 3.233 0.016
SD Card Memorette 2GB 4.085 4.213 4.128 1.357 2.801 0.014
SDHC Card Lexar 2GB 4.240 6.360 4.231 2.246 3.465 0.029
3.5″ hard disk over an eSata Enclosure Western Digital WD1502FAEX 1.5 TB 102.267 99.281 56.421 71.049 1.117 1.717
USB Flash drive Verbatim 2 GB 12.696 4.537 12.584 1.358 5.425 0.030
3.5″ hard disk Seagate ST3320620NS 320.0 GB 52.890 47.749 32.586 31.949 0.604 1.112
2.5″ hard disk over USB2.0 Enclosure Seagate ST9500420AS 500GB 16MB Cache 33.141 29.265 20.262 26.809 0.479 1.067
2.5″ hard disk Seagate ST9500420AS 500GB 16MB Cache 97.769 85.319 44.833 26.809 0.681 1.139
2.5″ hard disk Seagate ST95005620AS Momentus XT 500GB + 32 MB Cache + 4GB SSD 97.572 95.051 60.792 107.489 1.050 0.751
2.5″ hard disk Western Digital WD5000BEVT – 00A0RT0 500GB 70.775 74.614 23.257 41.557 0.446 1.256
2.5″ SSD Crucial M4 SSD 128GB 256.4 171.3 226.3 142.5 14.15 20.83
3.5″ hard disk inside VMWare Workstation Western Digital WD5000BEVT – 00A0RT0 500GB 32.018 24.076 9.777 16.341 0.101 0.753
Posted in Benchmark, Hardware | Comments Off on Storage Speed Benchmark Using CrystalDiskMark

Vacuum the Whole Database in Postgres

Postgres comes with a functionality called vacuum. Vacuum is intended to cleanup dead tuples or rows.
This is how you cleanup the entire DB in PostgreSQL

1
/usr/pg9/bin/vacuumdb --full --port=5433 --username=YOUR_USERNAME --password DB_NAME
Posted in Database, PostgreSQL | Comments Off on Vacuum the Whole Database in Postgres

Finding a String Inside Multiple Files in Linux

This is how you can find a text/string Proudly inside folder /var/www. The -H parameter is to show the filename and -R is to make grep look recursively.

1
grep -H -R "Proudly" /var/www
Posted in Linux | Comments Off on Finding a String Inside Multiple Files in Linux

Fix Microsoft Mouse in Linux Ubuntu

1
2
3
4
5
6
7
8
9
10
11
12
nano /etc/X11/xorg.conf

Section "InputDevice"
Identifier "Configured Mouse"
Driver "mouse"
Option "CorePointer"
# Option "Device" "/dev/input/mice"
Option "Protocol" "ExplorerPS/2"
Option "Emulate3Buttons" "false"
Option "ZAxisMapping" "4 5"
Option "ButtonMapping" "1 2 3 6 7"
EndSection
Posted in Linux, Operating System, Ubuntu | Comments Off on Fix Microsoft Mouse in Linux Ubuntu

Colorize Linux Shell Menu

Do you ever feel like you’re going blind because the prompt text color and the result text color are the same? Here’s how to colorize your shell prompt.

Open your favorite text editor (vim or nano), edit your ~/.bashrc, and add this at the end:

1
2
3
nano ~/.bashrc
# add this line:
PS1='\[\e[1;32m\][\u@\h \t \w]\$\[\e[0m\] '

The full set of color codes (the leading digit is the intensity: 0; for normal, 1; for bold/bright — so you have 16 colors, not 8):

1
2
3
4
5
6
7
8
0;30 black           1;30 dark gray
0;31 red             1;31 light red
0;32 green           1;32 light green
0;33 brown/yellow    1;33 yellow
0;34 blue            1;34 light blue
0;35 purple          1;35 light purple
0;36 cyan            1;36 light cyan
0;37 light gray      1;37 white

A few useful additions.

The PS1 line above is dense — here’s what each piece is doing:

1
2
3
4
5
6
7
8
9
\[ ... \]    tells bash "these characters are non-printing" so it computes
             prompt width correctly (otherwise long commands wrap weirdly)
\e[1;32m     ANSI escape: bold (1) green (32)
\u           current username
\h           short hostname
\t           current time, 24-hour HH:MM:SS
\w           full working directory
\$           '#' if you're root, '$' otherwise
\e[0m        reset all colors/attributes back to default

You can preview a color in your terminal without touching .bashrc by echoing the escape sequence directly:

1
2
echo -e "\e[1;32mhello in bold green\e[0m"
echo -e "\e[0;35mhello in purple\e[0m"

That’s the fast way to audition a color before committing to it in your prompt.

For background colors, the codes run 40 to 47 (same intensity rule applies). To make the whole prompt have a colored background, combine them:

1
2
PS1='\[\e[1;33;44m\][\u@\h \w]\$\[\e[0m\] '
# bold yellow text on a blue background

One portability note: hard-coded ANSI escapes work everywhere bash runs, but if you’re writing scripts that should adapt to different terminal types, tput is the modern, terminfo-aware alternative:

1
2
3
4
5
GREEN=$(tput setaf 2)
BOLD=$(tput bold)
RESET=$(tput sgr0)

echo "${BOLD}${GREEN}status: ok${RESET}"

tput queries the terminfo database for whatever terminal you’re actually on, so it gracefully degrades on terminals that don’t support color (it just emits empty strings). For your personal .bashrc, raw ANSI is fine and shorter; for scripts you ship to other people’s machines, tput is the polite choice.

After editing, reload your shell config with source ~/.bashrc (or just open a new terminal) to see the change.

Posted in Linux, Operating System, Ubuntu | Comments Off on Colorize Linux Shell Menu

Edit default Gnome-Terminal

Every time I open a shell terminal in my Ubuntu, I always think that the window size is too small. I always ended up resizing the shell window manually using the mouse. If you’re having this problem here is how to fix it permanently.

1
gnome-terminal --geometry=120x40

2026 update — what’s still relevant, and what’s changed. 🐧

–geometry is deprecated. Modern GNOME Terminal ignores the –geometry flag in most cases. The current way to set a default window size is in the GUI: Preferences → Profile → Text, then check “Initial terminal size” and set the columns and rows you want. The next terminal you open from your launcher will use that size.

Also worth knowing — newer distros are starting to ship different terminals by default. Fedora 39+ uses gnome-console (binary name kgx), and Ubuntu 24.10+ has been experimenting with ptyxis. They all do the same thing; just be aware that gnome-terminal may not be the default anymore.

Keyboard shortcuts most people don’t use enough:

  • Ctrl+Shift+T — open a new tab (instead of a whole new window)
  • Ctrl+PgUp / Ctrl+PgDn — switch between tabs
  • Ctrl+Shift+C / Ctrl+Shift+V — copy and paste (regular Ctrl+C sends SIGINT, remember?)
  • Ctrl++ / Ctrl+- — zoom in / out (great for screen sharing)
  • Ctrl+Shift+F — search the scrollback buffer
  • Ctrl+L — clear the screen (like running clear, but quicker)
  • Shift-click on a URL — open it in your browser without selecting it first

Profiles trick — colour your prod sessions red. Under Preferences → Profiles you can create multiple profiles, each with its own colour scheme, font, and starting size. A really useful pattern is to make a separate profile (say, Server SSH) with a red or dark-red background as a visual reminder that you’re not on your laptop anymore. Then launch into it directly:

1
gnome-terminal --profile="Server SSH" -- ssh user@server

It sounds gimmicky until the first time you almost rm -rf the wrong machine. 🚨

You can also have a Dark + Big profile for late-night work, a Light profile for screen sharing, and so on — switch via Terminal → Change Profile at any time. 💡

Posted in Linux, Ubuntu | Comments Off on Edit default Gnome-Terminal