How to Implement array_concat in a PHP Extension: Merging Arrays at the C Level

This article explains how to create a PHP extension function named array_concat that merges two arrays by concatenating string values for matching keys, detailing the required C code, Zend hash operations, parameter parsing, and example usage, providing a practical guide for PHP developers.

21CTO
21CTO
21CTO
How to Implement array_concat in a PHP Extension: Merging Arrays at the C Level

This article explores PHP's internal array handling and demonstrates how to add a custom array_concat function to a PHP extension, enabling the concatenation of string values for matching keys across two arrays.

PHP Example

<?php
function array_concat($arr, $prefix) {
    foreach ($arr as $key => $val) {
        if (isset($prefix[$key]) && is_string($val) && is_string($prefix[$key])) {
            $arr[$key] = $prefix[$key] . $val;
        }
    }
    return $arr;
}

$arr = array(
    0 => '0',
    1 => '123',
    'a' => 'abc',
);
$prefix = array(
    1 => '456',
    'a' => 'def',
);
var_dump(array_concat($arr, $prefix));
?>

The code merges two arrays by concatenating string values when the same key exists in both arrays.

Implementation in a PHP Extension (C)

PHP_FUNCTION(array_concat)
{
    zval *arr, *prefix, *entry, *prefix_entry, value;
    zend_string *string_key, *result;
    zend_ulong num_key;

    if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa", &arr, &prefix) == FAILURE) {
        return;
    }

    array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(arr)));

    ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(arr), num_key, string_key, entry) {
        if (string_key && zend_hash_exists(Z_ARRVAL_P(prefix), string_key)) {
            prefix_entry = zend_hash_find(Z_ARRVAL_P(prefix), string_key);
            if (Z_TYPE_P(entry) == IS_STRING && prefix_entry != NULL && Z_TYPE_P(prefix_entry) == IS_STRING) {
                result = strpprintf(0, "%s%s", Z_STRVAL_P(prefix_entry), Z_STRVAL_P(entry));
                ZVAL_STR(&value, result);
                zend_hash_update(Z_ARRVAL_P(return_value), string_key, &value);
            }
        } else if (string_key == NULL && zend_hash_index_exists(Z_ARRVAL_P(prefix), num_key)) {
            prefix_entry = zend_hash_index_find(Z_ARRVAL_P(prefix), num_key);
            if (Z_TYPE_P(entry) == IS_STRING && prefix_entry != NULL && Z_TYPE_P(prefix_entry) == IS_STRING) {
                result = strpprintf(0, "%s%s", Z_STRVAL_P(prefix_entry), Z_STRVAL_P(entry));
                ZVAL_STR(&value, result);
                zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, &value);
            }
        } else if (string_key) {
            zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry);
            zval_add_ref(entry);
        } else {
            zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry);
            zval_add_ref(entry);
        }
    } ZEND_HASH_FOREACH_END();
}

Explanation

In PHP, arrays are implemented as hash tables. The extension code interacts directly with the Zend Engine's hash API, defined in Zend/zend_hash.h and Zend/API.h. Functions such as zend_hash_num_elements, zend_hash_exists, zend_hash_find, and their index variants are used to query and manipulate the hash.

The macro ZEND_HASH_FOREACH_KEY_VAL provides a foreach‑like iteration over the hash entries. For each key, the code checks whether the same key exists in the $prefix array and whether both values are strings. If so, it concatenates the strings using strpprintf and updates the result hash.

Reference counting is handled manually with zval_add_ref when entries are copied into the return array, ensuring proper memory management.

For further reading on PHP 7 hash table internals, see the article at http://jpauli.github.io/2016/04/08/hashtables.html .

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CPHPExtensionArrayhashtableZend
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.