Get value out of Array - php

I am trying to get a certain value out of an array.
Example of the array is:
array(2) {
["error"]=>
array(0) {
}
["result"]=>
array(1) {
["open"]=>
array(1) {
["12345-AAAAA-66AAKK"]=>
array(14) {
["inf"]=>
Usually when I want a certain value I would use:
$datawanted=$data[result][open][value];
However, in this case the first array is a variable that always changes (12345-AAAAA-66AAKK), I need to find the value of that.
I tried getting this with reset() and key[0] but this not give the wanted result.
Is there a way to get the output of the first element in the result array?

You can use array_search: http://php.net/manual/de/function.array-search.php
Example:
foreach ($array['result']['open'] as $dynamicKey => $item) {
if ($key = array_search('Value you are looking for', $item) {
$datawanted=$array['result']['open'][$dynamicKey][$key];
}
}

$data[result][open] is not a correct way to access array items.
The token result looks like a constant. PHP searches for a constant named result, cannot find one and triggers a notice. Then it thinks "I guess the programmer wanted to write 'result' (a string, not a constant). I'll convert it as string to them." and uses 'result' instead.
It works but it's a horrible practice. It dates from the prehistory of PHP, 20 years ago and it's not recommended.
After you fix your code to correctly denote the keys of an array, the next step is to pick one of the many PHP ways to access values in the array.
You can get the first value of an array without knowing its key ($data['result']['open']['12345-AAAAA-66AAKK']) by using the function reset():
$datawanted = reset($data['result']['open']);
Or you can use the function array_values() to get only the values of the array (the keys are ignored, the returned array have the values indexed from zero) then your desired data is at position 0 on this array:
$values = array_values($data['result']['open']);
$datawanted = $values[0];
Another option, if you don't need to keep $data for further processing, is to use the PHP function array_shift() to remove the first value from the array and return it. Be warned that this function modifies the array it receives as argument:
$datawanted = array_shift($data['result']['open']);
If you need to process all the values of $data['result']['open'] (and you probably do) then the best way is to use the foreach PHP statement. It allows you to access both the key and the value of each element of the array:
foreach ($data['result']['open'] as $key => $value) {
// $key is '12345-AAAAA-66AAKK'
$datawanted = $value;
}

Related

Trouble with extracting a value from an associative array

I am having some basics trouble with PHP. I want to retrieve an average of a column of numbers from a MYSQL database. I am using SELECT AVG() to get the result in the database. The issue is that what is returned is not a floating number but an associative array with one key:value. This is the kind of thing I am getting back in json form:
array(1) { [0]=> array(1) { ["AVG(enterpriseAppDev.employee.age)"]=> string(7) "54.4538" } }
In my PHP project I am assigning the above to a variable $average.
Can anyone tell me how I can extract the value (54.4538) the the $average variable and use it later on?
I have tried to use a foreach loop to get the value like this
foreach ($average as $x => $x_value) {
$average = $x_value;
return $average;
}
I have also tried to do the standard Deviation in SQL using STDEV and STDEVP but I get an error saying these functions do not exist.
Any help would be much appreciated.
2 problems :
you assign the value $average into the loop whereas it is in the loop parameter... can cause a crash...
so you could use return $x_value without getting it into $average.
then, you don't need a loop here just do this (with NO loop)
return $average[0]['AVG(enterpriseAppDev.employee.age)']
if you really want a loop you can do this :
foreach ($average as $line_number => $line) {
foreach($line as $key => $x_value) {
return $x_value;
}
}
1.
If you'll always get this multidimensional array you can reset the internal pointer of the array with reset to "flatten" the first one. And this should do the trick:
var_dump(reset($average[0]));
// or you can do it twice to get the same result as before
$average = reset($average);
var_dump(reset($average));
2.
But probably you can get a better key name using an alias in your SQL:
SELECT AVG() AS myavg
// so you should end up with a result like:
$queryResult = array(
array(
"myavg" => "54.4538"
)
);
// and get the average
$average = reset($queryResult);
var_dump($average['myavg']);
3.
Or even more weird, if you're using php 5.4 where you can get an array reference directly from a function result:
var_dump(reset($average)['avg']);

Checking the first element of array, regardless of array indexes

I have a need to check if the elements in an array are objects or something else. So far I did it like this:
if((is_object($myArray[0]))) { ... }
However, on occasion situations dictate that the input array does not have indexes that start with zero (or aren't even numeric), therefore asking for $myArray[0] will generate a Notice, but will also return the wrong result in my condition if the first array element actually is an object (but under another index).
The only way I can think of doing here is a foreach loop where I would break out of it right on the first go.
foreach($myArray as $element) {
$areObjects = (is_object($element));
break;
}
if(($areObjects)) { ... }
But I am wondering if there is a faster code than this, because a foreach loop seems unnecessary here.
you can use reset() function to get first index data from array
if(is_object(reset($myArray))){
//do here
}
You could get an array of keys and get the first one:
$keys = array_keys($myArray);
if((is_object($myArray[$keys[0]]))) { ... }
try this
reset($myArray);
$firstElement = current($myArray);
current gets the element in the current index, therefore you should reset the pointer of the array to the first element using reset
http://php.net/manual/en/function.current.php
http://php.net/manual/en/function.reset.php

PHP - Loop an array where only some keys are set explicitely

I have the following array
$a = ["one", "dos" => "two", "three"];
As you see the second element has the key for his value set explicitely, but the other 2 items do not.
I want to loop through the array, but do something different, depending if the key for that item was set explicitly or not. Kinda like this:
foreach($a as $value){
if( has_explicit_key($value) )
// Do something
else
// Do other stuff
}
How can I achieve this?
PS: I guess I could check if the key is an integer, but if the key is set explicitly as an integer, that would not work, right?
try this
foreach($a as $key=>$value){
if( is_int($key) )
// Do something
else
// Do other stuff
}
this is the closest approach since keys are usually, 0,1,2......
In your specific case, you can exploit the fact that elements without explicit string keys automatically receive integer indexes:
$a = ["one", "dos" => "two", "three"];
foreach ($a as $k => $v) {
if (is_int($k)) {
// Do something
} else {
// Do other stuff
}
}
If you allow for the explicit keys to be scalars other than strings (integer, float, boolean, etc), then there is no way (at run-time) to distinguish between non-string keys supplied by the user and integer keys filled in by the parser. Specifically, refer to the PHP source function zend_ast_add_array_element. In that function, when the key is not explicitly given (offset IS_UNDEF), then PHP assigns one with zend_hash_next_index_insert and records no bookkeeping note of that fact.
Now, if you don't mind, and are capable of statically analyzing the data structure, just tokenize or parse the PHP code and see if T_DOUBLE_ARROW precedes the array value. This is probably not worth the effort and only works on static code.
You can loop through the array using
foreach($a as $key => $value) {
/* stuff */
}
To check if the key has been set explicitly can probably only be done by checking if the key is numerical (PHP will assign numerical keys to values without any keys in arrays).
Of course this means that you won't be able to detect a key that was set explicitly and is numeric.
So unless there's some function (which I'm unaware of) this would be the only way.

Calling PHP function in itself

In the following script function clean($data) calls it within it, that I understand but how it is cleaning data in the statement $data[clean($key)] = clean($value);??? Any help is appreciated.. I am trying to figure it out as I am new to PHP. Regards.
if (ini_get('magic_quotes_gpc')) {
function clean($data) {
if (is_array($data)) {
foreach ($data as $key => $value) {
$data[clean($key)] = clean($value);
}
} else {
$data = stripslashes($data);
}
return $data;
}
$_GET = clean($_GET);
$_POST = clean($_POST);
$_REQUEST = clean($_REQUEST);
$_COOKIE = clean($_COOKIE);
}
Your Question:
So if I undertsand correctly you want to know what is the function doing in the line
$data[clean($key)] = clean($value);
The Answer:
See the prime purpose of the function is to remove slashes from string with php's stripslashes method.
If the input item is an array then it tries to clean the keys of the array as well as the values of the array by calling itself on the key and value.
In php arrays are like hashmaps and you can iterate over the key and value both with foreach loop like following
foreach ($data as $key => $value) {....}
So if you want to summarize the algorithm in your code snippet it would be as under
Check if the input is array. If it is not then go to step 4
For each item of array clean the key and value by calling clean method on it (Recursively)
Return the array
clean the input string using stripslashes method
5 return the cleaned input
From my understanding it's not cleaning the key but creates a new element with a clean key while the uncleaned key remains.
$a['foo\bar'] : val\ue
becomes
$a['foo\bar'] : val\ue
$a['foobar'] : value
Someone correct me if im wrong.
Maybe you'll understand the code better if it's put this way:
foreach ($data as $key => $value) {
$key = clean($key); // Clean the key, the
$value = clean($value); // Clean the value
$data[$key] = $value; // Put it in the array that will be returned
}
Assuming you have an array like this:
$_POST = array(0 => 'foo', 1 => array('bar' => 'baz'));
the following will happen:
Call clean($_POST);
call clean 0
call clean 'foo'
$return[0] = 'foo'
call clean 1
call clean 'bar'
call clean 'baz'
$return[1] = array('bar' => 'baz');
You should probably read this: http://www.codewalkers.com/c/a/Miscellaneous/Recursion-in-PHP/
The main purpose of the function is to clean an associative array or a single variable. An associative array is an array where you define keys and values for that keys; so are special arrays used in PHP like $_GET $_POST and so on.
The meaning of "cleaning" is to check whether magic quotes are active - this causes some characters in these arrays to be escaped with backslashes when you post dynamic data to a PHP page.
$_GET["Scarlett"] = "O' Hara" becomes with magic quotes $_GET["Scarlett"] = "O\' Hara"
So if magic quotes are active, the function takes care of this, and slashes are stripped so that the strings retain their correct, not escaped value.
The algorithm checks if the data passed to the function is an array, if not it cleans directly the value.
$string = "Escapes\'in\'a string";
clean($string);
is it an array? No. Then return stripslashes(my data)
$array = array("key\'with\'escapes"=>"value\'with\'escapes", "another\'key"=>"another value");
clean($array)
is it an array? Yes. So cycle through each key/value pair with foreach, take the key and clean it like the first example; then take the value and do the same and put the cleaned versions in the array.
As you see the function has two different behaviours differentiated by that "if" statement.
If you pass an array, you activate the second behaviour that in turns passes couples of strings, not arrays, triggering the first behaviour.
My thought is that this function doesn't work properly, though. Anyone got the same sensation? I have it not tested yet but it seems it's not "cleaning" the key/values in the sense of replacing them, but adds the cleaned versions along the uncleaned ones.

Can items in PHP associative arrays not be accessed numerically (i.e. by index)?

I'm trying to understand why, on my page with a query string,
the code:
echo "Item count = " . count($_GET);
echo "First item = " . $_GET[0];
Results in:
Item count = 3
First item =
Are PHP associative arrays distinct from numeric arrays, so that their items cannot be accessed by index? Thanks-
They can not. When you subscript a value by its key/index, it must match exactly.
If you really wanted to use numeric keys, you could use array_values() on $_GET, but you will lose all the information about the keys. You could also use array_keys() to get the keys with numerical indexes.
Alternatively, as Phil mentions, you can reset() the internal pointer to get the first. You can also get the last with end(). You can also pop or shift with array_pop() and array_shift(), both which will return the value once the array is modified.
Yes, the key of an array element is either an integer (must not be starting with 0) or an associative key, not both.
You can access the items either with a loop like this:
foreach ($_GET as $key => $value) {
}
Or get the values as an numerical array starting with key 0 with the array_values() function or get the first value with reset().
You can do it this way:
$keys = array_keys($_GET);
echo "First item = " . $_GET[$keys[0]];
Nope, it is not possible.
Try this:
file.php?foo=bar
file.php contents:
<?php
print_r($_GET);
?>
You get
Array
(
[foo] => bar
)
If you want to access the element at 0, try file.php?0=foobar.
You can also use a foreach or for loop and simply break after the first element (or whatever element you happen to want to reach):
foreach($_GET as $value){
echo($value);
break;
}
Nope -- they are mapped by key value pairs. You can iterate the they KV pair into an indexed array though:
foreach($_GET as $key => $value) {
$getArray[] = $value;
}
You can now access the values by index within $getArray.
As another weird workaround, you can access the very first element using:
print $_GET[key($_GET)];
This utilizes the internal array pointer, like reset/end/current(), could be useful in an each() loop.

Categories