PHP - 自定义.zip文件下载前?

时间:2012-11-20 01:50:42

标签: php download customization

所以我正在创建一个脚本,我想学习如何限制在一个域上使用,但我需要在下载之前修改脚本。我的问题是,我想要一个由他们网站的用户填写的$ _GET变量。使用file_put_contents或其他东西自定义脚本,然后下载修改后的脚本..我该怎么做?它需要Javascript和PHP,还是只需要Javascript?我不知道该怎么做。可以找到修改下载的示例here

1 个答案:

答案 0 :(得分: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;
}