All,
I've created a whole bunch of session variables based on an id. So for example I can have the following variables:
$_SESSION['test_variable_1'];
$_SESSION['test_variable_2'];
$_SESSION['test_variable_3'];
I'd like to read all of these with PHP and basically return a JSON array of the id at the end of the variable. So I'd like 1, 2 and 3 returned in this example. The session variables I wnat to look at will always start with test_variable_ and followed by the ID I want to obtain. What is the best way to do this?
Thanks!
While the better idea would've been to just create a sub-array within the session superglobal, so that you could use $_SESSION['test_variable'][1] and the like, you can use something like preg_grep to scan for these keys:
$keys = array_keys($_SESSION);
$matches = preg_grep('/^test_variable_\d+$/', $keys);
foreach($matches as $key) {
$digit = substr($key, 13); // extract the digit.
echo $_SESSION[$key];
}
Something like this?
$ids = array();
foreach($_SESSION as $var => $value) {
if (strpos($var, 'test_variable_') === 0) {
$ids[] = str_replace('test_variable_', '', $var);
}
}
Related
I'm building a PHP querying a mongodo database. I need to retreive the value of a param from the url, and there is potentially more than one.
An example url would look like this
http://localhost/api/v1/report-01?type=EE&type=ER
How would I retrieve the two values from type.
At the moment I'm only get one, and it's the last one.
if (isset($params["TYPE"]) && in_array($params["TYPE"], ["EE", "ER"])) {
$matchPipeline["TYPE"] = $params["TYPE"];
echo "Printing Variables";
echo $params["TYPE"];
}
The code is only printing ER.
I have no access to the frontend, only the backend so I can't change the URL structure
How would I retrieve the two values from type.
With [ ] after your key
api/v1/report-01?type[]=EE&type[]=ER
You can achieve this by accessing directly to global $_SERVER variable and using preg_match_all, here is an example:
<?php
preg_match_all('/type=(\w+)/', $_SERVER['QUERY_STRING'], $matches);
var_dump($matches[1]);
Just create this function query to array and split the value
function queryToArray($q)
{
$arr = [];
foreach(explode("&", $q) as $l)
{
$b = explode('=', $l);
if ( (is_array($b) && count($b) > 0) )
$arr[$b[0]] = $b[1];
}
return $arr;
}
$arr = parse_url($url_string);
print_r(queryToArray($arr['query']);
Currently I am attempting to call a multidimensional array, using a string as a key or keys. I would like to use the following code, but I think the key is being interpreted as a string. Any solution?
$data= [];
$data['volvo'] = "nice whip";
$test = "['volvo']";
$data['drivers']['mike'] = "decent";
$test2 = "['drivers']['mike']";
echo $data$test; // should read 'nice whip'
echo $data$test2; // should read 'decent'
You just use the variable (which should just be the string and not PHP syntax) in place of the string literal.
$cars = [];
$cars['volvo'] = 'nice whip';
$test = 'volvo';
echo $cars[$test];
If you need a dynamic array access solution, you could also write a function, which does the actual array access like this:
function path($array, $path) {
$path = is_array($path) ? $path : explode('.', $path);
$current = $array;
while (count($path)) {
$seg = array_shift($path);
if (!isset($current[$seg])) throw new Exception('Invalid path segment: ' . $seg);
$current = $current[$seg];
}
return $current;
}
In your case, this would look like this
echo path($data, 'volvo');
echo path($data, 'drivers.mike');
or
echo path($data, ['volvo']);
echo path($data, ['drivers', 'mike']);
The problem is you can't pass multiple levels in one string like that. (If so, PHP would have to start looking for code fragments inside string array keys. And how would it know whether to interpret them as fragments and then split the string key up, or keep treating it as one string??)
Alt 1
One solution is to change the structure of $data, and make it a single level array. Then you supply keys for all the levels needed to find your data, joined together as a string. You would of course need to find a separator that works in your case. If the keys are plain strings then something simple like underscore should work just fine. Also, this wouldn't change the structure of your database, just the way data is stored.
function getDbItem($keys) {
// Use this to get the "old version" of the key back. (I.e it's the same data)
$joinedKey = "['".implode("'],['", $keys)."']";
$joinedKey = implode('_', $keys);
return $data[$joinedKey];
}
// Example
$data = [
'volvo' => 'nice whip',
'drivers_mike' => 'decent'
];
var_dump(getDbItem(['drivers', 'mike'])); // string(6) "decent"
Alt 2
Another way is to not change number of levels in $data, but simply traverse it using the keys passed in:
$tgt = $data;
foreach($keys as $key) {
if (array_key_exists($key, $tgt)) {
$tgt = $tgt[$key];
}
else {
// Non existing key. Handle properly.
}
}
// Example
$keys = ['drivers', 'mike'];
// run the above code
var_dump($tgt); // string(6) "decent"
If i knew the correct terms to search these would be easy to google this but im not sure on the terminology.
I have an API that returns a big object. There is one particular one i access via:
$bug->fields->customfield_10205[0]->name;
//result is johndoe#gmail.com
There is numerous values and i can access them by changing it from 0 to 1 and so on
But i want to loop through the array (maybe thats not the correct term) and get all the emails in there and add it to a string like this:
implode(',', $array);
//This is private code so not worried too much about escaping
Would have thought i just do something like:
echo implode(',', $bug->fields->customfield_10205->name);
Also tried
echo implode(',', $bug->fields->customfield_10205);
And
echo implode(',', $bug->fields->customfield_10205[]->name);
The output im looking for is:
'johndoe#gmail.com,marydoe#gmail.com,patdoe#gmail.com'
Where am i going wrong and i apologize in advance for the silly question, this is probably so newbie
You need an iteration, such as
# an array to store all the name attribute
$names = array();
foreach ($bug->fields->customfield_10205 as $idx=>$obj)
{
$names[] = $obj->name;
}
# then format it to whatever format your like
$str_names = implode(',', $names);
PS: You should look for attribute email instead of name, however, I just follow your code
use this code ,and loop through the array.
$arr = array();
for($i = 0; $i < count($bug->fields->customfield_10205); $i++)
{
$arr[] = $bug->fields->customfield_10205[$i]->name;
}
$arr = implode(','$arr);
This is not possible in PHP without using an additional loop and a temporary list:
$names = array();
foreach($bug->fields->customfield_10205 as $v)
{
$names[] = $v->name;
}
implode(',', $names);
You can use array_map function like this
function map($item)
{
return $item->fields->customfield_10205[0]->name;
}
implode(',', array_map("map", $bugs)); // the $bugs is the original array
Please i want to loop through my table and compare values with an array in a php included file. If there is a match, return the array key of the matched item and replace it with the value of the table. I need help in returning the array keys from the include file and comparing it with the table values.
$myarray = array(
"12aaa"=>"hammer",
"22bbb"=>"pinchbar",
"33ccr"=>"wood" );
in my loop in a seperate file
include 'myarray.inc.php';
while($row = $db->fetchAssoc()){
foreach($row as $key => $val)
if $val has a match in myarray.inc.php
{
$val = str_replace($val,my_array_key);
}
}
So in essence, if my db table has hammer and wood, $val will produce 12aaa and 3ccr in the loop. Any help? Thanks a lot
You are looking for array_search which will return the key associated with a given value, if it exists.
$result = array_search( $val, $myarray );
if ($result !== false) {
$val = $result;
}
your array should look like
$myarray = array(
"hammer"=>"11aaa",
"pinchbar"=>"22bbb",
"wood"=>"33ccr" );
and code
if (isset($myarray[$key])){
//do stuff
}
I think you need the function in_array($val, $myarray);
If you don't want or can't change $myarray structure like #genesis proposed, you can make use of array_flip
include 'myarray.inc.php';
$myarray = array_flip($myarray);
while($row = $db->fetchAssoc()) {
foreach($row as $key => $val) {
if (isset($myarray[$val])) {
// Maybe you should use other variable instead of $val to avoid confusion
$val = $myarray[$val];
// Rest of your code
}
}
}
How can you do this? My code seen here doesn't work
for($i=0;i<count($cond);$i++){
$cond[$i] = $cond[$i][0];
}
It can be as simple as this:
$array = array_map('reset', $array);
There could be problems if the source array isn't numerically index. Try this instead:
$destinationArray = array();
for ($sourceArray as $key=>$value) {
$destinationArray[] = $value[0]; //you may want to use a different index than '0'
}
// Make sure you have your first array initialised here!
$array2 = array();
foreach ($array AS $item)
{
$array2[] = $item[0];
}
Assuming you want to have the same variable name afterwards, you can re-assign the new array back to the old one.
$array = $array2;
unset($array2); // Not needed, but helps with keeping memory down
Also, you might be able to, dependant on what is in the array, do something like.
$array = array_merge(array_values($array));
As previously stated, your code will not work properly in various situation.
Try to initialize your array with this values:
$cond = array(5=>array('4','3'),9=>array('3','4'));
A solution, to me better readable also is the following code:
//explain what to do to every single line of the 2d array
function reduceRowToFirstItem($x) { return $x[0]; }
// apply the trasnformation to the array
$a=array_map('reduceRowTofirstItem',$cond);
You can read the reference for array map for a thorough explanation.
You can opt also for a slight variation using array_walk (it operate on the array "in place"). Note that the function doesn't return a value and that his parameter is passed by reference.
function reduceToFirstItem(&$x) { $x=$x[0]; }
array_walk($cond, 'reduceToFirstItem');
That should work. Why does it not work? what error message do you get?
This is the code I would use:
$inArr;//This is the 2D array
$outArr = array();
for($i=0;$i<count($inArr);$i++){
$outArr[$i] = $inArr[$i][0];
}