$p = (isset($_REQUEST["p"])?$_REQUEST["p"]:"");
This is the common line I usually use in my php code. I always assume is there a better(small and faster) way to write the same ?
Create your own function :
function getIfSet(&$value, $default = null)
{
return isset($value) ? $value : $default;
}
$p = getIfSet($_REQUEST['p']);
There's no other clean solution.
EDIT:
PHP 7 adds a null coalescing operator ("??")
$p = $_REQUEST["p"] ?? '';
https://www.php.net/manual/en/migration70.new-features.php
ORIGINAL:
if you want something shorter, and are content with an empty (string) default value, the following works:
$p = #$_REQUEST['p'];
# is the error-suppression operator and will keep the expression from giving a warning if the value is not set.
http://www.php.net/manual/en/language.operators.errorcontrol.php
How more shorter do you want it?
Of course, if you are using this every time you access a request value, you should create a function somewhere and then use that:
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;
}
Now add the 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;
}
And access it always simple like this:
$p = reqVal( 'p', 0 );
$p = getVal( 'p', 'something', false );
$p = postVal( 'p' ); // or just forget the 2nd and 3rd parameter
The answers that wrap your existing code in a function are good - they do indeed tidy up the code if you've got a bunch of them.
However the better solution is to sanitize your entire request array based on a set of expected values before you start.
For example:
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; }
}
}
Then simply add a call to this function at the start of the code, and you won't need to worry about doing isset($_REQUEST[..]) anywhere else in your code.
This concept can be expanded to force the incoming arguments to be the correct data type as well, or any other data cleansing you may want to do. This can give you complete confidence that the incoming data is populated as you expect.
Hope that helps.
I usually take advantage of the fact that PHP is loosely typed and simply do:
$p = (string) $_REQUEST['p'];
This way, even if $_REQUEST['p'] is not set, an empty string still gets stored into $p. Keep in mind that this only works if your error handler ignores notices, as accessing an unset key will trigger an E_NOTICE along the lines of "undefined index".
This is indeed so common, that i wonder there is no native way of doing it in PHP. Most developers write their own function to read safely from an array.
/**
* 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;
}
You can find many examples of different solutions here http://php.net/manual/en/function.isset.php in the User Contributed Notes section.
Try this:
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;
}
This one works well for me.
And you don't have to write the name twice.
It won't change the var if it is already set. So it is safe to use for quick n dirty conversion of old application using register_globals.
function getIfSet($key, $default = null)
{
global $$key;
if(!isset($$key)){
if(isset($_REQUEST[$key])){
$$key=$_REQUEST[$key];
}else{
if(!is_null($default)){
$$key = $default;
}
}
}
}
function getIfSetArray($list){
foreach($list as $item){
getIfSet($item);
}
}
getIfSet('varname');
getIfSetArray(['varname_1','varname_2']);
echo $varname;
echo $varname_1;
Related
I wanted to make function with this possible argument:s
leFunction ((string) $type,(string) $data) , this was simple, switch defining $return by given type (doing whatever switch can possibly do with $data). Eg I can send year 1865 as $data and if $type is "fromYear" and $data is_numeric, it'll do whatever it's supposed to do.
leFunction ((string) $type,(array) $data) , this is where it gets tricky. Idea was that with this second option I can pass same args as ("fromYear", array("year" => 1865, ....) ) then check if is_numeric($data["year"]) and continue with same code.
But when I combined both pieces together I got this not so great if:
if (is_numeric($data) || (is_array($data) && isset($data["year"])))
Then I replaced second part with function from parent obj :
if (is_numeric($data) || is_numeric($this->setIfGet("year", $data)))
func:
/**
* #param $needle string key
* #param $haystack array source
* #param bool $null make true if value of $needle could be null
* #return bool
*/
protected function setIfGet($needle, $haystack, $null = false)
{
return (isset($haystack[$needle])) ? $haystack[$needle] : ($null) ? (array_key_exists($needle, $haystack) ? $haystack[$needle] : false): false;
}
But here's the problem: If I want to echo year from $data argument I need to do
if (...) {
echo $data;
...
}
but it wont work if $data was array and year which I want to echo is in
$data["year"];
How can I get it work for both cases for 1 echo.
I think I found the answer to my own question:
if (is_numeric($newData = $data) || is_numeric($newData = self::setIfGet("year", $data))){
echo $newData;
I have the following function to check the array's keys
public function check($arr, $key, $default = NULL) {
return isset($arr[$key]) && !empty($arr[$key]) ? $arr[$key] : $default;
}
$this->check($info, 'location'); //it's working
$this->check($info['birthday'], 'year'); //it's working
$this->check($_POST, 'email'); //it's working
$this->check($_POST, 'password'); //it's working
everything is ok until multidimensional array appears
Notice: Array to string conversion in
change your function code to:
public function check($arr, $key, $default = NULL) {
return isset($arr[$key]) ? $arr[$key] : $default;
}
if you still want to check for empty value (though isset is enough):
public function check($arr, $key, $default = NULL) {
return isset($arr[$key]) && (!empty($arr[$key]) || is_array($arr[$key])) ? $arr[$key] : $default;
}
Not 100% sure what are you looking for but please notice that if you have email[][] field, when you return $arr[$key] you are returning an array. So you have to check if $arr[$key] is an array before returning its value.
public function check($arr, $key, $default = NULL) {
if( isset($arr[$key]) && !empty($arr[$key]) || is_array($arr[$key])) {
if(is_array($arr[$key])) {
//apply here your second level check condition
} else return $arr[$key]; // returns its value (if it's not an array)
} else return $default;
}
Hope it helps
Instead, if you're trying to build a function checking recursively if $key is contained somewhere in a multidimensional array, you have to do otherwise (that's why I wrote I'm not 100% sure what you're looking for)
? $arr[$key]
In the above code you are using $_POST['email'] (which is an array) as a string.
I am trying to figure out the best way to use dot notation when passing in a key or set of keys into a function and getting that post value.
Example
shipping.first_name
What it looks like in actual $_POST array:
$_POST[shipping][first_name] = 'some value'
I would like to be able to pass in (as a parameter) the string, and have the function return the post value.
function get_post($str = NULL){
return $_POST[$key1][$key1]..etc.
}
Current attempt (working as intended, but need to put into $_POST):
From: SO Question
function assignArrayByPath(&$arr, $path) {
$keys = explode('.', $path);
while ($key = array_shift($keys)) {
$arr = &$arr[$key];
}
}
$output = array();
assignArrayByPath($output, $str);
This produces an array of:
Array ( [shipping] => Array ( [first_name] => ) )
I would like then to do something like this:
return isset($_POST.$output) ? true : false;
So how do I take that array created from the period separated string and check if it exists in POST?
I think this might be a duplicate, but I am not positive. I apologize in advance if it is. Any help is much appreciated.
See Laravel array_set implement http://laravel.com/api/source-function-array_set.html#319
/**
* Set an array item to a given value using "dot" notation.
*
* If no key is given to the method, the entire array will be replaced.
*
* #param array $array
* #param string $key
* #param mixed $value
* #return array
*/
function array_set(&$array, $key, $value)
{
if (is_null($key)) return $array = $value;
$keys = explode('.', $key);
while (count($keys) > 1)
{
$key = array_shift($keys);
// If the key doesn't exist at this depth, we will just create an empty array
// to hold the next value, allowing us to create the arrays to hold final
// values at the correct depth. Then we'll keep digging into the array.
if ( ! isset($array[$key]) || ! is_array($array[$key]))
{
$array[$key] = array();
}
$array =& $array[$key];
}
$array[array_shift($keys)] = $value;
return $array;
}
Check exists you can see array_get http://laravel.com/api/source-function-array_get.html#224
/**
* Get an item from an array using "dot" notation.
*
* #param array $array
* #param string $key
* #param mixed $default
* #return mixed
*/
function array_get($array, $key, $default = null)
{
if (is_null($key)) return $array;
if (isset($array[$key])) return $array[$key];
foreach (explode('.', $key) as $segment)
{
if ( ! is_array($array) || ! array_key_exists($segment, $array))
{
return value($default);
}
$array = $array[$segment];
}
return $array;
}
I use this to check if an object has properties,
function objectHasProperty($input){
return (is_object($input) && (count(get_object_vars($input)) > 0)) ? true : false;
}
But then I want to check further to make sure all properties have values, for instance,
stdClass Object
(
[package] =>
[structure] =>
[app] =>
[style] =>
[js] =>
)
Then I want to return false if all the properties have empty values. Is it possible? Any hint and ideas?
There are several ways of doing this, all the way up to using PHP's reflection API, but to simply check if all public properties of an object are empty, you could do this:
$properties = array_filter(get_object_vars($object));
return !empty($properties);
(The temporary variable $properties is required because you're using PHP 5.4.)
For deep inspection and a more advanced handling I'd go for something like the following which is easily extended. Consider it a follow up answer to dev-null-dweller's answer (which is perfectly valid and a great solution).
/**
* Deep inspection of <var>$input</var> object.
*
* #param mixed $input
* The variable to inspect.
* #param int $visibility [optional]
* The visibility of the properties that should be inspected, defaults to <code>ReflectionProperty::IS_PUBLIC</code>.
* #return boolean
* <code>FALSE</code> if <var>$input</var> was no object or if any property of the object has a value other than:
* <code>NULL</code>, <code>""</code>, or <code>[]</code>.
*/
function object_has_properties($input, $visibility = ReflectionProperty::IS_PUBLIC) {
set_error_handler(function(){}, E_WARNING);
if (is_object($input)) {
$properties = (new ReflectionClass($input))->getProperties($visibility);
$c = count($properties);
for ($i = 0; $i < $c; ++$i) {
$properties[$i]->setAccessible(true);
// Might trigger a warning!
$value = $properties[$i]->getValue($input);
if (isset($value) && $value !== "" && $value !== []) {
restore_error_handler();
return true;
}
}
}
restore_error_handler();
return false;
}
// Some tests
// The bad boy that emits a E_WARNING
var_dump(object_has_properties(new \mysqli())); // boolean(true)
var_dump(object_has_properties(new \stdClass())); // boolean(false)
var_dump(object_has_properties("")); // boolean(false)
class Foo {
public $prop1;
public $prop2;
}
var_dump(object_has_properties(new Foo())); // boolean(false)
$foo = new Foo();
$foo->prop1 = "bar";
var_dump(object_has_properties($foo)); // boolean(true)
Depending on what do you consider as 'empty value' you may have adjust the callback function that removes unwanted values:
function objectHasProperty($input){
return (
is_object($input)
&&
array_filter(
get_object_vars($input),
function($val){
// remove empty strings and null values
return (is_string($val) && strlen($val))||($val!==null);
}
)
) ? true : false;
}
$y = new stdClass;
$y->zero = 0;
$n = new stdClass;
$n->notset = null;
var_dump(objectHasProperty($y),objectHasProperty($n));//true,false
I'm coding a worksheet app for a printer company.
I'm getting flood of forms.
For every single input field I have to check if the $_POST variables are set, and if, so echo back the value. (In case of some error, for example after a validation error, the user shouldn't retype the whole form)
Sample code:
if(isset($_POST['time'])&&!empty($_POST['time'])){echo $_POST['time'];}
I had to implement this about a hundred times.
So I tried to figure out some kind of function to make this simple and readable.
Something like this:
function if_post_echo($key, $default = "") {
if(isset($_POST[$key])&&!empty($_POST[$key])){
echo $_POST[$key];
}else{
echo $default;
}
}
But this wont work.
I have tried to pass in the $_POST for the $key variable like this:
if_post_echo($_POST['time'])
function if_request_echo($key, $default = "") {
if(isset($key)&&!empty($key)){
echo $key;
}else{
echo $default;
}
}
And I also tried this:
function if_request_echo($key, $default = null) {
return isset($_REQUEST[$key])&&!empty($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}
Without any reasonable outcome.
The question:
How can I forge a function that looks for the necessary $_POST variable and returns it or if its unset then returns an empty string.
And is there a way to do this for $_GET and $_REQUEST, too? (Or simply duplicate?)
Your PHP testing function:
<?php
function test_req($key, $default = '') {
if(isset($_REQUEST[$key]) and
!empty($_REQUEST[$key])) {
return $_REQUEST[$key];
} else {
return $default;
}
}
?>
Then in your form HTML:
<input name="my_field" value="<?php echo htmlentities(test_req('my_field')); ?>" />
$_REQUEST (linked) is a PHP super global that contains both POST ($_POST) and GET ($_GET) request parameters.
If you only want to capture POST request parameters then it would be:
<?php
function test_req($key, $default = '') {
if(isset($_POST[$key]) and
!empty($_POST[$key])) {
return $_POST[$key];
} else {
return $default;
}
}
?>
For example.
If you have a large amount of fields, I would propose that you also use an array of defaults:
$defaults = array(
"time" => "default",
"name" => "enter name here",
"text..." => "...",
);
$fields = array_filter($_POST) + $defaults;
$fields will then contain a list of form values with either the POST data or a preset default. No isset, see?
array_filter man page particularly: If no callback is supplied, all entries of input equal to FALSE will be removed. Goes some way to explaining the working behind this solution.
This should work:
function if_post_echo($key, $default = ''){
if(isset($_POST[$key]) AND !empty($_POST[$key]){
echo $_POST[$key];
}
echo $default;
}
If you're having problems I recommend that you try var_dump($_POST) or print_r($_POST) to see if everything has been properly posted.
Just to note, this is redundant:
isset($_POST[$key]) && !empty($_POST[$key])
An unset variable is going to always be "empty", so isset() is implied in your empty() call.
For your logic you can achieve the same result with just:
!empty($_POST[$key])
Your first function works perfectly to me.
Why do you think it doesn't work?
However, a better variant would be
function _post($key, $default = "") {
if(isset($_POST[$key])){
return $_POST[$key];
}else{
return $default;
}
}
To use it :
echo $_post($key); // You could define the message as a second parameter.
function requireArray( $array, $required ) {
foreach( $required as $k=>$v ) {
if ( !isset($array[$k]) || empty($array[$k]) )
return false;
}
return true;
}
#call like this:
requireArray($_POST, array('time', 'username', 'foo'));
If you want to know specifically:
function missingFrom( $array, $required ) {
$r = array();
foreach( $required as $k ) {
if ( !isset($array[$k]) || empty($array[$k]) )
$r[] = $k;
}
return $r;
}
Called like previous function.
Your method seems to work fine here:
function if_post_echo($key, $default = "") {
if(isset($_POST[$key])&&!empty($_POST[$key])){
echo $_POST[$key];
}else{
echo $default;
}
}
I made a simple input with the name test and the form method is POST and using echo if_post_echo('test');.
It posted on the page what was in the text box.
This feature is being added in PHP 7 as the "Null Coalesce Operator" using two question marks:
echo ($_GET['message'] ?? 'default-if-not-set');
https://wiki.php.net/rfc/isset_ternary