Automatic php2js convertion

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

Post Reply
tores
Forum Contributor
Posts: 120
Joined: Fri Jun 18, 2004 3:04 am

Automatic php2js convertion

Post by tores »

Hi all

Hopefully this will make peoples lives easier :wink:

EDIT: Better code further down

Javascript

Code: Select all

/* Converts a string representation of a php-variable to a js variable */
function php2js (variable) {
	var i, js_code;
	
	/* Replace entities */
	variable = variable.replace(/</g, "<");
	variable = variable.replace(/>/g, ">");
	variable = variable.replace(/&/g, "&");
	variable = variable.replace(/"/g, '"');
	variable = variable.replace(/'/g, "\\'");
	variable = variable.replace(/&brkln;/g, "\n");
	variable = variable.replace(/&slash;/g, "\\");

	/* Create global tokens */
	tokens = variable.split("\n");

	/* Remove empty tokens */
	for(i = 0; i < tokens.length; i++) {
		if (tokens[i] == '') {
			tokens.splice(i, 1);
		}
	}
	
	/* Create js code */
	js_code = 'var js_var = ' + build_js_var() + ';';
	
	/* Evaluate code and return it */
	eval(js_code);
	return js_var;
}


/* Builds js_code from the tokens */
function build_js_var () {
	var js, match, token;

	token = tokens.shift();

	if (token.match(/\w*? ?(Array|Object)/) != null) {
		/* Match arrays and objects, convert both to js Array */
		js = 'new Array';
	} else if ((match = token.match(/\s*?(\(|\))/)) != null) {
		/* Match parenthesis */
		js = match[1];
	} else if ((match = token.match(/\s+?\[.+?\] => (.*)/)) != null) {
		/* Match array values and object properties */
		js = "'" + match[1] + ((tokens[0].match(/\s*?\)/) != null) ? "'" : "',");
	} else {
		js = "'" + token + "'";
	}
	
	if (tokens.length > 0) {
		js += build_js_var();
	}
	return js;
}


/* Dumps variable. Output is similar to a preformated print_r */
function print_f (variable, margin){
	var property, html, tabs, i, key_color;
	
	key_color = 'orange';
	
	tabs = '';
	for (i = 0; i < margin + 1; i++) {
		tabs += '\t';
	}
	html = (margin == 0 && typeof(variable) == 'object') ? '<pre>Array\n(\n' : '';

	if (margin == 0 && html == '') {
		html += tabs + variable + '\n';
	} else {
		for(property in variable) {
			if (typeof(variable[property]) == 'object') {
				html += tabs + '[<span style="color:' + key_color + '">' + property + '</span>] => Array\n' +
						tabs + '(\n' + print_f(variable[property], margin + 1) + tabs + ')\n';
			} else if (typeof(variable[property]) == 'function') {
				html += tabs + '[<span style="color:' + key_color + '">' + property + '</span>] => ' + variable[property].toSource() + '\n';
			} else {
				html += tabs + '[<span style="color:' + key_color + '">' + property + '</span>] => ' + variable[property] + '\n';
			}
		}
	}
	if (margin == 0) {
		html += (typeof(variable) == 'object') ? ')</pre>' : '';
		document.write(html);
		document.close();
	} else {
		return html;
	}
}


/* Test-function */
function test (php_string) {
	/* Convert php string to js var */
	var js_var = php2js(php_string);
	
	/* Print js-variable */
	print_f(js_var, 0);
}
PHP

Code: Select all

/**
* Makes <var>$var</var> safe to pass as parameter to a js-function
* @param string Unsafe string-representation of variable
* @return string Safe string-representation of variable
*/
function make_js_safe ($var) {
	/* Note: &brkln; and &slash; is not html entities */
	return htmlspecialchars(str_replace(array("\n", "\\"), array('&brkln;', '&slash;'), $var), ENT_QUOTES);
}


/**
* Wrapper function for calling a javascript function
* @param string Name of the js function
* @param mixed Parameter(s) to pass to the js function
* @param bool Whether to create script-tags around the function-call
*/
function call_js_function ($fname, $var, $create_js_tags = true) {
	$fcall = $fname . '("' . make_js_safe( print_r($var, 1) ) . '")';
	echo ($create_js_tags) ? "<script type='text/javascript'>\n\t$fcall\n</script>" : $fcall;
}
Test

Code: Select all

/* Test php2js convertion with some more or less random data */
$o = new stdClass();
$o->g = 'something';
$o->prop = array(4 => 'fo\'o"', 'f\d' => -1);

$t = array(-3 => 1.2, 'bar' => 'images/alter2.JPG', 0 => false, 't' => null, 'key' => 'images/log1.JPG', 'o' => $o);

echo '<pre>';
print_r($t);
echo '</pre>';

call_js_function('test', $t);
Output

Code: Select all

Array
(
    [-3] => 1.2
    [bar] => images/alter2.JPG
    [0] => 
    [t] => 
    [key] => images/log1.JPG
    [o] => stdClass Object
        (
            [g] => something
            [prop] => Array
                (
                    [4] => fo'o"
                    [f\d] => -1
                )

        )

)

Array
(
	[0] => 1.2
	[1] => images/alter2.JPG
	[2] => 
	[3] => 
	[4] => images/log1.JPG
	[5] => Array
	(
		[0] => something
		[1] => Array
		(
			[0] => fo'o"
			[1] => -1
		)
	)
)
It's not bulletproof, and it converts every php array or object to a basic js-array... Future work includes adding support for associative arrays

regards tores
Last edited by tores on Sat Aug 27, 2005 4:47 pm, edited 1 time in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I've used something like this in the past

Code: Select all

<?php

function php2js($var,$prefix,$returnArray = false)
{
  $ret = array();
  if(is_array($var) or is_object($var))
  {
    $ret[] = $prefix . ' = new Array();';
    foreach($var as $key => $value)
    {
      array_splice($ret, count($ret), 0, php2js($value,$prefix.'['.var_export($key,true).']',true));
    }
  }
  elseif(is_numeric($var))
  {
    $ret[] = $prefix . ' = ' . $var . ';';
  }
  elseif($var === null or is_resource($var))
  {
    $ret[] = $prefix . ' = null;';
  }
  else
  {
    $ret[] = $prefix . ' = ' . var_export($var,true) . ';';
  }

  return ($returnArray ? $ret : implode("\n",$ret)."\n");
}

function test_php2js()
{
  $o = new stdClass();
  $o->g = 'something';
  $o->prop = array(4 => 'fo\'o"', 'f\d' => -1);

  $t = array(-3 => 1.2, 'bar' => 'images/alter2.JPG', 0 => false, 't' => null, 'key' => 'images/log1.JPG', 'o' => $o);

  print_r($t);
  echo php2js($t,'myJSVar');

  echo php2js(35,'myNumVar');

  echo php2js('some string','myStrVar');
}

test_php2js();

?>
outputs

Code: Select all

Array
(
    [-3] => 1.2
    [bar] => images/alter2.JPG
    [0] =>
    [t] =>
    [key] => images/log1.JPG
    [o] => stdClass Object
        (
            [g] => something
            [prop] => Array
                (
                    [4] => fo'o"
                    [f\d] => -1
                )

        )

)
myJSVar = new Array();
myJSVar[-3] = 1.2;
myJSVar['bar'] = 'images/alter2.JPG';
myJSVar[0] = false;
myJSVar['t'] = null;
myJSVar['key'] = 'images/log1.JPG';
myJSVar['o'] = new Array();
myJSVar['o']['g'] = 'something';
myJSVar['o']['prop'] = new Array();
myJSVar['o']['prop'][4] = 'fo\'o"';
myJSVar['o']['prop']['f\\d'] = -1;
myNumVar = 35;
myStrVar = 'some string';
:)
tores
Forum Contributor
Posts: 120
Joined: Fri Jun 18, 2004 3:04 am

