Generate URL with parameters from an array - php

I need to take an array like I have below:
$subids = Array
(
[s1] => one
[s2] => two
[s3] => three
[s4] => four
[s5] => five
[s6] => six
)
and generate a URL such as http://example.com?s1=one&s2=two&s3=three=&s4=four&s5=five&s6=six
All of the subids are not always defined, so sometimes s3 may not be defined, so it shouldn't be appended to the URL. Additionally, whatever the first subid is, it has to have the ? preceding it instead of the ampersand (&)
So if the array is just:
$subids = Array
(
[s2] => two
[s6] => six
)
then the URL needs to be http://example.com?s2=two&s6=six
I have the following so far:
$url = 'http://example.com'
foreach ($subids AS $key => $value) {
$result[$id]['url'] .= '&' . $key . '=' . $value;
}
However, I'm not sure what the best way would be to append the ? at the beginning of the first key/value pair.
I feel like there's a PHP function to help with this but I'm not finding much. I'm using Codeigniter if there's anything I can use that is provided by CI.

All you need is http_build_query:
$final = $url . "?" . http_build_query($subids);

You can use with http_build_query() function.
Example from php.net:
<?php
$data = array(
'foo' => 'bar',
'baz' => 'boom',
'cow' => 'milk',
'php' => 'hypertext processor',
);
echo http_build_query( $data ) . "\n";
echo http_build_query( $data, '', '&' );
?>
And output this lines:
foo=bar&baz=boom&cow=milk&php=hypertext+processor
foo=bar&baz=boom&cow=milk&php=hypertext+processor
You can read from the source: http://www.php.net/manual/en/function.http-build-query.php
BTW, If you use with WordPress, you can this function: http://codex.wordpress.org/Function_Reference/add_query_arg
Have fun. :)

You can use http_build_query() function but be sure to do some validations if the url comes from an external function for example.
$url = getUrlSomewhere();
$params = ['param' => 'value', 'param2' => 'value2'];
$queryParams = http_build_query($params);
if (strpos($url, '?') !== FALSE) {
$url .= '&'. $queryParams;
} else {
$url .= '?'. $queryParams;
}
If you have PECL extension you can use http_build_url() which already takes into account if you are adding more parameters to a pre-existent URL or not among other validations it does.

Related

Ignore parts of URL

