URL to Array in PHP - php

I don't know how to make this working. I want to make arrays from URL:
index.php?address=someaddress&telephone=12345&customer=Customer Name&p_name[0]=ProductOne&p_name[1]=ProductTwo&p_price[0]=1&p_price[1]=10&p_name[2]...
There is an api, which is working like this:
$api‐>addItem(array(
'name' => 'ProductOne',
'price' => '123',
));
$api­‐>addItem(array(
'name' => 'ProductTwo',
'price' => '32',
));
Is there any way to make arrays like this (=api request $api->addItem(array) from the URL? $api­‐>addItem(array can be used multiple times.

EDIT: Thanks dqhendricks and Rocket for pointing out that you can use parse_str() to do the same thing.
$q = parse_str(parse_url($url, PHP_URL_QUERY));
Or you could use this (the long way):
function parse_query($var) {
$var = parse_url($var, PHP_URL_QUERY);
$var = html_entity_decode($var);
$var = explode('&', $var);
$arr = array();
foreach($var as $val) {
$x = explode('=', $val);
$arr[$x[0]] = $x[1];
}
unset($val, $x, $var);
return $arr;
}
Use like this:
$url = "http://someurl.com/click?z=26&a=761";
print_r(parse_query($url));

Do you have control over the URL? If so, I'd change how you send your values.
Instead of:
name1=ProductOne&price1=123&name2=ProductTwo&price2=32
I'd use:
name[]=ProductOne&price[]=123&name[]=ProductTwo&price[]=32
The [] turn them into arrays, meaning $_GET['name'] is now an array. then you can foreach over it.
foreach($_GET['name'] as $k=>$v){
$api->addItem(array(
'name' => $v,
'price' => $_GET['price'][$k]
));
}

// extract the query from the url string
$url = parse_url('sample.php?name1=ProductOne&price1=123&name2=ProductTwo&price2=32', PHP_URL_QUERY);
// process into array so that first element is a key, and second element is a value
parse_str($url, $output_array);
// now $output_array contains the query's variables.
The bigger question is why would you want to do this when these variables are already contained in $_GET?

sample.php?name[]=Product1&name[]=Product2
Then in your PHP, you can see:
print_r($_GET['name']);

I'm not sure if I understood you right, but if what you're looking for is converting a querystring to an array you can user the pares_str function. in order to get only the querystring from a url you can use the parse_url function
$url = "sample.php?some_var=someval&s=4&bla=bla";
$url_parts = parse_url($url);
$qs = $url_parts["query"];
$params = array();
parse_str($qs,$params);
var_dump($params);

Like dqhendricks suggested, would it not pay to just use the raw gets and then append them to an array. I am assuming that you will always know what will be in the URL
$array_of_gets = array("address" => $_GET['address'],"telephone" => $_GET['telephone']);
and so on...

Related

Is there a function in PHP that's equivalent to Arrays.asList(val) in Java?

I have an array in PHP defined as:
$myArray = array(
"key_1" => "value_1",
"key_2"=> value_2",
"key_3"=> value_1",
)
Is there a function that could print it as:
[{key_1=value_1, key_2=value_2, key_3=value_3}] ?
I know Java provides Arrays.asList(myHashMap) for doing this for hashmaps (which are associative arrays like PHP)
Is there a function in PHP that's equivalent to Arrays.asList(val) in Java?
I don't know any array method that does this.
One way:
foreach($myArray as $key => $value) {
echo "$key=$value ";
}
Another one (each is deprecated as of php 7.2):
print_r(each($myArray));
Another dirty way you could achieve this is with the following
$array = array(
"key_1" => "value_1",
"key_2" => "value_2",
"key_3" => "value_1",
);
echo str_replace('"', '', str_replace(':', '=', json_encode([$array])));
if you want to print the content of an array with the keys, you can use the print_r($array) or $return = print_r($array,1), to have the string assigned to $return variable.

How to get value of array by using the key from a string

I have an array with some keys and I want to get the array values according to the array keys where the keys are in a string.
Example:
$arr = array(
"COV" => "Comilla Victorians",
"RK" => "Rajshaji Kings"
);
$str = "COV-RK";
Now I want to show Comilla Victorians VS Rajshaji Kings.
I can do it using some custom looping, But I need some smart coding here and looks your attention. I think there are some ways to make it with array functions that I don't know.
You could do something like:
echo implode(' VS ', array_map(function($v) use ($arr) { return $arr[$v]; }, explode('-', $str)));
So explode the string, map the resulting array, returning the value of the matching key in $arr, then just implode it.
You could try this:-
<?php
$arr = array(
"COV" => "Comilla Victorians",
"RK" => "Rajshaji Kings"
);
$str = "COV-RK";
$values = explode("-", $str); // explode string to get keys actually
echo $arr[$values[0]] . " VS " . $arr[$values[1]]; // print desired output

PHP: Converting a String into a Nested Array

I'm using Laravel and am attempting to write an artisan command that accepts an argument, $content, that then needs to be transposed to an array. For example:
// An example of a value that is being passed in from the CLI and stored as $content
$content = "['div']['div'][0]['h2']['a']";
To clarify, $content is then being passed in as a function argument where it will be used to pull out the values from the actual result set. In other words, I'm receiving a response from an API and $content is the path to the values that I need to pull out of the response. For example, the hard coded version of the implementation looks like:
$result = $report['div']['div'][0]['h2']['a'];
Now, $result contains the values that I need to process. However, I'm trying to make this dynamic so I don't repeat myself each time I add in a new data source to check for reports. Currently, I have 4 functions each with hard-coded paths to the desired result; the goal is to make it so that I can pass in an argument that contains the path to the desired values and refactor my code so I only have the one function which accepts the path to the values as an argument.
I hope that clarifies the end-goal and why I'm only referencing keys, not a value.
Anyway, back to the problem at hand. I've attempted different variations of the following:
// Attempting to parse the string into an array
$arr = explode("]", trim(str_replace("[","",$content), "]"));
This results in the following array:
array (size=5)
0 => string ''div'' (length=5)
1 => string ''div'' (length=5)
2 => string '0' (length=1)
3 => string ''h2'' (length=4)
4 => string ''a'' (length=3)
But, what I need is for the array to be formatted like the following:
$array = ['div']['div'][0]['h2']['a']
I attempted to do a foreach($array as $element) over $arr and do an array_push for each element, but that resulted in the same output as $arr.
How can I loop over the string and parse it into an array? Additionally, I need 0 to remain as an index, and not be type casted as a string. And, one last note, the value of $content will be completely different each time, so I need it to be quite flexible. The only part that will remain constant is the [ and ] will always encapsulate the keys.
I'd love to hear how others would solve this seemingly trivial problem (I've taken a few years off from programming and apparently have forgotten more than I care to admit ;) ). I honestly thought that the str_replace and explode was going to provide me the result I was expecting...
But, after re-reading the php.net/explode doc, it's always going to cast each element as a string (thus overriding my 0 index), and I have no idea how to turn it into a nested array, instead of a simple, flat array.
I look forward to your advice and insight. Thanks.
EDIT:
Including the function that is making use of the arguments to help provide some greater clarity.
private function yql_check_website($url, $xpath, $content) {
require_once('../vendor/OAuth.php');
$statement = "select * from html where url='{$url}' and xpath='{$xpath}' ";
$cc_key = $this->key;
$cc_secret = $this->secret;
$url = "http://query.yahooapis.com/v1/public/yql";
$args = array();
$args["q"] = $statement;
$args["format"] = "json";
$consumer = new OAuthConsumer($cc_key, $cc_secret);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL,"GET", $url, $args);
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
$url = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
$url .= "&env=store://datatables.org/alltableswithkeys";
$ch = curl_init();
$headers = array($request->to_header());
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$rsp = curl_exec($ch);
$report = json_decode($rsp, true);
// Dynamically inspect the $report object for the xpath content
$result = $report . $content;
unset($report);
return $result;
}
So, $report contains the entire API response, but the only thing I need is the content that is provided in $report['div']['div'][0]['h2']['a'] (for this example, at least, the path is different for each report that I'm scraping). So, the reason I'm trying to convert the command line argument into an array is so that it can be used in the above code where $content is being called in order to navigate the API's response and return the values from that segment.
I hope that makes more sense. And, if there is a better way to achieve this end-goal, feel free to mention it. I may be taking the wrong approach...
Laravel has a few methods for array access that provide "dot" access to arrays, including array_get. The method prototype looks like this:
function array_get(array $array, string $key, mixed $default = null)
So, in your case, you could write:
$results = array_get($report, "div.div.0.h2.a");
You could just use preg_match_all here..
$content = "['div']['div'][0]['h2']['a']";
$expression = /\['([a-zA-Z0-9]+)\']/;
$results = preg_match_all( $expression, $content, $matches );
print_r( $matches );
If you have to have the array be like what you're saying, you could do something like this (for starters - this is a little ugly though as it is...)
// array( ['div']['div'][0]['h2']['a']
// visualizing...
// array( 'div' => array ( 'div' => 'array( "0" => array( "h2" => array( "a") ) ) ) );
function createDepth( $source, $currentKey, $nextDepth = null ) {
if( !is_array( $nextDepth ) ) {
$source[] = array( $currentKey => $nextDepth );
} else {
$nextKey = array_shift( $nextDepth );
$source[] = createDepth( array( $currentKey => array() ), $nextKey, $nextDepth );
}
return source;
}
// Edit: doh, unset the first key..
unset( $matches[0] );
// Continue from here.
$currentKey = array_shift( $matches );
$holder = array();
$final = createDepth( $holder, $currentKey, $matches);
print_r( $final );
Note: All the above is untested...
Is this what you want ?
$str = "['div']['div'][0]['h2']['a']";
$str = preg_split('/]\[/', substr(str_replace("'", "", $str), 1, -1));
print_r($str);
Array (
[0] => div
[1] => div
[2] => 0
[3] => h2
[4] => a
)

How to parse key/value chain into associative array in PHP?

I have a string that looks like: key1/value1/key2/value2/ and so on
I did an explode('/',trim($mystring,'/')) on that
Now I want to haven an associative array like:
array(
'key1' => 'value1',
'key2' => 'value2',
...
);
of course i can do it with an for loop where i always read two entries and push them into a target array, but isnt there something more efficient and elegant? a one liner with some some php core function similar to ·list()· or something?
A method using array_walk() with a callback function:
function buildNewArray($value, $key, &$newArray) {
(($key % 2) == 0) ? $newArray[$value] = '' : $newArray[end(array_keys($newArray))] = $value;
}
$myString = 'key1/value1/key2/value2/';
$myArray = explode('/',trim($myString,'/'));
$newArray = array();
array_walk($myArray, 'buildNewArray', &$newArray);
var_dump($newArray);
If the format is not changin (i mean it is allways Key1/value1/key2/value2) it should be easy.
After the explode you have this:
$arr = Array('key1','value1','key2','value2')
so you now can do:
$new_arr = array();
$i = 0;
for($i=0;$i<count($arr);$i+=2)
{
$new_arr[$arr[i]] = $arr[$i+1];
}
at the end of the loop you will have:
$new_arr = array("key1"=>"value1","key2"=>"value2")
KISS :)
HTH!
One can always make yourself a one liner.
This is called User-defined functions
No need to devise something ugly-but-one-liner-at-any-cost.
Make your own function and you will get much shorter, cleaner and way more reliable result.
A function, which will not only do elementary string operations but also do something more intelligent, like parameter validation.

Is there a PHP function for imploding an associative array without losing the keys?

The title of this question is self-explanatory.
I've heard I can mimic this using http_build_query, but I'd rather use a function that's meant for this.
Input example:
$assoc = array(
"fruit" => "banana",
"berry" => "blurberry",
"vegetable" => "lettice"
);
Desired output (I get this with http_build_query):
string(46) "fruit=banana,berry=blurberry,vegetable=lettice"
output from reversal wanted is the same as input - that's my current problem.
Implode with
serialize($array);
Explode with
unserialize($array);
Found a function in the php .net comments for implode:
function implode_with_key($glue = null, $pieces, $hifen = ',') {
$return = null;
foreach ($pieces as $tk => $tv) $return .= $glue.$tk.$hifen.$tv;
return substr($return,1);
}

Categories