PHP: a short cut for isset and !empty?

2020-06-04 04:36发布

问题:

I wonder if there any better ideas to solve the problem below,

I have a form with a number of input fields, such as,

<input name="pg_title" type="text" value="" />
<input name="pg_subtitle" type="text" value="" />
<input name="pg_description" type="text" value="" />
<input name="pg_backdate" type="text" value="" />
etc

But sometimes don't need certain input fields above in my form, for instance, I only need the page title for my db injection,

<input name="pg_title" type="text" value="" />
 etc

And I have another php page to handle the $_POST data,

$pg_title = null;
$pg_subtitle = null;
$pg_description = null;
$pg_backdate = null;

 if(isset($_POST['pg_title']) && !empty($_POST['pg_title']) ) $pg_title = $_POST['pg_title'];
 if(isset($_POST['pg_subtitle']) && !empty($_POST['pg_subtitle']) ) $pg_subtitle = $_POST['pg_subtitle'];
 if(isset($_POST['pg_description']) && !empty($_POST['pg_description']) ) $pg_description = $_POST['pg_description'];
 if(isset($_POST['pg_backdate']) && !empty($_POST['pg_backdate']) ) $pg_backdate = $_POST['pg_backdate'];

Every time I will have to check if the $_POST of certain input field is set and not empty, otherwise its variable will be set to null, so that I won't inject an empty space into my db.

I find the isset and !empty in the if-condition are very repetitive when I have a long list of variable to handle.

Is there any default php function to 'shorten' the process above? Or do I have to write an user define function to handle this?

Or maybe there is another way doing this?

Thanks.

EDIT:

Thanks so much guys for the help.

Just some extra code in my php page that handle the $_POST data,

$sql = "
    UPDATE root_pages
    SET 
        pg_url = ?, 
        pg_title = ?,
        pg_subtitle = ?,
        pg_backdate = ?,
        pg_description = ?,     
        ...
        updated_by = ?
    WHERE pg_id = ?
    ";

    $result = $connection->run_query($sql,array(
        $pg_url, 
        $pg_title,
        $pg_subtitle,
        $pg_backdate,
        $pg_description,        
        ...
        $pg_id
        ));

as you see that $pg_subtitle, $pg_backdate, $pg_description, etc always present in my query. so if I get $pg_subtitle = '' instead of $pg_subtitle = null when there is no data in it, my db record will have an empty space for that column.

Thanks :-)

回答1:

You can use a simple function

function post_value_or($key, $default = NULL) {
    return isset($_POST[$key]) && !empty($_POST[$key]) ? $_POST[$key] : $default;
}

Then use:

$pg_title = post_value_or('pg_title');
// OR with a default
$pg_title = post_value_or('pg_title', 'No Title');


回答2:

isset && !empty is redundant. The empty language construct is basically shorthand for !isset($foo) || !$foo, with !empty being equivalent to isset($foo) && $foo. So you can shorten your code by leaving out the isset check.

A much simpler way is:

$values = array('pg_title' => null, 'pg_subtitle' => null, …);
$values = array_merge($values, $_POST);

// use $values['pg_title'] etc.

If you don't want your default null values to be overwritten by falsey values, e.g. '', you can do something like this:

$values = array_merge($values, array_filter($_POST));

Just be aware that '0' is falsey as well.



回答3:

empty($var) is an abbreviation for !( isset($var) && $var ).

So !empty($_POST['...']) will be sufficient for your situation — the isset call you have currently is redundant.



回答4:

User-defined function, I 'm afraid. But they come out short enough. I have one lying around somewhere if you want to take a look, but it's really trivial as you can imagine.

Update:

Here's one I found:

define('PARAM_INT', 0);
define('PARAM_STR', 1);

function get_param($name, $default = null, $type = PARAM_INT) {
    $value = $default;

    if (isset($_POST[$name])) {
        $value = $_POST[$name];
    }
    else if (isset($_GET[$name])) {
        $value = $_GET[$name];
    }

    switch($type) {
        case PARAM_INT:
            $value = (int)$value;
            break;
        case PARAM_STR:
            break;
        default:
            // error your heart out here
    }
    return $value;
}

Of course now all the cool kids do it with filter_var, but the idea is the same.



回答5:

+1 for array_merge() but I think that nevertheless short form for:

if (isset($_POST['some_var']) and !empty($_POST['some_var'])) $some_var = $_POST['some_var'];
else $some_var = NULL;

should be:

$some_var = $_POST['some_var'] ? $_POST['some_var'] : NULL;

yes, it causes "undefined index" notice, but it checks for both existance and emptiness

EDIT: and returns NULL of course, as OP asked.

During a small research, I've found an interesting "Control Flow Function" for this case, I've never used before: NULLIF()

So you can perform this task without PHP. Just wrap all variables in it:

NULLIF('".$_REQUEST['some_var']."', '')

in your query instead of '".$_REQUEST['some_var']."'

If variable is empty or doesn't exist it will be NULLIF('', '') as far as '' == '' it will return NULL. Otherwise it will return first arg == your variable.



回答6:

Consider using the available-by-default filter extension's filter_input function. You'll avoid the missing index Notice and get data sanitization at the same time.



回答7:

I'm always making myself unpoular with that. But the best approach is to get over the micro optimization mantra and use the syntax construct which was devised for that @.

Factually I'm lying. I'm all too often using isset() myself. (But at least I know it's not very bright.) And for new projects I'm now using object-oriented superglobals, which combine filtering and implicit isset tests into $_POST, $_GET, $_REQUEST wrappers. $_REQUEST->ascii["title"] or $_GET["raw"] don't bring up debug messages anymore.



回答8:

This function check if variable is set, is not empty, eventually if has any value.

/**
 * @param  var - testing variable
 * @param  value
 * @return boolean
 */
function is(&$var, $value = null){
  if(!is_null($value)){ return IsSet($var) && $var == $value; }
  return IsSet($var) && !empty($var);
}

echo $_GET['id'];             // this produce Warning
echo is($_GET['id'])?'1':'0'; // return false
echo $_GET['id'];             // after first using function is(), will not be produce Warning!!!

is($_GET['id']);              // return false
IsSet($_GET['id']);           // return false
$_GET['id'] = 7;
is($_GET['id'], 7);           // return true;


回答9:

I do not have enough rep to comment. However, the suggestion that vladkras made to use:

$some_var = $_POST['some_var'] ? $_POST['some_var'] : NULL;

is not E_ALL compliant. You should be checking array keys before accessing them using either empty() or isset() as others have suggested. Especially for user input.

Also, his second suggestion to use the MySQL function "NULLIF()" as in the following manner:

NULLIF('".$_REQUEST['some_var']."', '')

is even worse. Inserting unsanitized user input directly into a SQL query is a primary vector for a SQL injection attack.



回答10:

It is an interesting question and I await the answers.

However, little trick, you can do inline :

$pg_title = isset($_POST['pg_title']) && !empty($_POST['pg_title']) ? $_POST['pg_title'] : null;


标签: php function