所以我正在制作一个脚本,我想学习如何限制在一个域上的使用,但我需要在下载之前修改脚本。我的问题是,我想使用他们网站的用户填写的 $_GET 变量。使用 file_put_contents 或其他东西自定义脚本,然后下载修改后的脚本。我该怎么做?它需要 Javascript 和 PHP,还是只需要 Javascript?我不知道该怎么做。可以在此处找到修改下载的示例
问问题
356 次
1 回答
2
所以,如果我理解正确,用户用 var 填写一些表单(我们称之为 $var),然后单击表单的提交按钮来下载文件(我们称之为“myscript.php”)。
您想编辑“myscript.php”并在用户下载之前将 $var 放入该脚本中。这个假设正确吗?
为此,您需要预先准备好脚本,在某处放置一个占位符,然后在用户下载文件之前,更改预期代码块的占位符。或者,如果相关,您可以替换<?php
代码的第一个标签。
小例子:
myscript1.php
<?php
$varb = 'a string with DEFAULT VAR inside just to test';
//Block of code goes here
//{%%DEFAULT VAR%%}
print $var;
表单调用的代码:
<?php
$path = 'myscript1.php';
$file = file_get_contents($path);
$var = $_GET['var'];
$block = '
// valid php code that you put inside script (without <?php)
// Alternatively you can grab the block of code
// from a file with file_get_contents
$var = ' . $var . ';';
$file = str_replace('//{%%DEFAULT VAR%%}', $var, $file);
这是一个更完整(和复杂)的例子......
myscript2.php
<?php
$var = '{%%DEFAULT VAR%%}';
$varb = 'another string with DEFAULT VAR inside just to test';
print $var;
下载脚本(由表单调用)
<?php
$form =
'<html>
<head></head>
<body>
<form action="">
<span>myVar</span><input type="text" id="var" name="var"/><br/>
<input type="submit" value="download file"/>
</form>
</body>
</html>';
if (isset($_GET['var'])) {
$var = $_GET['var'];
$path = 'myscript2.php';
$file = file_get_contents($path);
// PART 1
/*
* Tokenizer Approach (read http://php.net/manual/en/book.tokenizer.php)
* Splits a php file into an Array with tokens (like the ZEND Engine Parser does)
* Usefull for parsing and validating the PHP file
* In this case we're just cheking if the script has
* $var = {%%DEFAULT VAR%%}; somewhere but you can implement a more complex code to check
* complete statements or instructions!!! This is just for example's sake!
* Skip this part if you don't need to validate the script
*/
$tokens = token_get_all($file);
if (!validatePHPScript($tokens)) {
throw new Exception("script didn't pass validation");
}
//END PART 1
// PART 2
/*
* The actual string replacement via str_replace
* It actually just replaces a placeholder for anything
* you want, in this case the $_GET['var'] value
* You can actually replace a placeholder for a complete
* block of code: just put the placeholder in the part you want
* to insert and then comment it. #{‰‰PLACEHOLDER_NAME%%}
* Then replace the placeholder with the comment tag
*
*/
$file = str_replace('{%%DEFAULT VAR%%}', $var, $file);
// END PART 2
//PART 3
/*
* Serve the file to download through headers
*/
header('Content-type: text/plain');
header('Content-disposition: attachment; filename=myscript.php');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . strlen($file));
ob_clean();
flush();
print $file;
// END PART 3
} else {
print $form;
}
验证函数示例:
//Validation example
function validatePHPScript(array $tokens)
{
$max = count($tokens);
$var_check = false;
$operator_check = false;
$string_check = false;
$semicolon_check = false;
// loop through all $tokens
for ($i = 0; $i < $max; ++$i) {
// only look for variables (tokens with type T_VARIABLE)
if (is_array($tokens[$i]) && $tokens[$i][0] === T_VARIABLE) {
// LOOK for a variable named $var
if ($tokens[$i][1] === '$var') {
// Found $var
$var_check = true;
// let's check if its an assignment statement
// by looping through the remaining code until we find a colon
for ($ii = $i +1; $ii < $max; ++$ii) {
// Look for the operator =
if ($tokens[$ii] === '=') {
$operator_check = true;
// Look for the string and check if it corresponds to the value
// we're going to replace
} else if ($operator_check && is_array($tokens[$ii]) && $tokens[$ii][0] === T_CONSTANT_ENCAPSED_STRING && $tokens[$ii][1] === "'{%%DEFAULT VAR%%}'") {
$string_check = true;
// Look for the statement end token (semicolon)
} else if($string_check && $tokens[$ii] === ';') {
$semicolon_check = true;
break;
}
}
// All checks passed so we don't need to loop anymore
if ($var_check && $operator_check && $string_check && $semicolon_check) {
return true;
} else {
// reset checks
$var_check = false;
$operator_check = false;
$string_check = false;
$colon_check = false;
}
}
}
}
return false;
}
于 2012-11-20T15:42:12.387 回答