📄 saja.php
字号:
<?php
/*
Example Usage: (ASP-style PHP tags are used instead of PHP-style tags to avoid bad parsing in editors)
page url: http://www.yoursite.com/index.php
saja url: http://www.yoursite.com/path/to/saja.php
---------- <index.php> -----------
<%
include($_SERVER['DOCUMENT_ROOT'].'/path/to/saja.php');
$saja = new saja;
$saja = set_path('/path/to/');
$saja->secure_mode(); //uses session variables to secure php function calls (optional)
%>
<div id=outputDiv>Some Text</div>
<input type=text id=myInput>
<button id=myButton onclick="<%=$saja->run("MyPhpFunction(myInput:value)->outputDiv:innerHTML");%>">do something</button>
---------- </index.php> -----------
---------- <saja.functions.php> -----------
<%
$validFunctions = array('MyPhpFunction');
function MyPhpFunction($myInput)
{
echo "You typed: [$myInput]";
$saja = new saja;
$saja->hide('myInput');
$saja->text('Done!','myButton:innerHTML');
$saja->rawjs("alert('Alert!')");
return $saja->send();
}
%>
---------- </saja.functions.php> -----------
*/
class saja
{
var $rc4_key;
var $saja_path;
var $actions;
var $splitsent = 0;
var $functionPadding = 15;
var $http_key = '';
function saja()
{
}
function set_path($path)
{
$this->saja_path = $path;
}
function secure_functions($keep_session=0)
{
$this->rc4_key = md5(rand());
if(!session_id())
session_start();
if(!$keep_session || !isset($_SESSION['SAJA_RC4_KEY']))
$_SESSION['SAJA_RC4_KEY'] = $this->rc4_key;
else
$this->rc4_key = $_SESSION['SAJA_RC4_KEY'];
}
function secure_http($keep_session=0)
{
$this->http_key = md5(rand());
if(!session_id())
session_start();
if(!$keep_session || !isset($_SESSION['SAJA_HTTP_KEY']))
$_SESSION['SAJA_HTTP_KEY'] = $this->http_key;
else
$this->http_key = $_SESSION['SAJA_HTTP_KEY'];
}
function secure_mode($keep_session=0)
{
$this->secure_functions($keep_session);
$this->secure_http($keep_session);
}
function saja_js()
{
$js = '<script type="text/javascript">var SAJA_PATH="'.$this->saja_path.'"; var SAJA_HTTP_KEY="'.$this->http_key.'"</script>'."\n";
$js .= '<script type="text/javascript" SRC="'.$this->saja_path.'saja.js"></script>'."\n";;
return $js;
}
function saja_status($style='')
{
return "<span id=\"sajaStatus\" style=\"$style\"></span>";
}
function sajasplit()
{
if(!$this->splitsent)
{
$this->splitsent = 1;
return '<saja_split>';
}
}
function run($commands)
{
//convert all strings so they are not parsed
list($parsedcommands, $strings) = $this->sajaParse($commands);
$commands = $this->ParseCommands($parsedcommands);
return $this->sajaUnParse($commands, $strings);
}
function texplode($seperator, $str)
{
foreach(explode($seperator, $str) as $val)
if($val)
$vals[] = trim($val);
return $vals;
}
function parseArgs($args, $getType)
{
$args = $this->texplode(',',$args);
if($args)
foreach($args as $arg)
{
if(strstr($arg,':'))
{
list($id, $property) = $this->texplode(':', $arg);
$arg = '';
}
if($getType == 'PHP')
{
if($i) $inner .= ',';
if($property)
$inner .= "'+saja.GetAsQuoted('$id','$property')+'";
else if($arg)
$inner .= "'+$arg+'";
else
$inner .= "'+$id+'";
}
else if($getType == 'PHPJSIN')
{
$inner .= "'+$arg)+'";
}
else if($getType == 'JS')
{
if($i) $inner .= ',';
if($property)
$inner .= "saja.Get('$id','$property')";
else
$inner .= $arg;
}
else if($getType == 'VAR')
{
if($property)
$inner .= "'+saja.Get('$id','$property')+'";
else if($arg)
$inner .= $arg;
else
$inner .= "'+$id+'";
}
$i++;
}
return $inner;
}
function sajaParse($string)
{
//parse all strings out of the command
$string = str_replace('\\\'', '\\"', $string);
$strings = explode('\'', $string);
for($i=0; $i<sizeof($strings); $i++)
{
$str = $strings[$i];
//a string
if($i%2)
{
$str = str_replace('\\"','\'',$str);
$j = ($i-1)/2;
$strs[$j] = $str;
$parsed[] = '$_'.$j.'_$';
}
//not a string
else
$parsed[] = $str;
}
$string = implode('', $parsed);
return array($string, $strs);
}
function sajaUnParse($commands, $strings)
{
if($strings)
foreach(array_keys($strings) as $key)
{
$commands = str_replace('$_'.$key.'_$', '\'\'+unescape(\''.rawurlencode($strings[$key]).'\')+\'\'', $commands);
}
return $commands;
}
function ParseCommands($commands)
{
$commands = $this->texplode(';', $commands);
foreach($commands as $command)
{
list($functions, $targets) = $this->texplode('->', $command);
if(strstr($functions, '('))
{
$inputArray = $this->texplode('(', $functions);
list($function, $args) = $inputArray;
if(sizeof($inputArray) > 2)
{
$args = rtrim(implode('(',array_slice($inputArray,1)),')').')';
$inputType = 'JsFunction';
}
$args = rtrim($args,')');
list($target, $action) = $this->texplode(',', $targets);
list($targetId, $targetProperty) = $this->texplode(':', $target);
if(!$action) $action = 'r';
if(!$targetProperty) $targetProperty = 'innerHTML';
if(strstr($function, ':'))
$all_commands .= "saja.Put(".trim($function,':')."(".$this->parseArgs($args, 'JS')."),'$targetId','$action','$targetProperty');";
else if($function)
{
//secure requests
if($this->rc4_key)
{
//pad the function name
$padLen = $this->functionPadding - strlen($function);
if($padLen > 0)
$function = substr(md5(rand()),0,$padLen+rand(0,10)).'_'.$function;
else
$function = '_'.$function;
$function = base64_encode($this->rc4($this->rc4_key, $function));
$session_id = session_id();
}
else
$session_id = 'null';
if($inputType == 'JsFunction')
$all_commands .= "saja.RunPhp('$function(".$this->parseArgs($args, 'PHPJSIN').");','$targetId','$action','$targetProperty',this,'$session_id');";
else
$all_commands .= "saja.RunPhp('$function(".$this->parseArgs($args, 'PHP').");','$targetId','$action','$targetProperty',this,'$session_id');";
}
}
else
{
list($target, $action) = $this->texplode(',', $targets);
list($targetId, $targetProperty) = $this->texplode(':', $target);
if(!$action) $action = 'r';
if(!$targetProperty) $targetProperty = 'innerHTML';
$all_commands .= "saja.Put('".$this->parseArgs($functions, 'VAR')."','$targetId','$action','$targetProperty');";
}
}
return $all_commands;
}
################################################################################
#
# SAJA RESPONSE FUNCTIONS
#
//execute raw javascript code
function rawjs($js)
{
$this->actions .= $this->sajasplit()."$js;";
}
//adds a new action to the queue
function exec($action)
{
$this->actions .= $this->sajasplit().$this->run($action);
}
//used for placing complex / long text into an element
function text($content, $target)
{
list($target, $action) = $this->texplode(',', $target);
list($targetId, $targetProperty) = $this->texplode(':', $target);
if(!$action) $action = 'r';
$action = "saja.Put(unescape('".rawurlencode($content)."'),'$targetId','$action','$targetProperty');";
$this->actions .= $this->sajasplit().$action;
return $action;
}
//hide an element
function hide($element)
{
$this->actions .= $this->sajasplit()."saja.Put('none','$element','r','style.display');";
}
//show an element
function show($element)
{
$this->actions .= $this->sajasplit()."saja.Put('','$element','r','style.display');";
}
//set style for an element
function style($element, $styleString)
{
$this->actions .= $this->sajasplit()."saja.SetStyle('$element', '$styleString');";
}
//return response actions to javascript for execution
function send()
{
return $this->sajasplit().$this->actions;
}
################################################################################
#
# REQUEST HANDLING
#
function runFunc($php, $validFunctions)
{
list($php, $session_id) = explode('~|session_id|~', $php);
if($session_id)
session_start($session_id);
else
session_start();
if($_SESSION['SAJA_HTTP_KEY'])
$php = $this->rc4($_SESSION['SAJA_HTTP_KEY'], urldecode($php));
list($function, $args) = explode('(',str_replace(' ','',trim($php)));
list($args) = explode(')', $args);
$args = explode(',',$args);
foreach(array_keys($args) as $key)
{
if(strstr(urldecode($args[$key]),'array('))
$args[$key] = urldecode(trim($args[$key],'\''));
else
$args[$key] = '\'' . str_replace('\'', '\\\'', str_replace('\\', '\\\\', urldecode(trim($args[$key],'\'')))) . '\'';
}
$args = implode(',', $args);
if($_SESSION['SAJA_RC4_KEY'])
{
$function = $this->rc4($_SESSION['SAJA_RC4_KEY'], base64_decode($function));
list($_,$function) = explode('_', $function, 2);
}
if(in_array($function, $validFunctions))
{
eval("echo $function($args);");
}
else
echo "ERROR: Function [$function] not validated.";
}
//RC4 Encryption from http://sourceforge.net/projects/rc4crypt
function rc4($pwd, $data)
{
$pwd_length = strlen($pwd);
$data_length = strlen($data);
for ($i = 0; $i < 256; $i++){
$key[$i] = ord($pwd[$i % $pwd_length]);
$box[$i] = $i;
}
for ($j = $i = 0; $i < 256; $i++){
$j = ($j + $box[$i] + $key[$i]) % 256;
$tmp = $box[$i];
$box[$i] = $box[$j];
$box[$j] = $tmp;
}
for ($a = $j = $i = 0; $i < $data_length; $i++){
$a = ($a + 1) % 256;
$j = ($j + $box[$a]) % 256;
$tmp = $box[$a];
$box[$a] = $box[$j];
$box[$j] = $tmp;
$k = $box[(($box[$a] + $box[$j]) % 256)];
$cipher .= chr(ord($data[$i]) ^ $k);
}
return $cipher;
}
}
?>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -