Do PHP array keys need to we wrapped in quotes? - php

Which one below is correct? First code has no quotes in the $_GET array and the second one does, I know you are supposed to have them when it is a string of text but in this case it is a variable, also what about if the key is a number?
no quotes
function arg_p($name, $default = null) {
return (isset($_GET[$name])) ? $_GET[$name] : $default;
}
with quotes
function arg_p($name, $default = null) {
return (isset($_GET['$name'])) ? $_GET['$name'] : $default;
}

The first one will use the value of $name as key while the second will use the literal string '$name' as key.

With PHP, $_GET["$name"] and $_GET[$name] are identical, because PHP will evaluate variables inside double-quotes. This will return the key of whatever the variable $name stores.
However, $_GET['$name'] will search for the key of $name itself, not whatever the variable $name contains.
If the key is a number, $_GET[6], $_GET['6'], and $_GET["6"] are all syntactically equal.

if the key is a variable
$array[$key];
you don't have to quote it.
but if it a literal string you must (it is not a string if you don't wrap it in quotes)
$array['myKey'];
and you will get an notice if you do it like this
$array[mykey];

Related

Transform any null input to empty string

So I've got a while loop, inside I have $array_collections that gives me 35 value per loop, I want to verify for every value if it's equal to NULL then give it an empty string. I did that :
while ($array_collections = tep_db_fetch_array($query)) {
foreach ($array_collections as $key => $value) {
if (is_null($value)) {
$array_collections[$key] = "";
}
}
$docs[] = new \Elastica\Document('', \Glam\HttpUtils::jsonEncode(
array(
'X' => $array_collections['X'],
... etc
)));
}
This technically should work, but the loop goes over 500K elements so it's huge, and for every element we put it into a table, problem is that I run out of memory at some point. So is there another simple way to give any given NULL value an empty string without looping?
well, you can put NOT NULL constraint with empty string as DEFAULT value in the DB for that so you dont need to do that in php using looping, but if you dont want to change the DB design then you can use COALESCE in your query
select COALESCE(yourfield,'') from table
it will convert NULL value into empty string
You can use array_map function to replace null values into empty string.
$array_collections=array_map(function($ar)
{
if(isset($ar) && $ar!=null){
return $ar;
}
return '';
},$array_collections);
Above code replace all null values to empty string. No need of loop.
you can use array_walk:
function replace_null(&$lsValue, $key) {
if(is_null($lsValue)) {
$lsValue = "";
}
}
array_walk($array_collections, 'replace_null');

Expanding variables in string passed as argument

I have a situation where I want to check if a lot of strings are empty before I perform an operation on them. I don't want to have to perform this check on every single string manually, so I put it in a function that looks like this:
function format_field($field_name, $format) {
$value = get_field($field_name);
if ($value != "") {
return $format;
}
return "";
}
A call to this function looks like this:
format_field('website', "<p><strong>Website:</strong>$value</p>");
I was hoping that by writing $value in the string passed to format_field() the value of $value would be expanded in the function before it got returned, but that doesn't seem to be the case.
Is this at all possible and I'm just going wrong?
I also know about sprintf(), but since $value can be referenced multiple times in the string it's less than ideal.
The problem with your code is that when passing "<p><strong>Website:</strong>$value</p>" as a function argument, the $value variable doesn't get substituted later in the function block.
So for example if you have $value = 'https://a.b.c'; the value of $format becomes "<p><strong>Website:</strong>https://a.b.c</p>"
What you could try, is substitute a placeholder, for example
pass "<p><strong>Website:</strong>{value}</p>" as the $format argument, then use something like that:
$format = "<p><strong>Website:</strong>{value}</p>";
$value = 'https://www.google.com';
echo preg_replace('#\{value\}#i', $value, $format);
which actually returns: <p><strong>Website:</strong>https://www.google.com</p>

Joomla check for empty string with JInput

Following this guide to sanitize my inputs, I'm wondering if an empty string is covered with this?
$jinput = JFactory::getApplication()->input;
$this->name = $jinput->get('name', '', 'STRING');
Typically without Joomla I'd be checking for an empty string as well. Something like:
if (!empty($_POST['name']))
Looking at the JInput get method I see that it checks if it is isset:
public function get($name, $default = null, $filter = 'cmd')
{
if (isset($this->data[$name]))
{
return $this->filter->clean($this->data[$name], $filter);
}
return $default;
}
Not the same thing, as isset will only check for null. However that is the default value for using the get method. So if I specify an empty string for the second parameter am I covered here?
$this->name = $jinput->get('name', '', 'STRING');
It's not up to Joomla to decide whether your empty string is valid value or not. They have to use isset(), because if they would use empty() and you return '0' which you would expect as normal, Joomla would return default value instead of that '0'.
So it's completely normal that they just use isset() to check if variable is set, and it's up to you to decide what values you accept.
If the value isn't set, and you set as the second parameter empty string '', you'll get an empty string returned.
In your example an empty string would be returned, which is expected behaviour.

how to store isset condition php to avoid repetition

my code:
if (isset($dayMarks[$res['resId']][$dDate])) {
$var=$dayMarks[$res['resId']][$dDate];
echo $var;
}
note that the isset condition is identical to the value assigned to $var, which creates a pretty ugly code.
How is it possible to assign the condition to $var without repeating it?
(in javascript, I'd write if (var=$dayMarks[$re...) )
This is a common problem in PHP where including files can create uncertainty about variables.
There are a two approaches that work well for me.
Default Assignment
With default assignment the $var variable will be given a default value when the key doesn't exist.
$var = isset($dayMarks[$res['resId']][$dDate]) ? $dayMarks[$res['resId']][$dDate] : false;
After this code can assume that $var will always contain a valid value.
Default Merger
My preferred method is to always declare a default array that contains all the required values, and their defaults. Using the False value to mark any keys that might be missing a value (assuming that key holds another value type besides boolean).
$default = array(
'date'=>false,
'name'=>'John Doe'
);
$dayMarks[$res['resId']] = array_merge($default, $dayMarks[$res['resId']]);
This will ensure that the required keys for that variable exist, and hold at least a default value.
You can now test if the date exists.
if($dayMarks[$res['resId']]['date'] !== false)
{
// has a date value
}
While this might not work exactly for your array. Since it looks like it's a table structure. There is a benefit to switching to named key/value pairs. As this allows you to easily assign default values to that array.
EDIT:
The actual question was if it was possible to reproduce the JavaScript code.
if (var=$dayMarks[$re...)
Yes, this can be done by using a helper function.
NOTE: This trick should only be used on non-boolean types.
function _isset($arr,$key)
{
return isset($arr[$key]) ? $arr[$key] : false;
}
$a = array('zzzz'=>'hello');
if(($b = _isset($a,'test')) !== false)
{
echo $b;
}
if(($c = _isset($a,'zzzz')) !== false)
{
echo $c;
}
See above code here
$isset = isset(...); //save the value
if ($isset) { .... }; // reuse the value
...
if ($isset) { ... }; // reuse it yet again
The only thing you can do is store $res['resId'][$dDate].
$var = $res['resId'][$dDate];
if( isset($dayMarks[$var]) ) {
$var = $dayMarks[$var];
echo $var;
}
If you only want to assign a variable processing simply, you can also write this as:
$var = $dayMarks[$res['resId']][$dDate]);
if (!isset($var)) unset($var);

PHP: Check if variable exist but also if has a value equal to something

I have (or not) a variable $_GET['myvar'] coming from my query string and I want to check if this variable exists and also if the value corresponds to something inside my if statement:
What I'm doing and think is not the best way to do:
if(isset($_GET['myvar']) && $_GET['myvar'] == 'something'): do something
My question is, exist any way to do this without declare the variable twice?
That is a simple case but imagine have to compare many of this $myvar variables.
Sadly that's the only way to do it. But there are approaches for dealing with larger arrays. For instance something like this:
$required = array('myvar', 'foo', 'bar', 'baz');
$missing = array_diff($required, array_keys($_GET));
The variable $missing now contains a list of values that are required, but missing from the $_GET array. You can use the $missing array to display a message to the visitor.
Or you can use something like that:
$required = array('myvar', 'foo', 'bar', 'baz');
$missing = array_diff($required, array_keys($_GET));
foreach($missing as $m ) {
$_GET[$m] = null;
}
Now each required element at least has a default value. You can now use if($_GET['myvar'] == 'something') without worrying that the key isn't set.
Update
One other way to clean up the code would be using a function that checks if the value is set.
function getValue($key) {
if (!isset($_GET[$key])) {
return false;
}
return $_GET[$key];
}
if (getValue('myvar') == 'something') {
// Do something
}
As of PHP7 you can use the Null Coalescing Operator ?? to avoid the double reference:
// $_GET['myvar'] isn't set...
echo ($_GET['myvar'] ?? '') == 'hello' ? "hello!\n" : "goodbye!\n";
// $_GET['myvar'] is set but != 'hello'
$_GET['myvar'] = 'farewell';
echo ($_GET['myvar'] ?? '') == 'hello' ? "hello!\n" : "goodbye!\n";
// $_GET['myvar'] is set and == 'hello'
$_GET['myvar'] = 'hello';
echo ($_GET['myvar'] ?? '') == 'hello' ? "hello!\n" : "goodbye!\n";
Output:
goodbye!
goodbye!
hello!
Code demo on 3v4l.org
In general, the expression
$a ?? $b
is equivalent to
isset($a) ? $a : $b
Note that in the code example it is necessary to place parentheses around $_GET['myvar'] ?? '' as == has higher precedence than ?? and thus
$_GET['myvar'] ?? '' == 'hello'
would evaluate to:
$_GET['myvar'] ?? ('' == 'hello')
which would be true as long as $_GET['myvar'] was set and "truthy" (see the manual) and false otherwise (since '' == 'hello' is false).
Precedence code demo on 3v4l.org
If you're looking for a one-liner to check the value of a variable you're not sure is set yet, this works:
if ((isset($variable) ? $variable : null) == $value) { }
The only possible downside is that if you're testing for true/false - null will be interpreted as equal to false.
As mellowsoon suggest, you might consider this approach:
required = array('myvar' => "defaultValue1", 'foo' => "value2", 'bar' => "value3", 'baz' => "value4");
$missing = array_diff($required, array_keys($_GET));
foreach($missing as $key => $default ) {
$_GET[$key] = $default ;
}
You put the default values and set the not recieved parameters to a default value :)
My question is, exist any way to do this without declare the variable twice?
No, there is no way to do this correctly without doing two checks. I hate it, too.
One way to work around it would be to import all relevant GET variables at one central point into an array or object of some sort (Most MVC frameworks do this automatically) and setting all properties that are needed later. (Instead of accessing request variables across the code.)
Thanks Mellowsoon and Pekka, I did some research here and come up with this:
Check and declare each variable as null (if is the case) before start to use (as recommended):
!isset($_GET['myvar']) ? $_GET['myvar'] = 0:0;
*ok this one is simple but works fine, you can start to use the variable everywhere after this line
Using array to cover all cases:
$myvars = array( 'var1', 'var2', 'var3');
foreach($myvars as $key)
!isset($_GET[$key]) ? $_GET[$key] =0:0;
*after that you are free to use your variables (var1, var2, var3 ... etc),
PS.: function receiving a JSON object should be better (or a simple string with separator for explode/implode);
... Better approaches are welcome :)
UPDATE:
Use $_REQUEST instead of $_GET, this way you cover both $_GET and $_POST variables.
!isset($_REQUEST[$key]) ? $_REQUEST[$key] =0:0;
why not create a function for doing this, convert the variable your want to check into a real variable, ex.
function _FX($name) {
if (isset($$name)) return $$name;
else return null;
}
then you do _FX('param') == '123', just a thought
I use all time own useful function exst() which automatically declare variables.
Example -
$element1 = exst($arr["key1"]);
$val2 = exst($_POST["key2"], 'novalue');
/**
* Function exst() - Checks if the variable has been set
* (copy/paste it in any place of your code)
*
* If the variable is set and not empty returns the variable (no transformation)
* If the variable is not set or empty, returns the $default value
*
* #param mixed $var
* #param mixed $default
*
* #return mixed
*/
function exst( & $var, $default = "")
{
$t = "";
if ( !isset($var) || !$var ) {
if (isset($default) && $default != "") $t = $default;
}
else {
$t = $var;
}
if (is_string($t)) $t = trim($t);
return $t;
}
A solution that I have found from playing around is to do:
if($x=&$_GET["myvar"] == "something")
{
// do stuff with $x
}
<?php
function myset(&$var,$value=false){
if(isset($var)):
return $var == $value ? $value : false;
endif;
return false;
}
$array['key'] = 'foo';
var_dump(myset($array['key'],'bar')); //bool(false)
var_dump(myset($array['key'],'foo'));//string(3) "foo"
var_dump(myset($array['baz'],'bar'));//bool(false)
This is similar to the accepted answer, but uses in_array instead. I prefer to use empty() in this situation. I also suggest using the new shorthand array declaration which is available in PHP 5.4.0+.
$allowed = ["something","nothing"];
if(!empty($_GET['myvar']) && in_array($_GET['myvar'],$allowed)){..}
Here is a function for checking multiple values at once.
$arrKeys = array_keys($_GET);
$allowed = ["something","nothing"];
function checkGet($arrKeys,$allowed) {
foreach($arrKeys as $key ) {
if(in_array($_GET[$key],$allowed)) {
$values[$key];
}
}
return $values;
}
Well, you could get by with just if($_GET['myvar'] == 'something') since that condition presumes that the variable also exists. If it doesn't, the expression will also result in false.
I think it's ok to do this inside conditional statements like above. No harm done really.
No official reference but it worked when I tried this:
if (isset($_GET['myvar']) == 'something')

Categories