Post by tores »

Excellent code feyd... I used it to modify my previous post. Hope you don't mind.

Javascript

Code: Select all

/* Dumps variable. Output is similar to a preformated print_r */
function print_f (variable, level){
	var property, html, margin, tab, i, key_color;
	
	key_color = 'orange';
	tab = '    ';
	
	if (typeof(variable) == 'object') {
		if (level == 0) {
			html = '<pre>Array\n(\n';
		} else {
			html = '';
		}
		margin = tab;
	} else {
		html = '';
		margin = '';
	}

	for (i = 0; i < level; i++) {
		margin += tab;
	}

	if (level == 0 && html == '') {
		html += margin + variable + '\n';
	} else {
		for(property in variable) {
			if (typeof(variable[property]) == 'object' && variable[property] != null) {
				html += margin + '[<span style="color:' + key_color + '">' + property + '</span>] => Array\n' +
						margin + tab + '(\n' + print_f(variable[property], level + 2) + margin + tab + ')\n';
			} else if (typeof(variable[property]) == 'function') {
				html += margin + '[<span style="color:' + key_color + '">' + property + '</span>] => ' + variable[property].toSource() + '\n';
			} else {
				html += margin + '[<span style="color:' + key_color + '">' + property + '</span>] => ' + variable[property] + '\n';
			}
		}
	}
	if (level == 0) {
		html += (typeof(variable) == 'object') ? ')</pre>' : '';
		document.write(html);
		document.close();
	} else {
		return html;
	}
}


