Access the Windows Registry with PHP

Share this article

Have you ever woken up in the morning and thought to yourself, “I want to do something crazy today?” Well, if today was one of those mornings then you’re in luck. I’d like to give you a little introduction on accessing the Windows Registry using PHP. PHP… the Registry… CRAZY! The Windows Registry is simply a hierarchically structured database in which the Windows operating system and other applications store important configuration information. All sorts of data is stored in the registry: user profiles, file-type associations, hardware information, serial numbers, and more. With functions available from the win32std extension, your Windows-based PHP applications can access the registry too. The win32std extension can be downloaded as a pre-compiled library from downloads.php.net/pierre/. Simply drop it into your PHP’s ext folder, update your php.ini file, and restart Apache if necessary. Note that right now the DLLs you’d download are 32-bit, so if you’re using a 64-bit build of WampServer or such then you won’t have much success. You’ll have to either downgrade WampServer to a 32-bit build or try compiling the library yourself.

The Registry Layout

The registry has a reputation of being a dark, dangerous and scary place in the Windows operating system. This is probably an over exaggerated fear, but still I’ll reiterate Microsoft’s registry mantra: “Before you modify the registry, back it up and make sure you understand how to restore it if a problem occurs. Improper changes could cause serious problems that may require you to reinstall your operating system.” So what does this dark, scary place look like? The Windows Registry is divided up into 5 main groups known as keys: HKEY_CURRENT_CONFIG
This key stores information about the computer’s hardware such as monitor resolution and speaker settings. You may see this key abbreviated as HKCC. HKEY_LOCAL_MACHINE
This key contains configuration information for the machine such as printers, software and networking information. The key is loaded first and then entries from the user’s profile override various values. You’ll see this key abbreviated as HKLM. HKEY_USERS
This key holds all the profiles for the local user accounts on the machine. Such things as the user’s screensaver selection, theme information and other preferences are stored here. This key is abbreviated as HKU. HKEY_CLASSES_ROOT
This key is an alias pointing to HKEY_LOCAL_MACHINESoftware which stores information about file associations and mime-types. The abbreviation is HKCR. HKEY_CURRENT_USER
This key is an alias pointing to the profile in HKEY_USERS for the currently logged in user. You’ll see this key abbreviated as HKCU. Each key contains subkeys which in turn contain other subkeys, configuration values, or both. Working under HKEY_CURRENT_USER is sufficient for playing around with a few CLI scripts and a sandbox. Only use HKEY_LOCAL_MACHINE for system-wide application data and situations where you are comfortable working with Microsoft’s security permissions. Understand what is right for your situation, know under which account PHP runs, and create your keys appropriately.

Making a Sandbox

I recommend setting up a special key for use in your scripts for the sake of safety, especially when you’re developing. To err is human and we don’t want to accidentally overwrite anything important. Organization is another reason for setting up a designated key. There’s a lot of information stored in the registry and we want to be able to locate our own values easily. Registry Editor is a Microsoft program used to view and edit the registry. To create our sandbox, go to Start, type “regedit” in the search bar, and select regedit.exe in the results list that appears. The left pane shows a tree structure of the existing keys while the right pane shows values stored within them. Expand the HKEY_CURRENT_USER node, right-click on the Software key and select New > Key from the popup context menu. Alternatively, we could have also traversed through the tree using the arrow keys so that the Software key is highlighted and select New > Key from the Edit menu. Supply a name for the key and press enter.

Now that we have a place to play, allow me to introduce you to the functions that win32std offers to manipulate registry entries.

Reading from the Registry

The reg_open_key() function opens a connection to the registry and returns a resource. This resource is then used with other registry functions to act on that connection. The reg_close_key() function closes the connection. reg_open_key() takes two arguments: first a predefined constant representing one of the five primary registry groups, then the remainder of the path to the desired key.
<?php
$keyConst = HKEY_CURRENT_USER;

// backslash is used as an escape so it must be escaped itself
$key = "Software\Intel";

