检查$ _REQUEST变量的更好方法

时间:2012-10-17 11:44:55

标签: php request

$p = (isset($_REQUEST["p"])?$_REQUEST["p"]:"");

这是我在php代码中经常使用的常用行。我总是假设有更好的(小而快的)写同样的方法吗?

8 个答案:

答案 0 :(得分:17)

创建自己的功能:

function getIfSet(&$value, $default = null)
{
    return isset($value) ? $value : $default;
}

$p = getIfSet($_REQUEST['p']);

没有其他清洁解决方案。

答案 1 :(得分:7)

你想要更短的时间吗?

当然,如果您使用时间访问一个请求值,您应该在某处创建一个函数然后使用它:

function reqVal( $val, $default = "", $no_sql = true )
{
    $var = isset( $_REQUEST[$val] ) ? $_REQUEST[$val] : $default;
    $var = $no_sql ? nosql( $var ) : $var;
    return $var;
}

function getVal( $val, $default = "", $no_sql = true )
{
    $var = isset( $_GET[$val] ) ? $_GET[$val] : $default;
    $var = $no_sql ? nosql( $var ) : $var;
    return $var;
}

function postVal( $val, $default = "", $no_sql = true )
{
    $var = isset( $_POST[$val] ) ? $_POST[$val] : $default;
    $var = $no_sql ? nosql( $var ) : $var;
    return $var;
}

现在添加sql incjection check:

function nosql( $var )
{
    if ( is_array( $var ) ) {
        foreach ( $var as $key => $elem ) $var[$key] = nosql( $elem );
    } else if ( $var === null ) {
        return null;
    } else {
        if ( get_magic_quotes_gpc() ) $var = stripslashes( $var );
        $var = mysql_real_escape_string( $var );
    }
    return $var;
}

并且像这样访问它总是很简单:

$p = reqVal( 'p', 0 );
$p = getVal( 'p', 'something', false );
$p = postVal( 'p' ); // or just forget the 2nd and 3rd parameter

答案 2 :(得分:4)

编辑: PHP 7添加了一个空合并运算符(“??”)

$p = $_REQUEST["p"] ?? '';

https://www.php.net/manual/en/migration70.new-features.php


ORIGINAL:

如果您想要更短的内容,并且满足空(字符串)默认值,则以下工作:

$p = @$_REQUEST['p'];

@是错误抑制运算符,如果未设置该值,将使表达式不发出警告。

http://www.php.net/manual/en/language.operators.errorcontrol.php

答案 3 :(得分:2)

我通常利用PHP松散类型的事实,并且只做:

$p = (string) $_REQUEST['p'];

这样,即使未设置$_REQUEST['p'],空字符串仍会存储到$p中。请记住,这只有在您的错误处理程序忽略通知时才有效,因为访问未设置的密钥会触发“E_NOTICE”行undefined index

答案 4 :(得分:0)

这确实很常见,我想知道在PHP中没有本机方式。大多数开发人员编写自己的函数来安全地从数组中读取。

/**
 * Gets the value associated with the specified key from an array.
 * @param array $array The array to search for the key.
 * @param mixed $key The key of the value to get.
 * @param mixed $default The default value to return, if the
 *   specified key does not exist.
 * @return mixed Value that is associated with the specified
 *   key, or the default value, if no such key exists.
 */
function getValueFromArray($array, $key, $default = null)
{
  $containsKey = isset($array[$key]);
  if ($containsKey)
    return $array[$key];
  else
    return $default;
}

/**
 * Gets the value associated with the specified key from an array.
 * @param array $array The array to search for the key.
 * @param mixed $key The key of the value to get.
 * @param mixed $value Retrieves the found value, or is set to null
 *   if the key could not be found.
 * @return bool Returns true if the key could be found, otherwise false.
 */
public function tryGetValueFromArray($array, $key, &$value)
{
  $containsKey = isset($array[$key]);
  if ($containsKey)
    $value = $array[$key];
  else
    $value = null;
  return $containsKey;
}

答案 5 :(得分:0)

您可以在用户贡献的便笺部分中找到许多不同解决方案的示例http://php.net/manual/en/function.isset.php

试试这个:

function get_if_set( $varname, $parent=null ) { 
    if ( !is_array( $parent ) && !is_object($parent) ) { 
        $parent = $GLOBALS; 
    }
    return array_key_exists( $varname, $parent ) ? $parent[$varname] : null; 
} 

答案 6 :(得分:0)

将现有代码包装在函数中的答案是好的 - 如果你有很多代码,它们确实可以整理代码。

然而,更好的解决方案是在开始之前根据一组预期值清理整个请求数组。

例如:

function sanitiseRequest() {
    $expected = array(
        'p' => '',
        'id' => 0,
        //etc
    );

    //throw away any input that wasn't expected...
    foreach($_REQUEST as $key=>$value) {
        if(!isset($expected[$key]) { unset $_REQUEST[$key]; }
    }
    //and for any expected values that weren't passed, set them to the defaults.
    foreach($expected as $key=>$defvalue) {
        if(!isset($_REQUEST[$key]) { $_REQUEST[$key] = $defvalue; }
    }
}

然后只需在代码开头添加对此函数的调用,您就不必担心在代码中的其他位置执行isset($_REQUEST[..])

可以扩展此概念以强制传入的参数也是正确的数据类型,或者您可能想要执行的任何其他数据清理。这可以让您完全确信输入的数据是按照您的预期填充的。

希望有所帮助。

答案 7 :(得分:0)

这个适合我。 而且你不必写两次名字。 如果已经设置,它将不会更改var。因此,使用register_globals进行旧应用程序的快速n脏转换是安全的。

if (appOpenedByPushNotification) {
  UIViewController* A = ... ;
  UIViewController* B = ... ;
  UIViewController* C = ... ;
  UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:A]; // you might be able to just do [UINavigationController new] but I've never tried that.
  [nav setViewControllers:@[A, B, C] animated:NO];
  // show the nav however you want, maybe like this:
  self.window.rootViewController = nav;
}