目前,我有以下代码:
if(isset($_GET['mid']) && !empty($_GET['mid'])) {
$mid = $_GET['mid'];
if(is_numeric($mid) && $mid > 0) {
if(isset($_GET['op']) && !empty($_GET['op'])) {
$op = $_GET['op'];
if($op == 'info') {
}
if($op == 'cast') {
}
}
}
}
但我觉得if语句中的if语句太复杂了......等等......
你会以不同的方式处理它吗?你会如何使它变得更简单?
[编辑]接受的答案:
好吧,我已经学到了一些我不知道的小细节和新的PHP函数。我认为没有一种正确的方式来完成我的要求。我显然以错误的方式使用了一些PHP函数,我将解决这个问题。
在我看来,像这样的输入应该使用PHP过滤器功能进行验证/清理,因此我将 Arkh的答案标记为已接受。
然而,对于一个特定的大学项目(PHP代码完全不相关),我将使用他的答案和 Tatu的帮助函数的想法。但是对于一个不同的项目,我会将他的答案与 Ignacio的类的想法混合使用,因为它看起来更好,更有条理。
答案 0 :(得分:11)
我会将filter_input与FILTER_SANITIZE_NUMBER_FLOAT过滤器一起用于mid。这样的事情:
$mid = filter_input(INPUT_GET, 'mid', FILTER_SANITIZE_NUMBER_FLOAT);
$op = filter_input(INPUT_GET, 'op');
if($mid > 0){
switch($op){
case 'info':
// Some code
break;
case 'cast':
// Some more code
break;
default:
break;
}
}
答案 1 :(得分:5)
我会编写一个带有索引名称的函数,并返回$_GET
中的值或抛出异常。
那,或将其封装在类似于以下的类中:
#$_GET = array('name' => 'Ignacio', 'foo' => '42');
class Get
{
public static function string($name)
{
if (isset($_GET[$name]))
{
return $_GET[$name];
}
else
{
throw new Exception(sprintf('Unknown GET parameter "%s"', $name));
}
}
public static function int($name)
{
$val = Get::string($name);
$ret = filter_var($val, FILTER_VALIDATE_INT);
if ($ret != $val)
{
throw new Exception(sprintf('Invalid int GET parameter "%s"', $name));
}
return $ret;
}
}
echo Get::string('name') . "\n";
echo Get::int('foo') . "\n";
#echo Get::int('name') . "\n";
#echo Get::int('age') . "\n";
答案 2 :(得分:4)
empty
已检查变量isset
。is_numeric
有点冗长,因为您还要检查0
。我会这样做:
$mid = empty($_GET['mid']) ? 0 : (int)$_GET['mid'];
// casting as an integer will
// make undesirable strings = 0
if ($mid > 0 && !empty($_GET['op'])) {
switch($_GET['op']) {
case 'info':
break;
case 'cast':
break;
default:
break;
}
}
如果您需要将$_GET['op']
存储在变量中以供日后使用,您可以在切换块之前执行此操作,但除非需要,否则我不会这样做。
答案 3 :(得分:3)
我喜欢创建一个实现ArrayAccess的InputFilter类的想法。这是更面向对象和更可定制的,因为您可以随意添加方法进行自定义,并使用相同的主过滤对象。
$get = new InputFilter($_GET);
echo $get->value_integer('variable_name');
这也很好,它可以重复使用$ _POST等等。你只需要做$post = new InputFilter($_POST);
之类的事情。而且,您也可以将它用于其他输入源。
或者,如果你有一个足够新的php版本,你可以稍后实现filter_input(),如@Arkh所建议的那样。 IMO,拥有自己的课程,感觉更可重复和耐用。
<?php
// empty for now, fill in later if desired
class InputFilterException extends Exception {}
/*
* Use the ArrayAccess interface as a template.
*
* Usage examples:
* $controller->get = InputFilter($_GET);
* echo $controller->get->value_string_html('variable');
* $controller->post = InputFilter($_POST);
* echo $controller->get->value_integer('variable');
*/
class InputFilter implements ArrayAccess {
protected $data;
function __construct( $data ) {
if( !is_array($data) ) {
throw new InputFilterException ("Only arrays are allowed here");
}
$this->data = $data;
}
// do not actually use these
function __get( $offset ) {
throw new InputFilterException( "Don't use as an array, use functions ->string() ->int() etc: ['" . $offset . "']" );
}
function __set( $offset, $value ) {
throw new InputFilterException( "Don't modify directly: ['" . $offset . "'] = \"" . $value . "\"" );
}
// implement ArrayAccess
function offsetExists( $offset ) {
return isset( $this->data[$offset]) );
}
function offsetSet( $offset, $value ) {
$this->data[$offset] = $value;
}
function offsetUnset( $offset ) {
unset( $this->data[$offset] );
}
function offsetGet( $offset ) {
throw new InputFilterException ("Don't use this object as an array, but were an array : ". $offset);
}
protected function getValue( $offset ) {
if( is_array($this->data[$offset]) ) {
throw new InputFilterException ("must use the asArray() function");
}
return $this->data[$offset];
}
function data_count() {
return count($this->data);
}
public function set_value( $offset, $data ) {
$this->offsetSet( $offset, $data );
}
// get an array *in* the data
public function asArray($offset) {
if( !is_array ($this->data[$offset]) ) {
throw new InputFilterException("only use asArray() for arrays");
}
return new Filter( $this->data[$offset] );
}
// validators...
function is_set( $offset ) {
return $this->offsetExists($offset);
}
function is_empty( $offset ) {
return $this->is_set($offset) && strlen($this->data[$offset]) == 0;
}
function is_numeric( $offset ) {
return $this->is_set($offset) && is_numeric($this->data[$offset]);
}
function is_integer( $offset ) {
if( !$this->is_set($offset) ) {
return false;
} elseif( is_numeric($this->data[$offset]) ) {
$int_value = intval($this->data[$offset]);
return $int_value == $this->data[$offset];
} elseif( strlen($this->data[$offset]) == 0 ) {
return true;
}
return false;
}
function is_array( $offset ) {
return $this->is_set($offset) && is_array($this->data[$offset]);
}
// return data formatted
function value_string( $offset ) {
return $this->getValue($offset);
}
function value_string_html( $offset ) {
return htmlentities( $this->getValue($offset), null, 'UTF-8' );
}
function value_integer( $offset ) {
return intval( trim($this->getValue ($offset)) );
}
function value_numeric( $offset ) {
return doubleval($this->getValue ($offset));
}
function value_alphanumeric( $offset ) {
return preg_replace("*[^A-Za-z0-9]*", "", $this->getValue ($offset));
}
function value_unfiltered( $offset ) {
return $this->getValue( $offset );
}
}
?>
答案 4 :(得分:2)
你可以做一个辅助功能:
function getvar($var) {
return isset($_GET[$var]) && !empty($_GET[$var]) ? $_GET[$var] : false;
}
$mid = getvar('mid');
$op = getvar('op');
if(is_numeric($mid) && $mid > 0) {
if($op == 'info') {
}
if($op == 'cast') {
}
}
这会使你的代码更清晰,但你自己的代码就没事了。
答案 5 :(得分:2)
你可以做的是定义一个过滤函数(已经存在于PHP&gt; = 5.2中),该过滤函数会根据一个变量过滤变量,无论是数字,字符串还是更多依赖根据您的要求。
function myfilter($variable, $type) {
switch($type){
case 'numeric':
//check for numbers
return the number or false based on check
break;
case 'alphanumberic':
//check for alphanumeric
return the text or false based on check
break;
}
}
然后使用此函数过滤使用$ _GET
获得的值$foo = myfilter($_GET['foo'], 'numeric');
$bar = myfilter($_GET['bar'], 'alphanumeric');
答案 6 :(得分:0)
我会做类似下面的事情。或多或少。但是你也可以使用过滤器来处理这些事情。你也可以关闭警告,只使用empty()而不用担心第一块中的isset。
function checkVar($var)
{
if(isset($var) && !empty($var)) {
return true;
}
return false;
}
function checkID($id){
if(checkVar($id) && is_numeric($id) && $id > 0) {
return $id;
}
return false;
}
if($mid = checkID($_GET['mid'])) {
if(checkVar($_GET['op'])) {
switch($_GET['op']) {
case 'info':
break;
case 'cast':
break;
}
}
}
答案 7 :(得分:0)
看起来有点复杂。但看起来你想要测试很多边缘条件。但是,有一些方法可以统一这个过程。我正在使用wrapper class:
if ($_GET->int["mid"]) {
if ($_GET->in_array("op", "info,cast")) {
但是可以定义一个自定义方法,它结合了所有的isset和is_numeric或任何检查。
答案 8 :(得分:0)
我喜欢以下关于整数变量的方法:
private function _extract_int_val($val) {
if ( isset($val) ) {
$number = esc_sql($val);
if ( is_numeric($number) && $number >= 0) {
return (int) $number;
}
}
}
答案 9 :(得分:-1)
这没什么不对。嵌套的if语句绝对没问题。 您可以使用filter。