http_build_query giving me get parameters of the same name [duplicate] - php

This question already has an answer here:
Build query string with indexed array data
(1 answer)
Closed 7 months ago.
I'm sending multiple parameters to another page, and I am using http_build_query() to do this. The following code:
$array = array();
if(!empty($_POST['modelcheck'])){
foreach($_POST['modelcheck'] as $selected){
$array[] = $selected;
}
}
$args = array
(
'pricefrom' => $fromval,
'priceto' => $toval,
'model' => $array
);
$params = http_build_query($args);
$cleanedParams = preg_replace('/%5B(\d+?)%5D/', '', $params);
header("Location: ../page2.php?" . $cleanedParams);
gives me a url:
page2.php?pricefrom=10000&priceto=60000&model=1&model=2
As you can see model is repeated multiple times, I would like the parameters following the first model to be model2, model3.......etc.
I've tried putting it in a for loop:
for ($i=0; $i <count($array) ; $i++) {
$args = array
(
'pricefrom' => $fromval,
'priceto' => $toval,
'model'.$i => $array
);
}
but this just gives me :
page2.php?pricefrom=10000&priceto=60000&model1=1&model1=2

You can use the second parameter in http_build_query to prefix the numerical keys with a string:
$args = array
(
'pricefrom' => $fromval,
'priceto' => $toval
);
$args += $array; // merge the two arrays together
$params = http_build_query($args, 'model', '&'); // use a second arg for prefix.
However, I do not recommend to create separate names for variables like this. Better to use &model[]=1&model[]=2. See Passing arrays as url parameter

There was nothing wrong with your original code except that you broke it with the call to preg_replace.
if(!empty($_POST['modelcheck'])){
foreach($_POST['modelcheck'] as $selected){
$models[] = $selected;
}
}
$args = [
'pricefrom' => $fromval,
'priceto' => $toval,
'model' => $models,
];
$params = http_build_query($args);
header("Location: ../page2.php?" . $params);
Now, in page2.php you just use $_GET['model'] as an array.
<?php
foreach ($_GET['model'] as $model) {
printf('%s<br/>', $model);
}

Your $args variable should look like:
$args = array (
'pricefrom' => $fromval,
'priceto' => $toval,
'model' => $array
);
UPD
Use preg_replace for replace html special chars if you want to use http_build_query with multiple params.
$query = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '[]=', http_build_query($args));
You will receive an array by accessing to $_GET['model']

Related

Use variable with part of array path to output array value

