Link to home
Start Free TrialLog in
Avatar of rgb192
rgb192Flag for United States of America

asked on

click on one link to change one (out of many) query string variable

toggle on/off 1 query_string variable with one href click (no checkboxes of choices)

website.com/index.php?query_variable1=45&query_variable2=59499&query_variable3=8


want

website.com/index.php?query_variable1=45&query_variable2=59499&

or
website.com/index.php?query_variable1=45&query_variable3=8




real world example toggle on/off different variables of query string:
videos:
captioning: on/off
video quality: 720,480,360,240
video size: small, large, full-screen
website.com/video.php?caption=on&video_quality=720&video_size=full_screen

separate links to click

click on link 'video size-small'
to change query to
website.com/video.php?caption=on&video_quality=720&video_size=small

click on link 'video quality-480'
to change query to
website.com/video.php?caption=on&video_quality=480&video_size=full_screen


clicking on one should not affect other
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Each of these links needs to be its own entity (its own anchor tag in the HTML document).  The PHP script that generates the links will be responsible for all of the UTL parameters.  Your examples seem to make sense -- just put them into HTML anchor tags and the task is complete!
Avatar of rgb192

ASKER

I dont understand

how to keep the current query string and only modify the clicked link (video size)

does this need a complex regular expression
or a preg replace to modify current query string
How to keep the current query string
This information is available in the $_GET array.  You can use var_dump($_GET) to print it out.  Then you can see the arguments by index name and array value.  You can write programming to iterate over the GET array, but if you do that, you want to make sure that anything in the GET array is "sanitary" since the URL is a common attack vector.
does this need a complex regular expression or a preg replace to modify current query string
No, nothing like that.  Just substitute the value you want in a copy of the $_GET array and rebuild the URL before writing the anchor tag to the browser output stream. Or you can hardcode the options (which is what I would probably do) in an array or object and call a method to build the anchor tag with the request variables.
Avatar of Julian Hansen
Where do you want to modify the query string - in the browser or on the server?

From your questions it sounds like you want to dynamically update the query string before sending to the server - is this correct?
You might use something like this.  It avoids attacks via invalid URL parameters, choosing among known good values.  It will also trigger a run-time error if the script tries to set a value that is unusable.
http://www.laprbass.com/RAY_temp_rgb192.php

If I had some more time, I might pretty it up some, but all the basic functionality is there.  As written, the script takes advantage of the fact that the last (rightmost) query variable overwrites identically named variables in the request array.

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);

/* PROBLEM DEFINITION
 *
 * SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28143970.html
 *
 * captioning: on/off
 * video quality: 720,480,360,240
 * video size: small, large, full-screen
 * website.com/video.php?caption=on&video_quality=720&video_size=full_screen
 */

Class Get
{
    // ACTUAL REQUEST ARGUMENTS
    protected $is = array();

    // ALLOWABLE REQUEST ARGUMENTS
    protected $ok = array
    ( 'c' => array('on',   'off')
    , 'q' => array('720',  '480',   '360', '240')
    , 's' => array('full', 'large', 'small')
    )
    ;

    // CONSTUCTOR OVERRIDES DEFAULT ARGUMENTS WITH THE REQUEST VARS
    public function __construct()
    {
        // COPY DEFAULT SETTINGS
        foreach ($this->ok as $key => $arr)
        {
            $this->is[$key] = $arr[0];
        }

        // SET REQUEST VARS
        foreach ($_GET as $key => $val)
        {
            // IGNORE ATTACK VECTORS
            if (array_key_exists($key, $this->ok))
            {
                // CHOOSE ONLY VALID SETTINGS
                if (in_array($val, $this->ok[$key])) $this->is[$key] = $val;
            }
        }
    }

    // SETTER PERMITS RUN-TIME SETTINGS (NOT JUST URL LINKS)
    public function setArg($key, $val)
    {
        // HANDLE PROGRAMMING ERRORS
        if (!in_array($key, $this->ok))       trigger_error("FAIL KEY: $key => $val", E_USER_ERROR);
        if (!in_array($val, $this->ok[$key])) trigger_error("FAIL VAL: $key => $val", E_USER_ERROR);

        // SET THE VALUE
        $this->is[$key] = $val;
        return $this->getURL();
    }

    // GETTER PERMITS RUN-TIME OBSERVATION OF SETTINGS
    public function getIs()
    {
        // RETURN THE CURRENT SETTING VALUES
        return $this->is;
    }

    public function getURL()
    {
        return 'http://'
        . $_SERVER['HTTP_HOST']
        . $_SERVER['PHP_SELF']
        . '?'
        . http_build_query($this->is)
        ;
    }
}

// SHOW THE USE CASE
$myreq = new GET;
$str = $myreq->getURL();

$html = <<<EOD
<p>
Caption: <a href="$str&c=off">Off</a> | <a href="$str&c=on">On</a>
<br>
Quality: <a href="$str&q=720">720</a> | <a href="$str&q=480">480</a> | <a href="$str&q=360">360</a> | <a href="$str&q=240">240</a>
<br>
Display: <a href="$str&s=small">Small</a> | <a href="$str&s=large">Large</a> | <a href="$str&s=full">Full Screen</a>
</p>
EOD;

