How to Call Function inside Array - php

I will create a json file with PHP with json_encode. I intend to include a function that I will call inside array before I change it to json. Whether calling functions inside an array can be done?
$arrayList = array(
array(
'uid' => "1234",
'nilai' => getBoolean (1)));
function getBoolean ($value) {
if ($value == 0 ) {
echo "false";
} else {
echo "true";
}
}
echo json_encode ($arrayList);
Output json
true[{"uid":"1234","nilai":null}]
What if I want json output like below
[{"uid":"1234","nilai":true}]
So the value of the function (getBoolean) goes into json not outside. Thanks

PHP uses an applicative order evaluation strategy so getBoolean(1) will be evaluated before the array is assigned to $arrayList.
However, you have a bug in your getBoolean function. You need to return a boolean type value, not the string version of the boolean.
Code: (https://3v4l.org/AOdn3B)
$arrayList = [ [ 'uid' => '1234', 'nilai' => getBoolean (1) ] ];
function getBoolean ($value) {
return (bool) $value;
}
echo json_encode ($arrayList);
Output:
[{"uid":"1234","nilai":true}]
p.s. I wouldn't personally bother to write a custom function for this. Just prepend (bool) directly to your array value.
$arrayList = [ [ 'uid' => 1234, 'nilai' => (bool) 1 ] ];
Then again if you have negative numbers or some other fringe case, use:
if ($value == 0) {
return false; // boolean, not string
} else {
return true; // boolean, not string
}

Related

If statement inside PHP object

Given the below code, how do I add an if statement inside obj so that the final PHP result does not display a field if it has a NULL value? For example, if id_info is NULL, then do not display "id":[id_info] in the actual PHP page? I couldn't find this info anywhere in the documentation.
<?php
$id_info = ($db->query("SomeSQL query")->fetch_assoc())['id'];
$name_info = ....;
//some more queries
$obj = (object) ["id" => strval($id_info),
"Name" => (object) [
"eng_name" => strval($name_info)
]];
echo json_encode($obj);
?>
As mentioned by knittl you could check if a specific value is null and not add it to your object.
If it is necessary though to dynamically create objects withouth the hustle of checking. You have to use array_filter or any other custom filtering function for that.
I wrote a custom filtering function that accepts a deeply nested array and returns it back filtered.
function arrayFilter($inputArr){
$output = null;
if (is_array($inputArr)){
foreach ($inputArr as $key=>$val){
if(!$inputArr[$key]) continue;
if (is_array($val)) {
$tmpArr = arrayFilter($val);
if($tmpArr) $output[$key] = array_filter($tmpArr);
}
else $output[$key] = $val;
}
} else {
$output[$key] = $val;
}
return $output;
}
So, lets say you have a deeply nested object similar to the one you provided
$obj = (object) [
"id" => null,
"Name" => (object) [
"eng_name" => strval('some name2'),
"de_name" => null,
"more" => (object) [
"fr_name" => strval('some name3'),
"ru_name" => null,
]
]
];
Below i convert the stdClass object you have to an array with json_encode and json_decode and if you pass it as a parameter into the function like:
$filtered = arrayFilter(json_decode(json_encode($obj), true));
Your output will be something like the following:
{
"Name":{
"eng_name":"some name2",
"more":{
"fr_name":"some name3"
}
}
}
Simply don't add it to the object in the first place:
$obj = [ "Name" => [ "eng_name" => strval($name_info) ] ];
if ($id_info != null) {
$obj["id"] = strval($id_info);
}

Check if a value is empty for a key in a multidimensional array

I need a simple and elegant solution to check if a key has an empty value in a multidimensional array. Should return true/false.
Like this, but for a multidimensional array:
if (empty($multi_array["key_inside_multi_array"])) {
// Do something if the key was empty
}
All the questions I have found are searching for a specific value inside the multi-array, not simply checking if the key is empty and returning a true/false.
Here is an example:
$my_multi_array = array(
0 => array(
"country" => "",
"price" => 4,
"discount-price" => 0,
),
);
This will return true:
$my_key = "country";
if (check_multi_array_for_empty_value($my_multi_array, $my_key)) {
//Run this code here because the "country" key in my multi dimensional array is empty
}
This will also return true:
$my_key = "discount-price";
if (check_multi_array_for_empty_value($my_multi_array, $my_key)) {
//Run this code here because the "discount-price" key in my multi dimensional array is empty
}
This will return false:
$my_key = "price";
if (check_multi_array_for_empty_value($my_multi_array, $my_key)) {
//This WILL NOT RUN because the "price" key in my multi dimensional array is NOT empty
}
When I say empty, I mean like this empty()
UPDATE:
I am trying to adapt the code from this question but so far without any luck. Here is what I have so far, any help fixing would be appreciated:
function bg_empty_value_check($array, $key)
{
foreach ($array as $item)
{
if (is_array($item) && bg_empty_value_check($item, $key)) return true;
if (empty($item[$key])) return true;
}
return false;
}
You have to call recursive function for example i have multi dimension array
function checkMultiArrayValue($array) {
global $test;
foreach ($array as $key => $item) {
if(!empty($item) && is_array($item)) {
checkMultiArrayValue($item);
}else {
if($item)
$test[$item] = false;
else
$test[$item] = true;
}
}
return $test;
}
$multiArray = array(
0 => array(
"country" => "",
"price" => 4,
"discount-price" => 0,
),);
$test = checkMultiArrayValue($multiArray);
echo "<pre>"
print_r($test);
Will return array with true and false, who have key and index will contain true and who have index but not value contain false, you can use this array where you check your condition
Below function may help you to check empty value in nested array.
function boolCheckEmpty($array = [], $key = null)
{
if (array_key_exists($key, $array) && !empty($array[$key])) {
return true;
}
if (is_array($array)) {
foreach ((array)$array as $arrKey => $arrValue) {
if (is_array($arrValue)) {
return boolCheckEmpty($arrValue, $key);
}
if ($arrKey == $key && !empty($arrValue)) {
return $arrValue;
}
}
}
return false;
}
Usage :
$my_multi_array = array(
0 => array(
"country" => "aa",
"price" => 1,
"discount-price" => 0,
),
);
// Call
$checkEmpty = $this->boolCheckEmpty($my_multi_array, 'price');
var_dump($checkEmpty);
Note : This function also return false if value is 0 because used of empty

Dynamically dig into JSON with PHP

Okay, so I need to dynamically dig into a JSON structure with PHP and I don't even know if it is possible.
So, let's say that my JSON is stored ad the variable $data:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
}
}
So, to access the value of value_actionsBla, I just do $data['actions']['bla']. Simple enough.
My JSON is dynamically generated, and the next time, it is like this:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
'bli':{
'new': 'value_new'
}
}
}
Once again, to get the new_value, I do: $data['actions']['bli']['new'].
I guess you see the issue.
If I need to dig two levels, then I need to write $data['first_level']['second_level'], with three, it will be $data['first_level']['second_level']['third_level'] and so on ...
Is there any way to perform such actions dynamically? (given I know the keys)
EDIT_0: Here is an example of how I do it so far (in a not dynamic way, with 2 levels)
// For example, assert that 'value_actionsBla' == $data['actions']['bla']
foreach($data as $expected => $value) {
$this->assertEquals($expected, $data[$value[0]][$value[1]]);
}
EDIT_1
I have made a recursive function to do it, based on the solution of #Matei Mihai:
private function _isValueWhereItSupposedToBe($supposedPlace, $value, $data){
foreach ($supposedPlace as $index => $item) {
if(($data = $data[$item]) == $value)
return true;
if(is_array($item))
$this->_isValueWhereItSupposedToBe($item, $value, $data);
}
return false;
}
public function testValue(){
$searched = 'Found';
$data = array(
'actions' => array(
'abort' => '/abort',
'next' => '/next'
),
'form' => array(
'title' => 'Found'
)
);
$this->assertTrue($this->_isValueWhereItSupposedToBe(array('form', 'title'), $searched, $data));
}
You can use a recursive function:
function array_search_by_key_recursive($needle, $haystack)
{
foreach ($haystack as $key => $value) {
if ($key === $needle) {
return $value;
}
if (is_array($value) && ($result = array_search_by_key_recursive($needle, $value)) !== false) {
return $result;
}
}
return false;
}
$arr = ['test' => 'test', 'test1' => ['test2' => 'test2']];
var_dump(array_search_by_key_recursive('test2', $arr));
The result is string(5) "test2"
You could use a function like this to traverse down an array recursively (given you know all the keys for the value you want to access!):
function array_get_nested_value($data, array $keys) {
if (empty($keys)) {
return $data;
}
$current = array_shift($keys);
if (!is_array($data) || !isset($data[$current])) {
// key does not exist or $data does not contain an array
// you could also throw an exception here
return null;
}
return array_get_nested_value($data[$current], $keys);
}
Use it like this:
$array = [
'test1' => [
'foo' => [
'hello' => 123
]
],
'test2' => 'bar'
];
array_get_nested_value($array, ['test1', 'foo', 'hello']); // will return 123

