HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Polyglot array_extend() function for Javascript and PHP

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
array_extendjavascriptphpfunctionforandpolyglot

Problem

This is a polyglot function I've made out of fun.

The goal is to grab n arrays (or Javascript Objects) and 'extend' them in order to obtain a single array with all the values.

This function runs both in Javascript and PHP.

Please, try to ignore some kludges on my code.

Here is my 'art':

function array_extend() {

    //Detects if we are running in Javascript or PHP
    //In PHP, this will be false because PHP only parses
    //escape sequences in double-quoted strings (except the sequence \')
    $javascript = '\0' == "\0";

    //PHP arrays support 'key=>value' pairs, JS arrays don't.
    $result = $javascript ? new Object() : array();

    $arguments = $javascript? arguments : func_get_args();

    $get_keys = function($elem){
        if('\0' == "\0")//PHP complains if I use the var $javascript
        {
            $object = Object;
            return $object['keys']($elem); //PHP doesn't like the Object.keys syntax
        }
        else
        {
            return array_keys($elem);
        }
    };

    for($j = 0, $length_args = $javascript? $arguments['length']: count($arguments); $j < $length_args; $j++)
    {
        $keys = $get_keys( $arguments[$j] );

        for($i = 0, $length_keys = $javascript? $keys['length']: count($keys); $i < $length_keys; $i++)
        {
            $result[$keys[$i]] = $arguments[$j][$keys[$i]];
        }
    }

    return $result;
}


Example of usage:

array_extend([1,2,3,4,5],[9,8,7,6,5,4,3,2,1,0]);
//should return the last elements in the array:

array_extend({'a':1, 'b':2, 'c':3},{test:'nice'});
//Javascript: returns {'a':1, 'b':2, 'c':3, test:'nice'}

array_extend(array('a'=>1, 'b'=>2, 'c'=>3), array('test'=>'nice'));
//PHP: returns array('a'=>1, 'b'=>2, 'c'=>3, 'test'=>'nice')


What do you guys think?

What can I improve? Where should I have done something better?

Solution

You may want to replace object key access notation with dot notation.

For example, instead of the following.

$object['keys']($elem);


Write this.

Object.keys($elem);


This works, because Object is interpreted as a constant, dot as concatenation, and keys($elem) as function call. Use of undefined constant doesn't warn if the code with it is not executed. Unknown functions don't error if they aren't called.

Code Snippets

$object['keys']($elem);
Object.keys($elem);

Context

StackExchange Code Review Q#79804, answer score: 2

Revisions (0)

No revisions yet.