PHP Variable Variable inside []'s - php

Thanks for the help below, however, I'm still having some problems, I'll try and explain further:
I have a variable as follows:
$value['questions'];
Now, I need to do a check in a loop, so I have this piece of code in the loop:
if($results[$value['questions']]==4){blah blah blah};
but the problem I am having is that the value of $value['questions'] is q1 but I need the q1 to be a string (i.e. inside quotes '') in the $results section of the code, so the $results element should look like this...
if($results['q1']==4){blah blah blah};
currently it looks like this
if($results[q1]==4){blah blah blah};
Make sense?
Thanks again for the help.
Hi all,
I hope there is a simple solution!
I have a variable:
$results['q1'];
Is it possible to have the 'q1' element as a variable, something like this:
$results['$i[question]'];
Have not been able to find a solution on Google and researching the PHP manuals...
Anyone got a suggestion/ solution?
Thanks,
Homer.

Yes, it is possible to use a variable as indice, when accessing an array element.
As an example, consider this portion of code :
$results = array(
'a' => 'sentence a',
'b' => 'hello !',
);
$indice = 'a';
echo $results[$indice];
Which will give the following output :
sentence a
Here, $indice is a quite simple variable, but you could have used whatever you wanted between the [ and ], like, for instance :
functions : $results[ my_function($parameter) ]
array element : $result[ $my_array['indice'] ]
Which seems to be what you want to do ?
object property : $result[ $obj->data ]
...
Basically, you can use pretty much whatever you want there -- as long as it evaluates to a scalar value (i.e. a single integer, string)
In your specific case, you could have $results declared a bit like this :
$results = array(
'q1' => 'first question',
'q2' => 'second question',
);
And $i would be declared this way :
$i = array(
'question' => 'q1'
);
Which means that $i['question'] would be 'q1', and that the following portion of code :
echo $results[ $i['question'] ];
Would get you this output :
first question
Edit : To answer the specific words you used in the title of your question, you could also use what's called variable variable in PHP :
$variable = 'a';
$indice = 'variable';
echo $results[ $$indice ];
Here :
$indice is 'variable'
and $$indice is 'a'
which means you'll get the same output as before
And, of course, don't forget to read the Arrays section of the PHP manual.
The Why is $foo[bar] wrong? paragraph could be of interest, especially, considering the example you firt posted.
Edit after the edit of the OP :
If $value['questions'] is 'q1', then, the two following portions of code :
if($results[$value['questions']]==4){blah blah blah}
and
if($results['q1']==4){blah blah blah}
should do exactly the same thing : with $results[$value['questions']], the $value['questions'] part will be evaluated (to 'q1') before the rest of the expression, and that one will be the same as $results['q1'].
As an example, the following portion of code :
$results = array(
'q1' => 4,
'q2' => 6,
);
$value = array('questions' => 'q1');
if($results[$value['questions']]==4) {
echo "4";
}
Outputs 4.

You can do:
$results[$i['question']];
This will first access the array $i to get the value corresponding to the key 'question'. That value will be used as the key into the array $results.
Your way: $results['$i[question]'];
is actually trying to get the value corresponding to the key '$i[question]' in the array $results. Since the key is in single quote, variable interpolation does not happen and the entire string is treated literally.
Alternatively you can also do:
$results["$i[question]"]; // using double quotes also works.
Example:
$arr1 = array('php' => 'zend', 'java' => 'oracle');
$arr2 = array('p' => 'php', 'j' => 'java');
echo $arr1[$arr2['p']]; // prints zend.
echo $arr1["$arr2[p]"]; // prints zend.

<?php
$result['q1'];
// is equivalent to
$index = 'q1';
$result[ $index ];
Now $index can be as complex as you want it to be. For example something like this is also possible:
$result[ 'q' . round( $someArray[$i] / 2 ) ];

CODE
<?php
$results = array(
'q1' => 'This is a result called q1.',
'q2' => 'So, can you access this?',
'$i[question]' => 'This is a result called $i[question]',
);
$i = array(
'question' => 'q2',
'answer' => 'Yes.'
);
echo '<pre>';
echo $results['q1'] . "\n"; // Using Array's is easy -
echo $results['$i[question]'] . "\n"; // all you gotta do is make sure
echo $results[$i['question']] . "\n"; // that you understand how
echo $i['answer']; // the keys work.
?>
OUTPUT
This is a result called q1.
This is a result called $i[question]
So, can you access this?
Yes.

Related

Access array where key is a variable

$furtherKeys = "['book']['title']";
echo $this->json['parent'] . $furtherKeys;
This breaks. Is there anyway to do something like this?
I know you could explode $furtherKeys, count it, and setup a loop to achieve this, but I'm just curious if there is a direct way to concatenate an array with key names stored in a variable and have it work.
I want to use it for populating input field values from a json file. If I set a data-variable for each input field like:
<input type="text" data-keys="['book']['title']">
I could get the value of the data-variable, then just slap it onto the json object, and populate the value.
Thanks!
You can simply parse your build up array access using eval(). See my exaple here:
$example = array(
'foo' => array(
'hello' => array(
'world' => '!',
'earth' => '?'
)
),
'bar' => array());
// your code goes here
$yourVar = null;
$access = "['foo']['hello']['world']";
$actualAccesEvalCode = '$yourVar = $example'.$access.';';
eval($actualAccesEvalCode);
echo 'YourVal now is '.$yourVar;
Yet, i think it is better to use iteration. If $this->json['parent'] actually is an array, you write a recursive function to give you the result of the key.
See this ideone work here:
<?php
$example = array(
'foo' => array(
'hello' => array(
'world' => '!',
'earth' => '?'
)
),
'bar' => array());
function getArrayValueByKeyString($array,$keystring) {
$dotPosition = stripos ($keystring , '.' );
if($dotPosition !== FALSE) {
$currentKeyPart = substr($keystring, 0, $dotPosition);
$remainingKeyPart = substr($keystring, $dotPosition+1);
if(array_key_exists($currentKeyPart, $array)) {
return getArrayValueByKeyString(
$array[$currentKeyPart],
$remainingKeyPart);
}
else {
// Handle Error
}
}
elseif (array_key_exists($keystring, $array)) {
return $array[$keystring];
}
else {
// handle error
}
}
echo '<hr/>Value found: ' . getArrayValueByKeyString($example,'foo.hello.world');
Although I don't know how to do this with both book and title at the same time, it is possible to use variables as key names using curly braces.
// SET UP AN ARRAY
$json = array('parent' => array('book' => array('title' => 'The Most Dangerous Game')));
// DEFINE FURTHER KEYS
$furtherKeys1 = "book";
$furtherKeys2 = "title";
// USE CURLY BRACES TO INSERT VARIABLES AS KEY NAMES INTO YOUR PRINT STATEMENT
print "The Parent Book Title Is: ".$json['parent']{$furtherKeys1}{$furtherKeys2};
This outputs:
The Parent Book Title Is: The Most Dangerous Game

Creating a link with implode only makes one array item a link?

$fidimp = implode('"', $fidarr);
$friendsimp = implode('<a href="../profile?id=', $funamearr);
$impglue = '</a><br />' . $fidimp . '>';
echo('<a href="../profile?id=' . $fidimp . '>' . implode('</a><br />', $funamearr));
This is the code I'm working with.
$funamearr has 2 values in it: "Conner" and "Rach667"
$fidarr has 2 values in it as well: "2" and "3" (the user's id's)
When this code is run, it only makes "Conner" a link (it works, by the way) How can I make it so that "Rach667" shows up as a link too?
First build an associative array from your ids to your names, then create an array of links and implode it, something like:
<?php
$funamearr = array( "Conner", "Rach667" );
$fidarr = array( 2, 3 );
$users = array_combine($fidarr, $funamearr);
foreach($users as $id => $name) {
$links[] = sprintf('%s', $id, $name);
}
echo implode('<br/>', $links);
Well I don't recommend using implode in this case but as said by LokiSinclair to use a loop.
<?php
foreach($funamearr as $key => $value) {
echo '' . $value . '<br/>";
}
This case assumes that the array keys of $funamearr and $fidarr match with eachother.
Outside the code I would make two tips.
1 Use usefull variable names.
$funamearr is not telling me much, except the arr part because it probably is an array. I would recommand $usernames (multiple so array ;)
2 Keep data together
No we have to hope that the keys are the same. but if you keep the data at the same level we won't and ofter easier in use
ie
array(
array(
'id' => 1,
'name' => 'test',
),
array(
'id' => 2,
'name' => 'test_name_2',
),
)

Conditional statement in an json encoded array

