开发者

PHP: a short cut for isset and !empty?

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 abo开发者_如何学Cve 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 a 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 variables to handle.

Is there any default PHP function to 'shorten' the process above? Or do I have to write a user-defined function to handle this?

Or maybe there is another way to do this?

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.


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.


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');


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.


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.


+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.


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.


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.


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.


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;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