I'm working on a simple script to scrape the channel ID of a YouTube URL.
For example, to get the channel ID on this URL:
$url = 'https://youtube.com/channel/UCBLAoqCQyz6a0OvwXWzKZag';
I use regex:
preg_match( '/\/channel\/(([^\/])+?)$/', $url, $matches );
Works fine. But if the URL has any extra parameters or anything else after the channel ID, it doesn't work. Example:
https://youtube.com/channel/UCBLAoqCQyz6a0OvwXWzKZag?PARAMETER=HELLO
https://youtube.com/channel/UCBLAoqCQyz6a0OvwXWzKZag/RANDOMFOLDER
etc...
My question is, how can I adjust my regex so it works with those URLs? We don't want to match with the random parameters etc
Feel free to test my ideone code.
You can fix the regexps in the following way:
$preg_entities = [
'channel_id' => '\/channel\/([^\/?#]+)', //match YouTube channel ID from url
'user' => '\/user\/([^\/?#]+)', //match YouTube user from url
];
See the PHP demo.
With [^\/?#]+ patterns, the regex won't go through the query string in an URL, and you will get clear values in the output.
Full code snippet:
function getYouTubeXMLUrl( $url) {
$xml_youtube_url_base = 'h'.'ttps://youtube.com/feeds/videos.xml';
$preg_entities = [
'channel_id' => '\/channel\/([^\/?#]+)', //match YouTube channel ID from url
'user' => '\/user\/([^\/?#]+)', //match YouTube user from url
];
foreach ( $preg_entities as $key => $preg_entity ) {
if ( preg_match( '/' . $preg_entity . '/', $url, $matches ) ) {
if ( isset( $matches[1] ) ) {
return [
'rss' => $xml_youtube_url_base . '?' . $key . '=' . $matches[1],
'id' => $matches[1],
'type' => $key,
];
}
}
}
}
Test:
$url = 'https://youtube.com/channel/UCBLAoqCQyz6a0OvwXWzKZag?PARAMETER=HELLO';
print_r(getYouTubeXMLUrl($url));
// => Array( [rss] => https://youtube.com/feeds/videos.xml?channel_id=UCBLAoqCQyz6a0OvwXWzKZag [id] => UCBLAoqCQyz6a0OvwXWzKZag [type] => channel_id )
$url = 'https://youtube.com/channel/UCBLAoqCQyz6a0OvwXWzKZag/RANDOMFOLDER';
print_r(getYouTubeXMLUrl($url));
// => Array( [rss] => https://youtube.com/feeds/videos.xml?channel_id=UCBLAoqCQyz6a0OvwXWzKZag [id] => UCBLAoqCQyz6a0OvwXWzKZag [type] => channel_id )

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

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']

How to get value from nested array using string

I have an array like this:
$temp = array( '123' => array( '456' => array( '789' => '0' ) ),
'abc' => array( 'def' => array( 'ghi' => 'jkl' ) )
);
I have a string like this:
$address = '123_456_789';
Can I get value of $temp['123']['456']['789'] using above array $temp and string $address?
Is there any way to achieve this and is it good practice to use it?
This is a simple function that accepts an array and a string address where the keys are separated by any defined delimiter. With this approach, we can use a for-loop to iterate to the desired depth of the array, as shown below.
<?php
function delimitArray($array, $address, $delimiter="_") {
$address = explode($delimiter, $address);
$num_args = count($address);
$val = $array;
for ( $i = 0; $i < $num_args; $i++ ) {
// every iteration brings us closer to the truth
$val = $val[$address[$i]];
}
return $val;
}
$temp = array("123"=>array("456"=>array("789"=>"hello world")));
$address = "123_456_789";
echo delimitArray($temp,$address,"_");
?>
Hello if string $address = '123_456_789'; is your case then you can use explode function to split the string by using some delimeter and you can output your value
<?php
$temp = array('123' => array('456' => array('789' => '0')),
'abc' => array('def' => array('ghi' => 'jkl')),
);
$address = '123_456_789';
$addr = explode("_", $address);
echo $temp[$addr[0]][$addr[1]][$addr[2]];
Using this array library you can easily get element value by either converting your string to array of keys using explode:
Arr::get($temp, explode('_', $address))
or replacing _ with . to take advantage of dot notation access
Arr::get($temp, str_replace('_', '.', $address))
Another benefit of using this method is that you can set default fallback value to return if element with given keys does not exists in array.

Stripping out numerical array keys from var_export

I want to do var_export() and strip out all numerical array keys on an array. My array outputs like so:
array (
2 =>
array (
1 =>
array (
'infor' => 'Radiation therapy & chemo subhead',
'PPOWithNotif' => '',
'PPOWithOutNotif' => 'Radiation therapy & chemo PPO amount',
'NonPPO' => 'Radiation therapy & chemo Non PPO amount',
),
),
3 =>
array (
1 =>
array (
'infor' => 'Allergy testing & treatment subhead',
'PPOWithNotif' => '',
'PPOWithOutNotif' => 'Allergy testing & treatment PPO amount',
'NonPPO' => 'Allergy testing & treatment Non PPO amount',
),
)
)
By doing this I can shuffle the array values however needed without having to worry about numerical array values.
I've tried using echo preg_replace("/[0-9]+ \=\>/i", '', var_export($data)); but it doesn't do anything. Any suggestions? Is there something I'm not doing with my regex? Is there a better solution for this altogether?
You have to set the second parameter of var_export to true, or else there is no return value given to your preg_replace call.
Reference: https://php.net/manual/function.var-export.php
return
If used and set to TRUE, var_export() will return the variable
representation instead of outputting it.
Update: Looking back on this question, I have a hunch, a simple array_values($input) would have been enough.
May not be the answer you are looking for, but if you have a one level array, you can use the function below. It may not be beautiful, but it worked well for me.
function arrayToText($array, $name = 'new_array') {
$out = '';
foreach($array as $item) {
$export = var_export($item, true);
$export = str_replace("array (\n", '', $export);
$export = substr($export, 0, -1);
$out .= "[\n";
$out .= $export;
$out .= "],\n";
}
return '$' . $name . ' = ' . "[\n" . substr($out, 0, -2) . "\n];";
}
echo arrayToText($array);
This package does the tricks
https://github.com/brick/varexporter
use Brick\VarExporter\VarExporter;
echo VarExporter::export([1, 2, ['foo' => 'bar', 'baz' => []]]);
Output:
[
1,
2,
[
'foo' => 'bar',
'baz' => []
]
]
Why not just use array_rand:
$keys = array_rand($array, 1);
var_dump($array[$keys[0]]); // should print the random item
PHP also has a function, shuffle, which will shuffle the array for you, then using a foreach loop or the next / each methods you can pull it out in the random order.

How to combine the keys and values of an array in PHP

Say I have an array of key/value pairs in PHP:
array( 'foo' => 'bar', 'baz' => 'qux' );
What's the simplest way to transform this to an array that looks like the following?
array( 'foo=bar', 'baz=qux' );
i.e.
array( 0 => 'foo=bar', 1 => 'baz=qux');
In perl, I'd do something like
map { "$_=$hash{$_}" } keys %hash
Is there something like this in the panoply of array functions in PHP? Nothing I looked at seemed like a convenient solution.
Another option for this problem: On PHP 5.3+ you can use array_map() with a closure (you can do this with PHP prior 5.2, but the code will get quite messy!).
"Oh, but on array_map()you only get the value!".
Yeah, that's right, but we can map more than one array! :)
$arr = array( 'foo' => 'bar', 'baz' => 'qux' );
$result = array_map(function($k, $v){
return "$k=$v";
}, array_keys($arr), array_values($arr));
function parameterize_array($array) {
$out = array();
foreach($array as $key => $value)
$out[] = "$key=$value";
return $out;
}
A "curious" way to do it =P
// using '::' as a temporary separator, could be anything provided
// it doesn't exist elsewhere in the array
$test = split( '::', urldecode( http_build_query( $test, '', '::' ) ) );
chaos' answer is nice and straightfoward. For a more general sense though, you might have missed the array_map() function which is what you alluded to with your map { "$_=$hash{$_}" } keys %hash example.

Categories