echo $html;

// SHOW THE REMEMBERED SETTINGS, PLUS ANY CHANGES FROM THE LINKS
echo "<pre>";
echo "REMEMBERED STATUS SETTINGS:" . PHP_EOL;
print_r($myreq->getIs());

Open in new window

Best regards, ~Ray
Variation on the theme...

<?php // RAY_temp_rgb192.php
error_reporting(E_ALL);

/* PROBLEM DEFINITION
 *
 * SEE http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_28143970.html
 *
 * captioning: on/off
 * video quality: 720,480,360,240
 * video size: small, large, full-screen
 * website.com/video.php?caption=on&video_quality=720&video_size=full_screen
 */

Class Get
{
    // ACTUAL REQUEST ARGUMENTS
    protected $is = array();

    // ALLOWABLE REQUEST ARGUMENTS
    protected $ok = array
    ( 'caption' => array('on',   'off')
    , 'quality' => array('720',  '480',   '360', '240')
    , 'display' => array('full', 'large', 'small')
    )
    ;

    // CONSTUCTOR OVERRIDES DEFAULT ARGUMENTS WITH THE REQUEST VARS
    public function __construct()
    {
        // COPY DEFAULT SETTINGS
        foreach ($this->ok as $key => $arr)
        {
            $this->is[$key] = $arr[0];
        }

        // SET REQUEST VARS
        foreach ($_GET as $key => $val)
        {
            // IGNORE ATTACK VECTORS
            if (array_key_exists($key, $this->ok))
            {
                // CHOOSE ONLY VALID SETTINGS
                if (in_array($val, $this->ok[$key])) $this->is[$key] = $val;
            }
        }
    }

    // SETTER PERMITS RUN-TIME SETTINGS (NOT JUST URL LINKS)
    public function setArg($key, $val)
    {
        // HANDLE PROGRAMMING ERRORS
        if (!in_array($key, $this->ok))       trigger_error("FAIL KEY: $key => $val", E_USER_ERROR);
        if (!in_array($val, $this->ok[$key])) trigger_error("FAIL VAL: $key => $val", E_USER_ERROR);

        // SET THE VALUE
        $this->is[$key] = $val;
        return $this->getURL();
    }

    // GETTER PERMITS RUN-TIME OBSERVATION OF SETTINGS
    public function getIs()
    {
        // RETURN THE CURRENT SETTING VALUES
        return $this->is;
    }

    public function getURL()
    {
        return 'http://'
        . $_SERVER['HTTP_HOST']
        . $_SERVER['PHP_SELF']
        . '?'
        . http_build_query($this->is)
        ;
    }

    public function getLinks($break='<br>', $delim='|')
    {
        $url = $this->getURL();
        $lnk = NULL;
        foreach ($this->ok as $key => $arr)
        {
            $lnk .= ucfirst($key) . ': ';
            foreach ($arr as $val)
            {
                $lnk .= '<a href="' . $url . '&' . $key . '=' . urlencode($val) . '">' . ucfirst($val) . '</a>' . $delim;
            }
            $lnk = rtrim($lnk, $delim);
            $lnk .= $break;
        }
        $len = strlen($lnk) - strlen($break);
        $lnk = substr($lnk, 0, $len);
        return $lnk;
    }
}

// SHOW THE USE CASE
$myreq = new GET;

// SHOW THE REMEMBERED SETTINGS, PLUS ANY CHANGES FROM THE LINKS
echo "<pre>";
echo "REMEMBERED STATUS SETTINGS:" . PHP_EOL;
print_r($myreq->getIs());

echo $myreq->getLinks();

Open in new window

Avatar of rgb192

ASKER

>>Where do you want to modify the query string - in the browser or on the server?

From your questions it sounds like you want to dynamically update the query string before sending to the server - is this correct?


either client or server works

I do not fully understand the question


there are repeats of the variable I clicked on
so I do not know the value I will $_GET if it is listed twice

first code:
?c=on&q=720&s=full&s=full
?c=on&q=720&s=full&s=large
?c=on&q=720&s=large&c=off

second code:
?caption=on&quality=720&display=large&quality=240
?caption=on&quality=240&display=large&quality=360
?caption=on&quality=360&display=large&caption=off
I do not know the value I will $_GET if it is listed twice
Yes, you do know.  
As written, the script takes advantage of the fact that the last (rightmost) query variable overwrites identically named variables in the request array.
This is the nature of associative arrays.  Identical keys permit overwriting.  You can prove this to yourself by installing and running the script.
hello rgb192,  , , I can not understand what you are trying to say about how you get the values INTO the "query string"

Not sure if you use some kind of "javascript"  "query string" builder, that adds to the "query string" as a button-check-link is clicked ? ?,, , although you say - "toggle on/off 1 query_string variable with one href click (no checkboxes of choices)"  you do NOT show any code for how that is done, If you have code for that, please show us that code. .
OR, , are you asking for Javascript code to do a "query string"  build up for the video choices you have as button-check-links?

