In Python I can use "get" method to get value from an dictionary without error.
a = {1: "a", 2: "b"}
a[3] # error
a.get(3, "") # I got empty string.
So I search for a common/base function that do this:
function GetItem($Arr, $Key, $Default){
$res = '';
if (array_key_exists($Key, $Arr)) {
$res = $Arr[$Key];
} else {
$res = $Default;
}
return $res;
}
Have same function basicly in PHP as in Python?
Thanks:
dd
isset() is typically faster than array_key_exists(). The parameter $default is initialized to an empty string if omitted.
function getItem($array, $key, $default = "") {
return isset($array[$key]) ? $array[$key] : $default;
}
// Call as
$array = array("abc" => 123, "def" => 455);
echo getItem($array, "xyz", "not here");
// "not here"
However, if an array key exists but has a NULL value, isset() won't behave the way you expect, as it will treat the NULL as though it doesn't exist and return $default. If you expect NULLs in the array, you must use array_key_exists() instead.
function getItem($array, $key, $default = "") {
return array_key_exists($key, $array) ? $array[$key] : $default;
}
Not quite. This should behave the same.
function GetItem($Arr, $Key, $Default = ''){
if (array_key_exists($Key, $Arr)) {
$res = $Arr[$Key];
} else {
$res = $Default;
}
return $res;
}
The first line in your function is useless, as every code path results in $res being overwritten. The trick is to make the $Default parameter optional as above.
Keep in mind that using array_key_exists() can cause significant slowdowns, especially on large arrays. An alternative:
function GetItem($Arr, $Key, $Default = '') {
return isset($Arr[$Key]) ? $Arr[$Key] : $Default;
}
There is no base function to do that in my mind.
Your GetItem is a good way to do what you wanna do :)
Yes. or
function GetItem($Arr, $Key, $Default) {
return array_key_exists($Key, $Arr)
? $Arr[$Key]
: $Default;
}
php7 is out for a long time now so you can do
$Arr[$Key] ?? $default
Related
I'm writing a function named all to check all elements inside an array $arr, returning a single boolean value (based of $f return value). This is working fine passing custom functions (see the code with $gte0 been passed to all).
However sometimes one want just check that an array contains all true values: all(true, $arr) will not work becase true is passed as boolean (and true is not a function name). Does PHP have a native true() like function?
function all($f, array $arr)
{
return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) {
return $f($v1) && $f($v2);
}, true);
}
$test = array(1, 6, 2);
$gte0 = function($v) { return $v >= 0; }
var_dump(all($gte0, $test)); // True
$test = array(true, true, false);
$id = function($v) { return $v; } // <-- this is what i would avoid
var_dump(all($id, $test)); // False
all(true, $test); // NOT WORKING because true is passed as boolean
all('true', $test); // NOT WORKING because true is not a function
EDIT: another way could be checking $f in all function:
$f = is_bool($f) ? ($f ? function($v) { return $v; }
: function($v) { return !$v; } ): $f;
After adding this, calling all with true is perfectly fine.
intval might do what you're looking for (especially as the array only contains integers in your example):
var_dump(all('intval', $test)); // False
However, many types to integer conversions are undefined in PHP and with float this will round towards zero, so this might not be what you want.
The more correct "function" would be the opposite of boolean true: empty, but it's not a function, so you can't use it (and invert the return value):
var_dump(!all('empty', $test)); // Does not work!
And there is no function called boolval or similar in PHP, so write it yourself if you need it ;)
Additionally your all function could be optimized. While iterating, if the current result is already FALSE, the end result will always be FALSE. And no need to call $f() n * 2 times anyway:
function all($f, array $arr)
{
$result = (bool) $arr;
foreach($arr as $v) if (!$f($v)) return FALSE;
return $result;
}
Edit: knittl is right pointing to array_filter, it converts to boolean with no function given which seems cool as there is no "boolval" function:
function all($f, array $arr)
{
return ($c = count($arr))
&& ($f ? $arr = array_map($f, $arr) : 1)
&& $c === count(array_filter($arr));
}
var_dump(all(0, $test)); // False
Making the first function parameter optional will do you a proper bool cast on each array element thanks to array_filter.
Better to pass in a function to map the values to booleans that you can then reduce to a final value.
function all($map, $data) {
if (empty($data)) { return false; }
$reduce = function($f, $n) {
return $f && $n;
};
return array_reduce(array_map($map, $data), $reduce, true);
}
$gte0 = function($v) { return $v >= 0; };
$gte2 = function($v) { return $v >= 2; };
$data = array(1, 2, 3, 4, 5);
var_dump(all($gte0, $data));
var_dump(all($gte2, $data));
Then the result of the function remains expectant but the test can be slotted in as needed. You can go a step further and allow both the map and reduce function to be passed in.
function mr($map, $reduce, $data) {
return array_reduce(array_map($map, $data), $reduce, true);
}
You could use PHP's array_filter function, it will remove all 'falsy' values from an array if no callback is specified:
$a = array ( true, true, false );
var_dump($a == array_filter($a));
There isn't any true() function in PHP, you should compare the value to true.
try
return ($f === $v1) && ($f === $v2);
instead of
return $f($v1) && $f($v2);
I think this should work:
function all($f, array $arr)
{
return empty($arr) ? false : array_reduce($arr, function($v1, $v2) use ($f) {
return $f($v1) && $f($v2);
}, true);
}
function isTrue($a)
{
return true === $a;
}
all("isTrue", $test);
This is similar question to MySQL and PHP - insert NULL rather than empty string but I'm still encountering the problem.
I'm trying to create a function so that an empty string is inserted as a NULL into MySQL.
I create the function IsEmptyString:
function IsEmptyString($val){
if (trim($val) === ''){$val = "NULL";}
}
Before inserting the the variable, I escape it and then I call the function above. I've also tried $val = NULL;
What am I doing wrong? Also should I call the function before escaping?
You need to return $val at the end of the function:
function IsEmptyString($val){
if (trim($val) === ''){$val = "NULL";}
return $val;
}
You're not returning the value. This should work
function IsEmptyString($val){
if (trim($val) === ''){$val = "NULL";}
return $val;
}
Also you're assigning your variable to a string and not null.
This line $val = "NULL";
should be
$val = null;
Also see PHP's isset() and empty() functions.
alternativly, you can pass val as reference.
function IsEmptyString(&$val){
if (trim($val) === ''){$val = "NULL";}
}
however, be carefull not to send "'".$val."'" to the database;
Either you can return the result with return...
function IsEmptyString($val)
{
if (trim($val) === '')
return 'NULL';
else
return $val;
}
...or you have to pass the variable as reference (note the & before the $val)
function IsEmptyString(&$val)
{
if (trim($val) === '')
$val = 'NULL';
}
Looks like a good candidate for a ternary operator:
function valOrNull($val) {
return (trim($val) === '') ? NULL : $val;
}
Why does the following code give me an error in php?:
$b = array("1" => "2")["1"];
Error I get is Parse error...
Help.
Unfortunately, in PHP, you need to do this:
$a = array("1" => "2");
$b = $a["1"];
It feels like your example should work because it does in other languages. But this is just the way PHP is.
Couple things. You can't pull immediately from arrays during creation, and keys of numerical values are automatically converted to integers, even if they're intended to be strings.
You can use a function to do this for you:
function Get($array, $key, $default = false)
{
if (is_array($array) === true)
{
settype($key, 'array');
foreach ($key as $value)
{
if (array_key_exists($value, $array) === false)
{
return $default;
}
$array = $array[$value];
}
return $array;
}
return $default;
}
And use it like this:
$b = Get(array("1" => "2"), "1"); // 2
If you don't need to access multi-dimensional arrays you can also use this shorter function:
function Get($array, $key, $default = false)
{
if (is_array($array) === true)
{
return (array_key_exists($value, $array) === true) ? $array[$value] : $default;
}
return $default;
}
Is there a better way to do this simple task below? Like with an array or even another method?
<?PHP
// current way
if ($city != NULL) {
$city = FilterALLHTML($city);
}
if ($state != NULL) {
$state = FilterALLHTML($state);
}
if ($title != NULL) {
$title = FilterALLHTML($title);
}
if ($division != NULL) {
$division = FilterALLHTML($division);
}
?>
Here is my current function
function FilterALLHTML($document) {
//old array line //"'<[\/\!]*?[^<>]*//?//>'si",// strip html
$text = strip_tags($document);
$search = array ("/f.?u.?c.?k/i",
"/(s|$).?h.?i.?t/i",
'/(potspace|mycrib|palbolt)/i');
$text = preg_replace ($search, '', $text);
return $text;
}
UPDATE - Ok my new function after the suggestions from this post thanks guys
function FilterALLHTML($var) {
//old array line //"'<[\/\!]*?[^<>]*//?//>'si",// strip html
if ($var != null){
$text = strip_tags($var);
$search = array ("/f.?u.?c.?k/i",
"/(s|$).?h.?i.?t/i",
'/(potspace|mycrib|palbolt|pot space)/i');
$text = preg_replace ($search, '', $text);
return $text;
}
return null;
}
Change your FilterALLHTML function to do the null check and have it return null?
Then you can throw away all the ifs.
Example:
function FilterALLHTML($input)
{
if ($input === null)
return null;
// Original code, I'll just use strip_tags() for a functional example
return strip_tags($input);
}
Edit:
I felt like sharing an alternative to variable variables, as I don't really like the idea of using string literals instead of variable names. References all the way :)
function FilterALLHTML(&$text)
{
if ($text !== null)
{
// Omitted regex bit for simplicity
$text = strip_tags($text);
}
}
$city = "<b>New York</b>";
$state = null;
$title = "<i>Mr.</i>";
$fields = array(&$city, &$state, &$title);
foreach ($fields as &$var)
FilterALLHTML($var);
(note: FilterALLHTML implementation differs from first example)
Yes, use PHP's variable variables.
$vars = array('city','state','title','division');
foreach($vars as $v) {
if ($$v != null) $$v = FilterAllHTML($$v);
}
If you know for a fact that all the variables have been previously defined, then you don't need the null check. Otherwise, the null check will prevent E_NOTICE errors from triggering.
foreach (array('city', 'state', 'title', 'division') as $var) {
if ($$var != null) {
$$var = FilterALLHTML($$var);
}
}
Like Thorarin I'd suggest having your FilterALLHTML function check for null instead though.
zombat's answer is the best, but I'd add that you shouldn't really be checking for null either. If for some reason FilterAllHTML has a problem with null values, which it shouldn't, put the check for null in the FilterAllHTML function definition.
$vars = array('city', 'state', 'title', 'division');
foreach($vars as $var) {
$$var = FilterAllHTML($$var);
}
Well, you could already consider writing a function because you do exactly the same thing four times.
Assuming FilterALLHTML is not a custom function.
function Filter($var)
{
if ($var != null)
{
return FilterALLHTML($var);
}
return null;
}
Or just include the null check in the FilterALLHTML function and return null from there, if needed.
So, if you can change FilterALLHTML then you'd do it like this:
function FilterALLHTML($var)
{
if ($var == null)
{
return null;
}
else
{
//do your filtering
return $filteredVar;
}
}
Adding to Thorarin's answer, you can change your filterall function in order to accept an array as input, and passing it by reference it will modify the arrays' content.
$tofilter = array($city,$state,$division,$title);
filterall($tofilter);
I didn't see it mentioned, you could always pass the parameters by reference to skip the repeated assignments:
function FilterALLHTML(&$var)
{
if ($var == null)
{
$var = null;
}
else
{
$var = strip_tags($var);
}
}
I believe you can also store references in the array but i haven't tried it.
foreach (array(&$city, &$state, &$title, &$division) as $var)
{
FilterALLHTML($var);
}
I don't think you can improve the performance, but you can shorten the syntax, but it will end up being the same to the interpreter
<?PHP
$city = ($city == NULL) ? "default value" : FilterALLHTML($city);
$state = ($state == NULL) ? "default value" : FilterALLHTML($state);
$title = ($title == NULL) ? "default value" : FilterALLHTML($title);
$division = ($division == NULL) ? "default value" : FilterALLHTML($division);
?>
"default value" should be replaced with what you would like the value to be if the variable is null
I'm working on a program that uses PHP's internal array pointers to iterate along a multidimensional array. I need to get an element from the current row, and I've been doing it like so:
$arr[key($arr)]['item']
However, I'd much prefer to use something like:
current($arr)['item'] // invalid syntax
I'm hoping there's a function out there that I've missed in my scan of the documentation that would enable me to access the element like so:
getvalue(current($arr), 'item')
or
current($arr)->getvalue('item')
Any suggestions?
I very much doubt there is such a function, but it's trivial to write
function getvalue($array, $key)
{
return $array[$key];
}
Edit: As of PHP 5.4, you can index array elements directly from function expressions, current($arr)['item'].
Have you tried using one of the iterator classes yet? There might be something in there that does exactly what you want. If not, you can likely get what you want by extending the ArrayObject class.
This function might be a bit lenghty but I use it all the time, specially in scenarious like:
if (array_key_exists('user', $_SESSION) === true)
{
if (array_key_exists('level', $_SESSION['user']) === true)
{
$value = $_SESSION['user']['level'];
}
else
{
$value = 'DEFAULT VALUE IF NOT EXISTS';
}
}
else
{
$value = 'DEFAULT VALUE IF NOT EXISTS';
}
Turns to this:
Value($_SESSION, array('user', 'level'), 'DEFAULT VALUE IF NOT EXISTS');
Here is the function:
function Value($array, $key = 0, $default = false)
{
if (is_array($array) === true)
{
if (is_array($key) === true)
{
foreach ($key as $value)
{
if (array_key_exists($value, $array) === true)
{
$array = $array[$value];
}
else
{
return $default;
}
}
return $array;
}
else if (array_key_exists($key, $array) === true)
{
return $array[$key];
}
}
return $default;
}
PS: You can also use unidimensional arrays, like this:
Value($_SERVER, 'REQUEST_METHOD', 'DEFAULT VALUE IF NOT EXISTS');
If this does not work, how is your multidimensional array composed? A var_dump() might help.
$subkey = 'B';
$arr = array(
$subkey => array(
'AB' => 'A1',
'AC' => 'A2'
)
);
echo current($arr[$subkey]);
next($arr[$subkey]);
echo current($arr[$subkey]);
I often use
foreach ($arr as $key=>$val) {
$val['item'] /*$val is the value of the array*/
$key /*$key is the key used */
}
instead of
next($arr)/current($arr)