/* Opposite to make_js_safe */
function entity_decode(variable) {
	/* Replace entities */
	variable = variable.replace(/</g, "<");
	variable = variable.replace(/>/g, ">");
	variable = variable.replace(/&/g, "&");
	variable = variable.replace(/"/g, '"');
	variable = variable.replace(/&brkln;/g, "\\n");
	variable = variable.replace(/&slash;/g, "\\");

	return variable;
}


/* Test-function */
function test (js_encoded) {
	/* Convert php string to js var */
	eval(entity_decode(js_encoded));
	
	/* Print js-variable */
	print_f(args, 0);
}
PHP

Code: Select all

/**
* Wrapper function for calling a javascript function.
* @param string Name of the js function
* @param mixed Parameter(s) to pass to the js function
* @param bool Whether to create script-tags around the function-call
*/
function call_js_function ($fname, $params, $create_js_tags = true) {
	$fcall = $fname . '("' . $params . '")';
	echo ($create_js_tags) ? "<script type='text/javascript'>$fcall</script>" : $fcall;
}


/**
* Makes <var>$var</var> safe to pass as parameter to a js-function
* @param string Unsafe string-representation of variable
* @return string Safe string-representation of variable
*/
function make_js_safe ($var) {
    /* Note: &brkln; and &slash; is not html entities */
    return str_replace(array("\n", "\\"), array('&brkln;', '&slash;'), htmlspecialchars(var_export($var, true)));
}


/**
* Convert php var to corresponding js-code. Original code by feyd
* HTML may be present in <var>var</var>
* @param mixed A php variable
* @param string Prefix
* @param bool Top level or not
* @return string js-code
*/
function php2js ($var, $prefix, $toplevel = true) {

	$ret = array();
	if (is_array($var) or is_object($var)) {
		$ret[] = $prefix . ' = new Array();';
		foreach ($var as $key => $value) {
			array_push($ret, php2js($value, $prefix.'['.make_js_safe($key).']', false));
		}
	} elseif (is_numeric($var)) {
		$ret[] = $prefix . ' = ' . $var . ';';
	} elseif ($var === null or is_resource($var)) {
		$ret[] = $prefix . ' = null;';
	} else {
		$ret[] = $prefix . ' = ' . make_js_safe($var) . ';';
	}

	return ($toplevel) ? 'var '.implode('', $ret) : implode('', $ret);
}

function test_php2js() {
	$o = new stdClass();
	$o->g = "something\n";
	$o->prop = array(4 => 'fo\'o"', 'f\d' => true);

	$t = array(-3 => 1.2, 'bar' => '<b>bold text</b>', 0 => false, 't' => null, 'key' => 'images/log1.JPG', 'o' => $o);

	print_r($t);
	call_js_function('test', php2js($t, 'args'));

	$params = array('innerHTML' => '<a href="is out there">The truth</a>', 'style' => array('color' => 'red', 'font-weight' => 'bold'), 'pi' => M_PI);
	call_js_function('test', php2js($params, 'args'));
}

echo '<pre>';
test_php2js();
echo '</pre>';
Output

Code: Select all

Array
(
    [-3] => 1.2
    [bar] => bold text
    [0] => 
    [t] => 
    [key] => images/log1.JPG
    [o] => stdClass Object
        (
            [g] => something

            [prop] => Array
                (
                    [4] => fo'o"
                    [f\d] => 1
                )

        )

)

Array
(
    [-3] => 1.2
    [bar] => bold text
    [0] => false
    [t] => null
    [key] => images/log1.JPG
    [o] => Array
        (
            [g] => something

            [prop] => Array
                (
                    [4] => fo'o"
                    [f\d] => true
                )
        )
)

Array
(
    [innerHTML] => The truth
    [style] => Array
        (
            [color] => red
            [font-weight] => bold
        )
    [pi] => 3.1415926535898
)
Post Reply