I have an associative array called $new_get which comes from the original array of $_GET. The difference is that I modified somes of the keys and values that I will after need to echo to make a new URL.
I simply want to convert back this $new_get to it's original form, like :
?something=this&page=2
My $new_get looks like :
$new_get = array (
'something' => 'this',
'page' => '2'
);
simply do that :
$query = "?" .http_build_query($new_get);
if your $new_get is built the same way than $_GET.
Here is a function of my own to make a new URL Query based on the actual one :
// the array_of_queries_to_change will be numbered, the values in it will replace the old values of the link. example : 'array_of_queries_to_change[0] = "?page=4";'.
// the returned value is a completed query, with the "?", then the query. It includes the current page's one and the new ones added/changed.
function ChangeQuery($array_of_queries_to_change)
{
$array_of_queries_to_change_count = count($array_of_queries_to_change); // count how much db we have in total. count the inactives too.
$new_get = $_GET;
$i0 = 0;
// echo "///" .($get_print = print_r($_GET, true)) ."///<br />";
// echo "///" .($get_print = print_r($new_get, true)) ."///<br />";
while ($i0 < $array_of_queries_to_change_count)
{
$array_of_keys_of_array_of_queries_to_change = array_keys($array_of_queries_to_change);
$new_get[$array_of_keys_of_array_of_queries_to_change[$i0]] = $array_of_queries_to_change[$array_of_keys_of_array_of_queries_to_change[$i0]];
$i0++;
}
$query = "?" .http_build_query($new_get);
return $query;
}
/*// example of use :
$array_of_queries_to_change = array (
'page' => '2',
'a key' => 'a value'
);
$new_query = ChangeQuery($array_of_queries_to_change);
echo $new_query;
*/
Related
I'm trying to execute variable which part of it is a string.
Here it is:
$row = array(
'index_1' => array(
'index_2' => 'my-value'
)
);
$pattern = "['index_1']['index_2']";
I tried to do it in following ways:
// #1
$myValue = $row{$pattern};
// #2
$myValue = eval("$row$pattern");
I also trying to get it working with variable variable, but not successful.
Any tips, how should I did it? Or myabe there is other way. I don't know how may look array, but I have only name of key indexes (provided by user), this is: index_1, index_2
You could use eval but that would be quite risky since you say the values come from user input. In that case, the best way might be to parse the string and extract the keys. Something like this should work:
$pattern = "['index_1']['index_2']";
preg_match('/\[\'(.*)\'\]\[\'(.*)\'\]/', $pattern, $matches);
if (count($matches) === 3) {
$v = $row[$matches[1]][$matches[2]];
var_dump($v);
} else {
echo 'Not found';
}
This can help -
$row = array(
'index_1' => array(
'index_2' => 'my-value'
)
);
$pattern = "['index_1']['index_2']";
$pattern = explode("']['", $pattern); // extract the keys
foreach($pattern as $key) {
$key = str_replace(array("['", "']"), '', $key); // remove []s
if (isset($row[$key])) { // check if exists
$row = $row[$key]; // store the value
}
}
var_dump($row);
Storing the $row in temporary variable required if used further.
Output
string(8) "my-value"
If you always receive two indexes then the solution is quite straight forward,
$index_1 = 'index_1';// set user input for index 1 here
$index_2 = 'index_2';// set user input for index 2 here
if (isset($row[$index_1][$index_2])) {
$myValue = $row[$index_1][$index_2];
} else {
// you can handle indexes that don't exist here....
}
If the submitted indexes aren't always a pair then it will be possible but I will need to update my answer.
As eval is not safe, only when you know what you are ding.
$myValue = eval("$row$pattern"); will assign the value you want to $myValue, you can add use return to make eval return the value you want.
here is the code that use eval, use it in caution.
demo here.
<?php
$row = array(
'index_1' => array(
'index_2' => 'my-value'
)
);
$pattern = 'return $row[\'index_1\'][\'index_2\'];';
$myValue = eval($pattern);
echo $myValue;
$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
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.
How can I remove ?cat= from the example 1 so it can look like example 2 using PHP.
Example 1
?cat=some-cat
Example 2
some-cat
Easy, use str_replace:
$cat = '?cat=some-cat';
$cat = str_replace('?cat=', '', $cat);
EDIT:
If you are pulling this query string through something like $_SERVER['QUERY_STRING'], then I'd opt for you to use $_GET, which is an associative array of the GET variables passed to your script, so if your query string looked like this:
?cat=some-cat&dog=some-dog
The $_GET array would look like this:
(
'cat' => 'some-cat',
'dog' => 'some-dog'
)
$cat = $_GET['cat']; //some-cat
$dog = $_GET['dog']; //some-dog
Another edit:
Say you had an associative array of query vars you wish to append onto a URL string, you'd do something like this:
$query_vars = array();
$query_vars['cat'] = 'some-cat';
$query_vars['dog'] = 'some-dog';
foreach($query_vars as $key => $value) {
$query_vars[] = $key . '=' . $value;
unset($query_vars[$key]);
}
$query_string = '?' . implode('&', $query_vars); //?cat=some-cat&dog=some-dog
Yes, you can, very easily:
$cat = '?cat=some-cat';
$cat = substr($cat, 5); // remove the first 5 characters of $cat
This may not be the best way to do this. That will depend on what you are attempting to achieve...
One of my sites has some very complicated sorting functions, on top of a pagination, and the various variables add up to a pretty complex URL, which is a huge pain to manage. Is there a way to manage the QUERY_STRING efficiently?
By this I mean... if the url is index.php?catid=3&sort=date&year=2009&page=2 and I wish to have the user jump to page 3, or change the sort method..... how would I preserve the remaining vars without checking for each individual var with an if/else condition and echo them out in the link that would link to page 3 or alternate sort method.
To handle actual query strings (string format), you can use parse_str(). When you want to build a query string, use http_build_query().
There's quite a few examples on those documentation pages.
If for some reason you can't use http_build_query, check out my question about the fastest way to implode an associative array.
<?php
$QueryString = 'catid=3&sort=date&year=2009&page=2'; // sample querystring
parse_str($QueryString, $HttpQuery);
print_r($HttpQuery); // will be an associative array
$HttpQuery['page'] = 3; // change any values
$NewQueryString = http_build_query($HttpQuery); // rebuild the querystring
PHP supplies you a global $_GET which holds your query string all nicely parsed into elements
$_GET['catid'] will be '3'
$_GET['sort'] will be 'date'
$_GET['year'] will be '2009'
etc
You could unset the ones you don't want to pass along and then move to new url via something like:
$get = array_intersect_key($_GET, array_keys($_GET));
unset($get['sort']);
$url = 'target.php?' . http_build_query($get);
If you mean that you would like that the link to page 3 would be only
index.php?page=3
or link to changing the sort method would be only
index.php?sort=date
You would have to store the other variables in session variables (or cookies, if you want them to persist longer).
Something like this:
<?php
session_start();
foreach($_GET as $var => $val) {
// filter any malicious stuff and invalid variables out of $var and $val here
// like
if (in_array($var, $array_of_valid_variable_names)) {
if ($var == 'page') $val = intval($val);
$_SESSION[$var] = $val;
}
}
// do stuff based on the values stored in $_SESSION
echo 'Next page';
?>
Although most of the solutions provided here will work, I think the most simple way to do this will be
// parse query string into an array
$queryData = array();
parse_str($_SERVER['QUERY_STRING'], $queryData);
/*
* ... manipulate array $queryData
*/
// rebuild query string
$queryString = http_build_query($queryData, null, '&'); // or use & if you don't need XHTML compliance
That's it. Please see documentation on http_build_query() and parse_str() (that's one of those functions whose name was completey messed up - nobody would expect the function to do what it does just by looking at the name).
I have had the exact same problem with a general "build me a sortable, pageable Table" class. This is why someone invented subprocedures called "functions" in php.
You have to create a function that handles exactly the link-building process. like so:
/**
* $set: associative array of changing vars
* $unset : normal array of vars to delete
**/
function get_link($set,$unset=array())
{
$set+=$_GET;
if ($unset && is_array($unset))
foreach($unset as $idx)
unset($set[$idx]);
if ($set)
foreach($set as $name=>$value)
$pairs[]=$name.'='.urlencode($value);
return $_SERVER['SCRIPT_NAME']."?".join('&',$pairs);
}
UNTESTED CODE! Use your brains
or you could use $_SESSION-vars for pageing and sorting (an' stuff) and have links only change those (which is what i mostly do nowadays)
Add the variable name and value at the end of the query string (changing page to 3):
index.php?catid=3&sort=date&year=2009&page=2&x=page&y=3
Then, after extracting $_GET, use a simple function to check if x and y are set.
If they are, set the variable whose name is contained in x to the value y.
You can use the same link everywhere with a simple addition at the end, and the amount of programming is minimal.
Don't manage the string directly but manage an array ( key => value ) representation of it and only translate it back to string when needed.
One possible way of doing it:
function explodeQueryString( $queryString )
{
$parts = array();
if ( strlen( $queryString ) > 1 && substr( $queryString, 0, 1 ) == '?' )
{
$q = explode( '&', substr( $queryString, 1 ) );
foreach( $q as $part )
{
list( $key, $value ) = explode( '=', $part );
$parts[ urldecode( $key ) ] = urldecode( $value );
}
}
return $parts;
}
function implodeQueryString( array $arguments )
{
$parts = array();
foreach( $arguments as $key => $value )
{
$parts[ ] = sprintf( '%s=%s', urlencode( $key ), urlencode( $value ) );
}
return sprintf( '?%s', implode( '&', $parts ) );
}
// $query = $_GET;
$query = '?something=1&somethingelse=2&page=1&yetsomethingelse=3';
$q = explodeQueryString( $query );
print_r( $q );
$q[ 'page' ] += 1;
$query = implodeQueryString( $q );
echo $query;