Get Value from Array as Array Key

How do I recursively get value from array where I need to explode a key?
I know, it's not good the question, let me explain.
I got an array
[
"abc" => "def",
"hij" => [
"klm" => "nop",
"qrs" => [
"tuv" => "wxy"
]
]
]
So, inside a function, I pass:
function xget($section) {
return $this->yarray["hij"][$section];
}
But when I want to get tuv value with this function, I want to make section as array, example:
To get hij.klm value (nop), I would do xget('klm'), but to get hij.klm.qrs.tuv, I can't do xget(['qrs', 'tuv']), because PHP consider $section as key, and does not recursively explode it. There's any way to do it without using some ifs and $section[$i] ?
function xget($section) {
return $this->yarray["hij"][$section];
}
that one is static function right?
you can do that also for this
function xget($section) {
if(isset($this->yarray["hij"][$section])){
return $this->yarray["hij"][$section];
}elseif(isset($this->yarray["hij"]["klm"]["qrs"][$section])){
return $this->yarray["hij"]["klm"]["qrs"][$section];
}
}
as long as the key name between two of them are not the same.
You could use array_walk_recursive to find tuv's value regardless of the nested structure:
$tuv_val='';
function find_tuv($k,$v)
{
global $tuv_val;
if ($k=='tuv')
$tuv_val=$v;
}
array_walk_recursive($this->yarray,"find_tuv");
echo "the value of 'tuv' is $tuv_val";
try my code
<?php
$array = array(
'aaa' => 'zxc',
'bbb' => 'asd',
'ccc' => array(
'ddd' => 'qwe',
'eee' => 'tyu',
'fff' => array(
'ggg' => 'uio',
'hhh' => 'hjk',
'iii' => 'bnm',
),
),
);
$find = '';
function xget($key){
$GLOBALS['find'] = $key;
$find = $key;
array_walk_recursive($GLOBALS['array'],'walkingRecursive');
}
function walkingRecursive($value, $key)
{
if ($key==$GLOBALS['find']){
echo $value;
}
}
xget('ggg');
?>