You might also show us your code for the - "toggle on/off 1 query_string variable with one href click (no checkboxes of choices)" , maybe you have something like -

<a href="#" onclick="makeQuery(Cap-On);">caption on</a>
This makes no sense

?c=on&q=720&s=full&s=full <== Here you have two 's' parameters same value
?c=on&q=720&s=full&s=large <== Here you have 2 's' parameters different value
?c=on&q=720&s=large&c=off <== Here you have 1 s 1 c parameter

In the first and second - the value of s in the $_GET will always be the second instance of the parameter - the first will be overwritten. It makes no sense at all to have two parameters with the same name in a query string.

The only one that makes sense is the third one - in which case

$_GET['s'] will contain 'large' and
$_GET['c'] will contain 'off'

Beyond that I have no idea what you are trying to do.
@julianH:  Actually it makes perfect sense; it's just that it may be a novel concept.  I see it used only occasionally, but it's a powerful concept.  Install the script and run it.  No special tools are required.  Click on some of the links and watch what happens to the internal values.  It's doing what the author asked for, "clicking on one should not affect other."   It's providing a link that allows a single click to change a single value, while preserving all of the other values.

In all instances of duplicate keys in associative arrays, the latter key's value overwrites the prior key's value.  In PHP the raw request strings are turned into associative arrays by the PHP interpreter before the user script gets control.  That's how a URL request string that looks like this...

c=on&q=720&s=full

... gets turned into the $_GET array that looks (more or less) like this:

'c'  => 'on',   'q' => '720',   's '=> 'full'

As you can see, the array has named strings for the keys.  So if you add another argument to the request string with a matching key, it will replace the previous value when PHP creates $_GET.  This is a useful piece of knowledge when your script is handling arrays.
OK, here is some of my javascript to do this, It will give the Changed Web Address with the Get Query as "var queryStr"  in the  makeQuery(arryPos,value)  function -

<script>/* <![CDATA[ */

var queryArry = ["caption=on","quality=240","size=small"];

function makeQuery(arryPos,value){
queryArry[arryPos] = value;
var queryStr = "website.com/video.php?"+queryArry[0]+"&"+queryArry[1]+"&"+queryArry[2];
document.getElementById("vidInfo").innerHTML = queryStr;
}

/* ]]> */</script>
<table border="1">
<tr><td colspan="2"><span id="vidInfo">website.com/video.php?caption=on&quality=240&size=small</span></td></tr> 
<tr><td>Caption: </td><td><a href="#" onclick="makeQuery(0,'caption=on');">On</a> - <a href="#" onclick="makeQuery(0,'caption=off');">Off</a></td></tr>
<tr><td>Quality: </td><td><a href="#" onclick="makeQuery(1,'quality=240');">240</a> - <a href="#" onclick="makeQuery(1,'quality=360');">360</a> - <a href="#" onclick="makeQuery(1,'quality=480');">480</a> - <a href="#" onclick="makeQuery(1,'quality=720');">720</a></td></tr>
<tr><td>Video Size: </td><td><a href="#" onclick="makeQuery(2,'size=small');">Small</a> - <a href="#" onclick="makeQuery(2,'size=large');">Large</a> - <a href="#" onclick="makeQuery(2,'size=full');">Full Screen</a></td></tr>
</table>

Open in new window

This works in firefox for me.
@Slick812: It works in Chrome and IE, too.
@Ray - I get what you are saying but in this case I disagree

The parameters given make no sense - having the same parameter repeated with the same value is just a waste of space - effect will be the same as if there is one. However having the same paramter twice with different values is ambiguous.

In PHP the $_GET array will organise the parameters nicely for you and overwrite the dupes - and you can access the string directly and parse it yourself - you can also drive your car using your feet if you try hard enough - doesn't mean it is a good idea.

Based on other questions posted by the author there seems to be something he wants to do with selecting options in the page - he mentioned in the opening not wanting to use checkboxes. As with many of the authors questions there is a riddle element that needs to be solved to find out what the actual question is - trying to read between the lines to figure out what he is trying to achieve so we can go back to first principles and suggest a way forward.

What it seems he is asking is given a page of options where you can switch options on and off how do you build a query string that caters to those choices - but not using checkboxes. This is where I am confused - how is he presenting the choices in his interface. I suspect the solution is very simple - just need to figure out the question.
ASKER CERTIFIED SOLUTION
Avatar of Ray Paseur
Ray Paseur
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@Ray - you misunderstand me - associative arrays will sort the problem out - that does not detract from the fact that the question is ambiguous because we don't know why there are two parameters in the query string with same name different value. How PHP deals with it and the fact that effect is that the last param wins - is beside the point - in this case the author (for all we know) might want the first value to prevail. It is ambiguous as to what the requirement is.
Avatar of rgb192

ASKER

this was the Ray_Paseur script that I used although all worked but the urls looked cleaner

also tried Slick812 javascript

thanks