$_GET['string'] help [SOLVED]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
MrSpock
Forum Newbie
Posts: 4
Joined: Tue Aug 15, 2006 5:20 pm

$_GET['string'] help [SOLVED]

Post by MrSpock »

Perhaps someone can help with this. I have searched everywhere and can't seem to find a reference. Maybe it's not possible, or maybe I don't know the function I'm looking for. I am inclined to think the latter, since I am relatively new to PHP.

I have written a small php one-liner to allow users to click on a thumbnail and open a window with captions:

Code: Select all

<?
echo "{$_GET['desc']}<br /><img src=\"{$_GET['pixurl']}\">";
?>
which is called like:

Code: Select all

pix.php?desc=some text&pixurl=/path/to/image/file
I would like to shorten the urls by setting variables for text and image in pix.php like so:

Code: Select all

$desc1 = "some text for image 1";
$desc2 = "some text for image 2";
.
.
$desc9 = "some text for image 9";

$image1 = "/path/to/image1";
$image2 = "/path/to/image2";
.
.
$image9 = "/path/to/image9";
and call them like:

Code: Select all

pix.php?id=1
pix.php?id=2
.
.
pix.php?id=9
Is there a function that will allow me to call $_GET['id'] and prepend the result with $image and $desc ($image1, $desc1, etc.) and still be able to resolve the string variable? I have tried $desc.$_GET['id'] which only returns 'id', so concatenation won't work.
Last edited by MrSpock on Wed Aug 16, 2006 10:55 am, edited 2 times in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

You are looking for the language construct called variable variables.

So you know, the code you are currently using is a security hole by allowing someone to inject HTML into your script.
User avatar
MrSpock
Forum Newbie
Posts: 4
Joined: Tue Aug 15, 2006 5:20 pm

Post by MrSpock »

Thank you for confirming my suspicions about the security issue. This is part of the reason I wanted to find a different way of doing this. variable variables looks like what I'm after. Thanks for clearing this up for me.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

feyd, why variable variables? arrays seems to suit better:

Code: Select all

$images = array(
   1 => array('desc' => "some text for image 1", 'path' => "/path/to/image1") ,
        array('desc' => "some text for image 2", 'path' => "/path/to/image2") ,
//........
        array('desc' => "some text for image 8", 'path' => "/path/to/image8") ,
        array('desc' => "some text for image 9", 'path' => "/path/to/image9") ,
);
echo "{$images[$_GET['id']]['desc']}<br /><img src=\"{$images[$_GET['id']]['path']}\">";
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

I'd recommend you santitize/validate the user supplied input. If you can pass a '5' by get, you can pass almost anything else. Using it straight from the query string is dangerous. At the very least, check to make sure that you have that value in the array...

Code: Select all

<?php
$images = array(
    1 => array('desc' => "some text for image 1", 'path' => "/path/to/image1"),
    2 => array('desc' => "some text for image 2", 'path' => "/path/to/image2"),
//........
    8 => array('desc' => "some text for image 8", 'path' => "/path/to/image8"),
    9 => array('desc' => "some text for image 9", 'path' => "/path/to/image9") 
);

$id = $_GET['id'];
// Sanitize or validate id here
if ( array_key_exists($id, $images) )
{
    echo $images[$id]['desc'] . '<br /><img src="' . $images[$id]['path'] . '">';
}
else
{
    echo 'You supplied information that is not found in our system...';
}
?>
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Weirdan wrote:feyd, why variable variables? arrays seems to suit better:
I have no problem with arrays here, but his example/wish talked of variable variables. :)
User avatar
MrSpock
Forum Newbie
Posts: 4
Joined: Tue Aug 15, 2006 5:20 pm

Post by MrSpock »

Wow. A bunch of usefull replies. Thank you all! Feyd is correct given that I had no idea what to call the construct I was looking for.

I seem to remember reading that variable variables would not work in superglobal arrays; but then it could be I don't fully understand what superglobals are. Anyway, before I got back to the forums, I put together this hack. It works, but is it secure? Would I be better off using arrays and sanitizing as per Everah's advice? Here is what I have:

Code: Select all

<?
// Descriptions
$desc1 = "Description for $img1";
$desc2 = "Description for $img2";

// imgURLs
$imgbase = "/images/";
$img1 = "image1.jpg";
$img2 = "image2.jpg";

$a = "desc"; // set description var prefix
$b = "img";  // set imgURL var prefix
$c = strip_tags($_GET['id']); // we need strip_tags() to kill HTML tags
echo "${$a . $c}"; // build and display the selected description var
echo "<img src=\"$imgbase${$b . $c}\">"; // and build the image tag using the selected image var
?>
Like I said, it works, but is strip_tags() secure enough? I have tested that it does strip tags, but can it still pass other undesirables? I assume that I would have to use arrays to validate the input as Everah suggests. I'm assuming:

Code: Select all

echo $images[$id]['desc'] . '<br /><img src="' . $imgbase . $images[$id]['path'] . '">';
would allow me to use my $imgbase var with this method. Is this correct?

And thanks again for all the help.
Last edited by MrSpock on Wed Aug 16, 2006 12:37 am, edited 1 time in total.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Code: Select all

<?
// Descriptions
$desc1 = "Description for $img1";
$desc2 = "Description for $img2";

// imgURLs
$imgbase = "/images/";
$img1 = "image1.jpg";
$img2 = "image2.jpg";

$a = "desc"; // set description var prefix
$b = "img";  // set imgURL var prefix
/**
 * Is this page only going to load from a URI with a QueryString? 
 * If not, you'll get a notice if you dont check isset()
 **/
$c = ( isset($_GET['id']) ) ? strip_tags($_GET['id']) : 0; // we need strip_tags() to kill HTML tags
echo ${$a . $c}; // build and display the selected description var
echo '<img src="' . $imgbase . ${$b . $c} . '">'; // and build the image tag using the selected image var
?>
User avatar
MrSpock
Forum Newbie
Posts: 4
Joined: Tue Aug 15, 2006 5:20 pm

Post by MrSpock »

I inserted your changes. When I load the page without a QueryString, it displays image and description of id=0. Perhaps it is not a bad thing that I used zero-based numbering for my variables (I neglected to include that in my previous snippet when I stripped the real paths/filenames for public consumption). The code with your changes (and my restored ommissions) is :

Code: Select all

<?
// Descriptions
$desc0 = "Description for $img0";
$desc1 = "Description for $img1";
$desc2 = "Description for $img2";

// imgURLs
$imgbase = "/images/";
$img0 = "image0.jpg";
$img1 = "image1.jpg";
$img2 = "image2.jpg";

$a = "desc"; // set description var prefix
$b = "img";  // set imgURL var prefix
/**
 * Is this page only going to load from a URI with a QueryString?
 * If not, you'll get a notice if you dont check isset()
 **/
$c = ( isset($_GET['id']) ) ? strip_tags($_GET['id']) : 0; // we need strip_tags() to kill HTML tags
echo ${$a . $c}; // build and display the selected description var
echo '<img src="' . $imgbase . ${$b . $c} . '">'; // and build the image tag using the selected image var
?>
Anyway, the page is only (normally) going to load with a QueryString.

Works great! Thanks again.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Glad I could be of some service. And as a general rule, when you think that the page will only load with a querystring, that is the time to test it without one. I tend to test for the inevitable curious, ignorant or stupid user so I don't look like an ignorant and stupid developer when someone happens across a glitch. That's just me, but I have been stung by this before so I try to stear people in the direction of revelation instead of the direction of tribulation, if you know what I mean.

Anywho, 'nuff ramblin. Good job on your script.
Post Reply