I'm showing a "Review Your Order:" part of a page with the success callback of a json_encode array. I probably said that completely wrong in technical terms but hopefully you can see what I'm trying to do.
Part of the PHP processing page...
$results = array(
'roomname' => $_POST['roomX'],
'qty' => $_POST['qtyX'],
and I want the results to be returned as...
Room Name: Whatever is returned. (notice the label "Room Name: ")
But I only want the label to show IF the POST has a value assigned.
Example of how I think it should look but it's not working..
$results = array(
'roomname' => if (!$_POST['roomX']=='' { echo 'Room Name: ' .$_POST['roomX'];},
Does that make sense? There are dozens of options for each order and I don't want "Label: " in front of a bunch of values that are empty.
EDIT: Added code from answer below.
// beginning of array
$results = array(
'roomname' => $_POST['roomX'],
'qty' => $_POST['qtyX'],
// more code...
// end of array.. remember not to have a comma on this last one.
);
// pasted answer between the array ending and the json_encode line.
if ($_POST['roomX'] != ''){
$results['roomname'] = "Room Name: ".$_POST['roomX'];
}
$json = json_encode($results);
echo $json;
here is one way, you can user a Ternary operation
$results = array(
'roomname' => $_POST['roomX']==''? 'Room Name: '.$_POST['roomX']: '',
);
this will add a blank string if the value is empty
the other way will be to just add the value later;
$results = array(...);
if ($_POST['roomX'] != ''){
$results['roomname'] = $_POST['roomX']
}
$results = array();
if (isset($_POST['roomX'])) {
$results[] = array(...);
}
if there's no post value, you just end up with an empty array.
you can make an if statement before assigning any data to roomname like so
$result = array(
'roomname' => ($_POST['roomX'] !== '')? 'Room name: '.$_POST['roomX']:''
);
The thing I used here is a shortend if statement and works as following: (if statement)? true : false;
I hope this will help you.

Search for [ ] and replace everything between it

I have a template file that uses the structure
[FIRSTNAME]
[LASTNAME]
etc etc.... and I will be doing a search and replace on it. One thing that I would like to do is that when the template get's sent back, IF I haven't stipulated, [FIRSTNAME].... it still shows in the template... I would like to make it NULL IF I haven't stipulated any data to that variable.
in my code i'm using the FILE_GET_CONTENTS
$q = file_get_contents($filename);
foreach ($this->dataArray as $key => $value)
{
$q = str_replace('['.$key.']', $value, $q);
}
return $q;
So once that loop is over filling in the proper data, I need to do another search and replace for any variables left using, [FIRSTNAME]
I hope this makes sense any someone can steer me in the right direction.
Cheers
It sounds like you just want to add a line like:
$q = preg_replace('/\[[^\]]*\]/', '' , $q);
After all your defined substitutions, to eliminate any remaining square-bracketed words.
If you want to be concise, you can replace the whole function with a variation of the "one line template engine" at http://www.webmasterworld.com/php/3444822.htm, with square brackets instead of curlies.
You can actually pass arrays into the str_replace function as arguments.
$keys = array(
'FIRSTNAME',
'LASTNAME'
):
$replacements = array(
'George',
'Smith'
);
str_replace($keys, $replacements, $input);
And if you want to remove first name if its blank, why don't you just add it to the key => replacement array with a value of ''?
$this->dataArray['FIRSTNAME'] = '';
or something like
if (!isset($this->dataArray['FIRSTNAME'])) {
$this->dataArray['FIRSTNAME'] = '';
}

variables inside variables

Ok this might sound like a dumb question but bear with me. I am trying to make it so that when people go to example.php?id=1, example.php?id=2, example.php?id=3 etc they see different data called from an included file filling in the blanks.
I have a variable called $offername and I want to display $offer1name, $offer2name, $offer3name in that space, depending on what $_GET['id'] says. Ideally, when someone goes to example.php?id=2, $offername will equal $offer2name.
I want to do something like this:
$offername = $offer.$_GET['id'].name
But of course that doesn't work. What should I do?
A much cleaner solution is to just use multidimensional arrays.
e.g., instead of
$offername = ${offer.$_GET['id'].name};
use
$offername = $offer[$_GET['id']]['name'];
and define $offer like so:
$offer = array(
1 => array(
'name' => 'firstoffer',
),
2 => array(
'name' => 'secondoffer',
),
3 => array(
'name' => 'thirdoffer',
),
);
I find variable variables difficult to read, and most of the time when I see them used, an array would be much better.
This should work:
$var = 'offer' . $_GET['id'] . 'name';
$offername = $$var;
See the page on variable variables for more.
PHP can use variable variables
So you can have $offer_variable_name = 'offer' . $_GET['id'] . 'name';
And then use something like $offername = $$offer_variable_name.
You can in addition to the other solutions do:
$offername = ${'offer' . $_GET['id'] . 'name'};

Categories