array_replace_recursive keep values as keys with null values

I use this function like you'd use angular.extend() or $.extend() in my controllers.
function extend($base = array(), $replacements = array())
{
$base = !is_array($base) ? array() : $base;
$replacements = !is_array($replacements) ? array() : $replacements;
return array_replace_recursive($base, $replacements);
}
Standard use:
$inputs = extend([
'name' => 'test',
'empty'
], getInputs());
// getInputs() grabs the data from a form encoded or json body request.
I want empty to be a key so I can use this array with Laravel models or other objects later on.
I get:
[
[name] => 'test',
[0] => 'empty'
]
I want:
[
[name] => 'test',
[empty] => null
]
This should output: OK (1 test, 2 assertions)
public function testInputs()
{
$inputs = \Api::inputs([
'name' => 'test',
'empty'
]);
$this->assertArrayHasKey('name', $inputs);
$this->assertArrayHasKey('empty', $inputs);
}
Is there a native way to do this or will I be rolling my own?
In PHP, non-associative elements in arrays are treated as values for an associative array with automatic integer keys. The documentation states:
The key is optional. If it is not specified, PHP will use the
increment of the largest previously used integer key.
What that means is that ['abc', 'def'] is the same as [0 => 'abc', 1 => 'def'].
If you want your function to use values as keys, there is no way you will be able to differentiate an array that actually uses integers for keys from those that PHP automatically assigned due to missing keys.
I personally believe it is easier just to change the input to the function so that it is in the right format: ['name' => 'test', 'empty' => null].
If that is not an option and you know the values you receive will never have numbers as keys you need to change your function to something like the following:
function extend($base, $replacements) {
$base = !is_array($base) ? array() : $base;
$replacements = !is_array($replacements) ? array() : $replacements;
$ret = array();
foreach ($base as $key => $val) {
if (is_int($key)) { // value without key
$ret[$val] = null;
} else {
$ret[$key] = $val;
}
}
return array_replace_recursive($ret, $replacements);
}

Categories