I have an array like so:
$cars = array(
'type' => array(
'brand' => array(
'car' => 'Honda',
),
),
);
And I also have a string like so:
$path = "type][brand][car";
I'd like to return a value of car from $cars array using $path string, but of course this won't work:
echo $cars[$path];
The output I'd like to have is: "Honda". How this should be done?
Here is basicly what I understood you want to achieve in a simple function, that uses the parents array to get a nested value:
<?php
$cars = array(
'type' => array(
'brand' => array(
'car' => 'Honda',
),
),
);
$parents = array('type', 'brand', 'car');
// you could also do:
// $path = "type][brand][car";
// $parents = explode("][", $path);
function GetCar($cars, $parents) {
foreach($parents as $key) {
$cars = $cars[$key];
// echo $key."<br>";
}
return $cars;
}
var_dump(GetCar($cars, $parents)); // OUTPUT: string(5) "Honda"
echo GetCar($cars, $parents); // OUTPUT: Honda
A snippet: https://3v4l.org/OKrQN
I still think, that there is a better solution for what you need in a bigger picture (that I don't know)
Here is the correct answer, I am not just saying that as I've done this many times before. And I have really analyzed the problem etc...
$array = array(
'type' => array(
'brand' => array(
'car' => 'Honda',
),
),
);
$path = "type][brand][car";
function transverseGet($path, array $array, $default=null){
$path = preg_split('/\]\[/', $path, -1, PREG_SPLIT_NO_EMPTY);
foreach($path as $key){
if(isset($array[$key])){
$array = $array[$key];
}else{
return $default;
}
}
return $array;
}
print_r(transverseGet($path, $array));
Output
Honda
Sandbox
The trick is, every time you find a key from the path in the array you reduce the array to that element.
if(isset($array[$key])){
$array = $array[$key];
At the end you just return whatever is left, because your out of path parts to run so you can assume its the one you want.
If it doesn't find that key then it returns $default, you can throw an error there if you want.
It's actually pretty simple to do, I have this same setup for set,get,isset - key transversal
Like a Ninja ()>==<{>============>
If you require to use that specific structure you could do something like this:
$path = "type][brand][car";
$path_elements = explode("][", $path);
This way you get an array with each of the components required, and you'll have to do something like:
echo $cars[$path_elements[0]][$path_elements[1]][$path_elements[2]];
Of course that is a little bit too static and needs the same 3 level element structure.
May be this can resolve the problem :
strong text$cars = array( 'type' => array(
'brand' => array(
'car' => 'Honda',
), ), );
$path = "type][brand][car";
preg_match_all('/[a-z]+/', $path,$res);
$re = $res[0];
echo $cars[$res[0][$res[1]][$res[2]];

PHP - array key within array value

I have a PHP array like this:
$arr = array(
'id' => 'app.settings.value.id',
'title' => 'app.settings.value.title',
'user' => 'app.settings.value.user'
);
I want to remove '.id', '.title' and '.user' in the array values. I want to insert the key of this array at the end of the value. I know, that I can get an array key by passing an array and a value to 'array_search', but I want the key within this one array definition - at the end of it's value. Is this possible?
I don't like this, but I guess it's simple and works:
$arr = array(
'id' => 'app.settings.value',
'title' => 'app.settings.value',
'user' => 'app.settings.value'
);
$result = array();
foreach ($arr AS $key => $value) {
$result[$key] = $value . '.' . $key;
}
You're storing app.settings.value which is the same for all array items, so personally I'd prefer:
$arr = array(
'id',
'title',
'user'
);
function prepend_key($key)
{
return 'app.settings.value.' . $key;
}
$result = array_map('prepend_key', $arr);
With $result containing:
array(
'app.settings.value.id',
'app.settings.value.title',
'app.settings.value.user'
);
At the end of the day, either works :)

Get the sub array in a bidimensional array having a particular key/value pair

I have a large PHP array, similar to:
$list = array(
array(
'id' = '3243'
'link' = 'fruits'
'lev' = '1'
),
array(
'id' = '6546'
'link' = 'apple'
'lev' = '2'
),
array(
'id' = '9348'
'link' = 'orange'
'lev' = '2'
)
)
I want to get the sub-array which contains a particular id.
Currently I use the following code:
$id = '3243'
foreach ($list as $link) {
if (in_array($id, $link)) {
$result = $link;
}
}
It works but I hope there is a better way of doing this.
You can
write $link['id']==$id instead of in_array($id, $link) whitch will be less expensive.
add a break; instruction after $result = $link; to avoid useless loops
While this answer wouldn't have worked when the question was asked, there's quite an easy way to solve this dilemma now.
You can do the following in PHP 5.5:
$newList = array_combine(array_column($list,'id'),$list);
And the following will then be true:
$newList[3243] = array(
'id' = '3243';
'link' = 'fruits'; etc...
The simplest way in PHP 5.4 and above is a combination of array_filter and the use language construct in its callback function:
function subarray_element($arr, $id_key, $id_val = NULL) {
return current(array_filter(
$arr,
function ($subarr) use($id_key, $id_val) {
if(array_key_exists($id_key, $subarr))
return $subarr[$id_key] == $id_val;
}
));
}
var_export(subarray_element($list, 'id', '3243')); // returns:
// array (
// 'id' => '9348',
// 'link' => 'orange',
// 'lev' => '2',
// )
current just returns the first element of the filtered array.
A few more online 3v4l examples of getting different sub-arrays from OP's $list.

Getting values from a just created array

I have this function that creates an array of values:
function getPostInfo($query, $fields, $type, $limit, $since, $until, $lang, $stopwords, $identifier) {
$url = file_get_contents('https://graph.facebook.com/search?q='.spaces($query).'&fields='.$fields.'&limit='.$limit.'&until='.$until);
$j = json_decode($url);
foreach($j->data as $v) {
if ($v->type == $type) {
$author_id = $v->from->id;
$original_id = $v->id;
$post_url = getPostUrl($original_id, $author_id);
//$description = stopWords($v->message);
$description = $v->message;
$pub_date = $v->created_time;
$post[] = array(
'author_id' => $author_id,
'orginal_id' => $original_id,
'post_url' => $post_url,
'descritpion' => $description,
'pub_date' => $pub_date
);
}
}
return $post;
}
When I call this function like this:
$post = getPostInfo($query, $fields, $type, $limit, $since, $until, $lang, $stopwords, $identifier);
echo var_dump($post);
The array returns correctly.
But If I try to search for a specific value of the array like this:
echo var_dump($post['author_id']);
it always returns NULL.
What is wrong in my code?
Thank you for the help.
I believe if you change
$post[] = array(
to
$post = array(
it should fix the issue.
Can you display the result of your var_dump($post)?
The assignment in the function is wrong. You need to use this code (strip the [] parentesys)
$post = array(
'author_id' => $author_id,
'orginal_id' => $original_id,
'post_url' => $post_url,
'descritpion' => $description,
'pub_date' => $pub_date
);
or access the index you need by
$post[0]['author_id']
In this situation you should rely on var_dump or var_export to investigate on how your data structure is layed down. I prefer the second one as is output is similar to
the code needed to obtain the data and it is easier to find errors.
In the manual, you will see that var_dump returns void and if you try to echo its result you will not obtain what expected
echo var_dump($post['author_id']);
strip the echo and you will get fine with you output (use var_export or ob_start if you need to get a string with the output).
EDIT
As in the comment, the $post variable is an array of arrays, the above notes are still valid as you need to access the various author_id index prefixing the index of the array containing it. If you need to get all the id of the authors in a place then you can resort to array map:
$authors = array_map(function($x){return $x['author_id'];},$post);
If you where was trying to obtains something else you should better explain what the expected result was.
Like Eineki says you're trying to access an element of the array that doesn't exists. If you do a var_dump on the $post variable like this:
var_dump($post);
You should see that the $post array is actually a numerical array starting at [0] and each item includes a sub-array containing your data.
What you've created is a two dimensional array, an array of arrays, one array for each item in your $j->data array.
You can iterate through the array like this:
foreach ($post as $key => $value)
{
var_dump($value);
var_dump($value['author_id'];
}
Let's make this really fun and easy.
function getPostInfo($query, $fields, $type, $limit, $since, $until, $lang, $stopwords, $identifier) {
//your code
}
}
return (object)$post;
}
then when you access your returned object it's just
$post->author_id;
this is just for fun but it works well. Converts an array into a standard object. :)
ok let's get serious ;)
Initialize the array before the foreach statement ($posts = array()), then assign the variables to the array keys ($post['key'] = $value) then assign each set of array keys to the array ($posts[] = $post). I hope this helps.
function getPostInfo($query, $fields, $type, $limit, $since, $until, $lang, $stopwords, $identifier) {
$url = file_get_contents('https://graph.facebook.com/search?q='.spaces($query).'&fields='.$fields.'&limit='.$limit.'&until='.$until);
$j = json_decode($url);
$posts = array(); //initialize array here
foreach($j->data as $v) {
if ($v->type == $type) {
//create variables
$author_id = $v->from->id;
$original_id = $v->id;
$post_url = getPostUrl($original_id, $author_id);
//$description = stopWords($v->message);
$description = $v->message;
$pub_date = $v->created_time;
//asign values to array keys
$post['author_id'] = $author_id;
$post['orginal_id'] = $original_id;
$post['post_url'] = $post_url;
$post['descritpion']= $description;
$post['pub_date'] = $pub_date;
//asign $post to the $posts array to create an array of $post(s)
$posts[] = $post;
}
}
return $posts;
}
I think this might help accomplish what you want.
the following code is the reference used. It is from the examples from the Array section in the PHP manual.
<?php
// This:
$a = array( 'color' => 'red',
'taste' => 'sweet',
'shape' => 'round',
'name' => 'apple',
4 // key will be 0
);
$b = array('a', 'b', 'c');
// . . .is completely equivalent with this:
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name'] = 'apple';
$a[] = 4; // key will be 0
$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';
// After the above code is executed, $a will be the array
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round',
// 'name' => 'apple', 0 => 4), and $b will be the array
// array(0 => 'a', 1 => 'b', 2 => 'c'), or simply array('a', 'b', 'c').
?>

PHP Api - Results/Array question

I have been looking around for PHP tutorials and I found a very detailed one that have been useful to me.
But now, I have a question. The results showed by the API are stored into a $results array. This is the code (for instance):
$fetch = mysql_fetch_row($go);
$return = Array($fetch[0],$fetch[1]);
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
My question is.. I want to display the last 10 news.. how do I do this? On normal PHP / mySQL it can be done as:
while($var = mysql_fetch_array($table)) {
echo "do something"
}
How can I make it so the $results can print multiple results?
I have tried like:
while($var = mysql_fetch_array($table)) {
$results = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
}
But this only shows me one result. If I change the $results .= Array(...) it gives error.
What can I do?
Thanks!
Edit
My function to read it doesn't read when I put it the suggested way:
function write(XMLWriter $xml, $data){
foreach($data as $key => $value){
if(is_array($value)){
$xml->startElement($key);
write($xml, $value);
$xml->endElement();
continue;
}
$xml->writeElement($key, $value);
}
}
write($xml, $results);
$results[] = Array(
'news' => Array (
'id' => $return[0],
'title' => $return[1]
));
That should do it.
If you are familiar with arrays, this is the equivalent of an array_push();
array_push() treats array as a stack, and pushes the passed variables onto the end of array. The length of array increases by the number of variables pushed. Has the same effect as:
<?php
$array[] = $var;
?>
Use [] to add elements to an array:
$results = array();
while($var = mysql_fetch_array($table)) {
$results[] = Array(
'news' => Array (
'id' => $var[0],
'title' => $var[1]
));
}
}
You can then loop through the $results array. It's not an optimal structure but you should get the hang of it with this.

Categories