// open the registry key HKCUSoftwareIntel
if (!($reg = @reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}
...

reg_close_key($reg);
Now that you have an open connection, you can retrieve information from the registry using the reg_enum_key(), reg_enum_value() and reg_get_value() functions. If just the resource is passed to reg_enum_key() then it will return an array of subkeys under the current key. An integer value can also be passed to retrieve the subkey at a particular index.
<?php
// retrieve an array of subkeys under the current key
$subkeys = reg_enum_key($reg);
foreach ($subkeys as $index => $subkey) {
    echo "The subkey at " . $index . " is " . $subkey . "n";
}

// retrieve a specific subkey
$index = 2;
$subkey = reg_enum_key($reg, $index);
echo "The subkey at " . $index . " is " . $subkey . "n";
As reg_enum_key() returns keys, reg_enum_value() returns the values of the keys. The function accepts the resource and an optional index. The value name can be passed to reg_get_value() to retrieve the value’s value (isn’t that a mouthful!).
<?php
// retrieve an array of values under a given key
$values = reg_enum_value($reg);
foreach ($values as $index => $value) {
    echo "The value at " . $index . " is " . $value . " and stores ";
    echo reg_get_value($reg, $value) . "n";
}

// retrieve a specific value given the index
$index = 1;
$value = reg_enum_value($reg, $index);
echo "The value at " . $index . " is " . $value . " and stores ";
echo reg_get_value($reg, $value) . "n";

Writing to the Registry

There are a handful of data types you can choose from when reading from and writing to the registry. They’re generally of little consequence because of PHP’s dynamic nature but you do have to specify the type when you write a value. Most of the time you’ll find yourself using REG_SZ or REG_DWORD, but here’s a list of the data types exposed By the extension:
  • REG_DWORD – value is stored as a 32-bit long integer
  • REG_SZ – value is stored as a fixed-length string
  • REG_EXPAND_SZ – value is stored as a variable-length string
  • REG_MULTI_SZ – value is a list of items separated by a delimiter such as a space or comma
  • REG_BINARY – value is a binary string
  • REG_NONE – value has no particular data type associated with it
The reg_set_value() function is used to write a value to the registry. If the value already exists then the new value will overwrite it, but if it doesn’t exist then it will create it. The function takes four arguments: first the open resource, then the name of the value, then a predefined constant representing the value’s data type and finally the data itself.
<?php
$keyConst = HKEY_CURRENT_USER;
$key = "Software\SitePoint";
if (!($reg = @reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}

$values = array(
    array("dbDriver", REG_SZ,    "mssql"),
    array("dbHost",   REG_SZ,    "localhost"),
    array("dbPort",   REG_DWORD, 1433),
    array("dbSchema", REG_SZ,    "MyAppDB"),
    array("dbUser",   REG_SZ,    "DBUser"),
    array("dbPass",   REG_SZ,    "s3cr3t"));

foreach ($values as $value) {
    reg_set_value($reg, $value[0], $value[1], $value[2]);
}

reg_close_key($reg);

An Example – USB Drive Dongle

You might be wondering if there’s a practical use for working with the Registry. In a web-based application, you could store your configuration information in the registry. If you’ve written a desktop application then the registry could be a good place to store all sorts of information from application data to user preferences. Windows itself writes all sorts of interesting hardware and state related information to the registry, and some of it could be useful if you’re creative enough. Suppose our PHP application has been licensed in such a way that a USB dongle is required to be attached to the server to run it. How can PHP detect the presence of the dongle? The answer on Windows lies in the Registry! Each device has a unique identifier, and so the script can search the appropriate keys for the identifier when it starts up to determine whether the dongle is plugged in or not. The first step is to determine the identifier of the device. For this example I’ll use a commodity thumbdrive. Simply plug the drive into a USB port on the computer, and then go to Start, type “device” in the search bar, and select Device Manager in the results list that appears. Find the device in Device Manager, right click the entry, and select Properties from the context menu. Then go to the Details tab of the Properties window and select “Device Instance Path” from the drop down list. The sequence of the hexadecimal numbers towards the end of the value is the device id (marked in red).

Windows records the presence of USB devices under various subkeys of HKEY_LOCAL_MACHINESystemCurrentControlSetServices. Storage media like my thumbdrive will appear under USBSTOR; other devices may appear under usbaudio, usbccgp, and usbehci. Also, note that HKEY_LOCAL_MACHINE will be accessibly only be privileged accounts. So now we can simply search the key’s Enum subkey for the device instance. When the drive is attached it will be listed, and when it’s not attached it won’t be listed.
<?php
// device instance ID
$id = "0060E049DF74EC311000711F";

// WARNING: must run with administrative privs to access these keys
$keyConst = HKEY_LOCAL_MACHINE;
$key = "SYSTEM\CurrentControlSet\services\USBSTOR\Enum";

if (!($reg = reg_open_key($keyConst, $key))) {
    throw new Exception("Cannot access registry.");
}

$found = false;
$numDevices = reg_get_value($reg, "Count");
for ($i = 0; $i < $numDevices; $i++) {
    $value = reg_get_value($reg, $i);
    if (strpos($val, $id) !== false) {
        $found = true;
        break;
    }
}    
reg_close_key($reg);

echo "USB drive dongle ", ($found) ? "found" : "not found";
This simple check also opens up some other interesting possibilities; you could easily code a sensitive admin-only interface which verifies the dongle and the request is sent from the server itself by checking $_SERVER["REMOTE_ADDR"]. This set up would require the user to be physically at the designated server and provide a form of physical authentication.

In Conclusion

Throughout the course of this article we’ve seen what the Windows Registry is and a small sample of what information can be found in it. You can write your own configuration data, or you can read back information, using the functions provided by the win32std extension. By the way, the win32std extension offers more than just access to the registry. If you’re interested, check out wildphp.free.fr/wiki/doku.php?id=win32std:index to see what else it offers. Image via Fotolia

Frequently Asked Questions (FAQs) about Accessing the Windows Registry from PHP

How can I access the Windows Registry from PHP?

Accessing the Windows Registry from PHP can be achieved by using the COM class in PHP. This class allows PHP to interact with any COM objects, including the Windows Registry. You can create a new instance of the COM class and then use the RegRead method to read a value from the registry. However, please note that this method requires the correct permissions to access the registry.

What is the Windows Registry and why would I need to access it from PHP?

The Windows Registry is a database that stores low-level settings for the operating system and for applications that opt to use the registry. You might need to access it from PHP for various reasons, such as to retrieve system information, check for the presence of certain software, or to modify system settings. However, modifying the registry should be done with caution as it can affect the system’s operation.

Can I write to the Windows Registry from PHP?

Yes, you can write to the Windows Registry from PHP using the RegWrite method of the COM class. However, this should be done with extreme caution as incorrect modifications can cause serious problems that may require you to reinstall your operating system.

What permissions do I need to access the Windows Registry from PHP?

To access the Windows Registry from PHP, you need to have administrative privileges. This is because the registry contains critical system and application settings. If you’re running your script from a web server, the server’s user account will also need to have the necessary permissions.

What is the structure of the Windows Registry?

The Windows Registry is organized hierarchically as a tree, with keys and values. Keys are similar to folders, and values are the data entries within the keys. Each key can contain subkeys, and each subkey can contain further subkeys, forming a tree structure.

How can I handle errors when accessing the Windows Registry from PHP?

When accessing the Windows Registry from PHP, errors can be handled using the standard PHP error handling functions. For example, you can use the set_error_handler function to define a custom error handler.

Can I access the Windows Registry from PHP on a non-Windows system?

No, you cannot access the Windows Registry from PHP on a non-Windows system. The Windows Registry is a feature specific to the Windows operating system.

What is the COM class in PHP?

The COM class in PHP is a built-in class that allows PHP to interact with COM objects. COM (Component Object Model) is a binary-interface standard for software components introduced by Microsoft. It allows PHP to interact with any COM objects, including the Windows Registry.

Can I delete keys from the Windows Registry using PHP?

Yes, you can delete keys from the Windows Registry using PHP. This can be done using the RegDelete method of the COM class. However, this should be done with extreme caution as deleting the wrong key can cause serious problems.

What are the risks of modifying the Windows Registry?

Modifying the Windows Registry carries risks. Incorrect modifications can cause serious problems that may require you to reinstall your operating system. Therefore, it’s recommended to back up the registry before making any changes and to only make changes if you’re confident in what you’re doing.

Timothy BoronczykTimothy Boronczyk
View Author

Timothy Boronczyk is a native of Syracuse, New York, where he lives with no wife and no cats. He has a degree in Software Application Programming, is a Zend Certified Engineer, and a Certified Scrum Master. By day, Timothy works as a developer at ShoreGroup, Inc. By night, he freelances as a writer and editor. Timothy enjoys spending what little spare time he has left visiting friends, dabbling with Esperanto, and sleeping with his feet off the end of his bed.

Intermediate
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week