Monday, April 14, 2008

Script Type PHP :)

Update 2008/03/15
I have removed preg_replace and added DOM classes to parse and manage, in a better way, script nodes that contain php code.
Everything inside a simple PHP 5 compatible class.
Finally, please remember that this is a layer between <?php ?> and JavaScript, and only an experiment ;)

Here you can read another example, where difference between server, output, and client, should be more clear than precedent one.

<?php require 'PHPScriptHandler.php'; ?>
<html>
<head>
<title>Hello PHP World</title>
<script type="text/php" author="andr3a">

// here we are between the server and output, known as client
$hello = ucwords('hello php world');

// imagine that we would like to use a variable
// defined somewhere in the server
global $something;

// we could even include or require php files
// perform database operations and everything else
</script>
<script type="text/javascript">
onload = function(){
// here we are in the client, on window load event
alert($hello);
alert($something);
};
</script>
</head>
<body>
<?php
// here we are in the server side
// we could do what we do every day without problems
$something = '<div>Hello Body</div>';
echo $something;
?>
</body>
</html>


-------------------------------

This is a little experiment to emulate script tag with php.
The final result will be something like this one:

<html>
<head>
<title>Hello PHP World</title>
<script type="text/php">

// string
$hello = ucwords('hello php world');

// object
$o = new stdClass;
$o->test = 'hello again';

</script>
<script type="text/javascript">
onload = function(){
alert($hello);
alert($o.test);
};
</script>
</head>
<body>
</body>
</html>

How can it be possible?

<?php // 5 - PHP Script Handler Experiment - by Andrea Giammarchi
function php_script_handler($output){return stripos($output, 'type="text/php"') ? preg_replace_callback('#(?i)<script[[:space:]]+type="text/php"(.*?)>([^\a]+?)</script>#', 'php_script_parser', $output) : $output;}
function php_script_parser(){eval(end(func_get_arg(0)));return '<script type="text/javascript"'.next(func_get_arg(0)).'>'.PHP_EOL.php_script_vars(get_defined_vars()).PHP_EOL.'</script>';}
function php_script_vars($vars){foreach($vars as $key => $value)$vars[$key] = '$'.$key.'='.json_encode($value).';';return implode(PHP_EOL, $vars);}
ob_start('php_script_handler');
?>

Of course, we need to include this file before we write a single character in the layout (spaces included), so basically to obtain the expected result, just save above code in a file called, for example, php_script_handler.php, and put them before the layout

<?php require 'php_script_handler.php'; ?>
<html>
<head>
<title>Hello PHP World</title>
.... other stuff ....


The evil eval? Yes, absolutely ... but first of all, this is only a simple experiment, secondly, the page will not be sent before evaluation, so there's no way from the client side to inject malicious code.

The main problem is true interoperability between these two languages, JavaScript, and PHP, but did I say that this is only an experiment? :P

No comments:

Post a Comment