簡體   English   中英

在代碼中使用eval(),你會如何避免它?

[英]Using eval() in the code, and how would you avoid it?

在我的代碼中,我想嘗試獲取$ _POST或$ _GET變量,並在請求一次后立即取消它們。

此函數返回使用的方法,這很簡單。 不幸的是,我不能簡單地直接或通過引用返回$ _POST或$ _GET變量,因為我無法取消它們(通過引用取消設置不起作用)。 所以,我返回變量名稱:

class Input {
  protected function interface_get($method): string {
    switch ($method) {
      case 'post':
        return '_POST';
        break;
      case 'get':
        return '_GET';
        break;
      case 'ajax':
        // Not supported yet.
        return null;
        break;
      default:
        return null; // returns '_GET' or '_POST'
    }
  }
  public function fetch_eval(string $method, ?string $request = null) { // ...fetch('post', 'username')
    if ($request !== null) {
      $request = '[\'' . $request . '\']'; // "['username']"
    }
    $request = $this->interface_get($method) . $request; #"$_POST['username']"
    eval('$return = $' . $request . ';'); #$return = $_POST['username'];
    eval('unset($' . $request . ');'); #unset($_POST['username']);
    return $return;
  }
  public function fetch_varvar(string $method, ?string $request = null) {
    $interface = $this->interface_get($method); #$interface = '_POST';
    if ($request === null) {
      $return = (${$interface});
      unset(${$interface});
    } else {
      $return = ${$interface}; #"Notice:  Undefined variable: _POST in [...]"
      $return = ${$interface}[$request]; #"Warning:  Illegal string offset 'email' in [...]"
      unset($interface[$request]);
    }
    return $result;
}
}
// set $_POST = ['email'=>'spam@me'];
$in = new Input();
echo $in->fetch_eval('post', 'email'); #'spam@me'
// $_POST = [];

// set $_POST = ['email'=>'spam@me']; again
echo $in->fetch_varvar('post', 'email'); #'Notice:  Undefined variable: _POST [...]'

有趣的部分是處理輸出。 這是我的fetch函數,我認為最簡單但最臟的方法:

我嘗試使用變量變量,它在測試腳本中工作:

// $_POST = [0 => 5, 'bob' => 5];
$e = '_POST';
$var = 'bob';
echo ${$e}[$var]; #5
unset(${$e}[$var]);
echo ${$e}[$var ]; #NOTICE Undefined index: bob on line number 22
// Works as expected.

但它在我的腳本中不起作用( Undefined variable: _POST [...] 。)。 我想也許原因是它在課堂上,但無論如何我無法解決它。 更重要的是,如果你把這些功能放在課堂之外並刪除$this-> -es,它們就可以了! 但不是在課堂上。

如果有人能告訴我為什么我的后一個代碼不起作用,我將不勝感激。 但無論如何,你會說使用eval()是合理的嗎? 我知道有些人無論如何都會避免它。 顯然,在這種情況下,它開辟了一個非常大的漏洞,所以我寧願完全避免它而不是消毒和擔心。

我想將interface_get()作為一個單獨的函數,但如果需要,我也可以在fetch()復制它,我想。

非常感謝你提前。

@Syscall和@Ignacio Vazquez-Abrams在評論中提供了問題的答案。

根據PHP文檔( https://php.net/manual/en/language.variables.superglobals.php ):

Superglobals不能用作函數或類方法中的變量變量。

這就是為什么它不在Input類中工作。 為了它的工作,我不得不像這樣使用$ GLOBALS變量:

public function fetch(string $method, ?string $request = null) {
    $interface = $this->interface_get($method); #$interface = '_POST';
    if ($request === null) {
        $return = $GLOBALS[$interface];
        unset($GLOBALS[$interface]);
    } else {
        $return = $GLOBALS[$interface][$request];
        unset($GLOBALS[$interface][$request]);
    }
    return $return;
}

這段代碼有效。 非常感謝您的投入。 可能有更好或更優雅的方式來實現我想要的。 在這種情況下,總是歡迎進一步的投入。

您可以使用$GLOBALS[$interface]來獲取數據。

假設總是定義$_POST$_GET ,您可以檢查是否在之前定義了鍵並取消設置,以避免出現警告。

public function fetch(string $method, ?string $request = null) {
    $interface = $this->interface_get($method); #$interface = '_POST';
    if ($request === null) {
        $result = $GLOBALS[$interface];
        unset($GLOBALS[$interface]);
        return $result;
    }
    if (isset($GLOBALS[$interface][$request])) {
        $result = $GLOBALS[$interface][$request];
        unset($GLOBALS[$interface][$request]);
        return $result;
    }
    return null;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM