Page 1 of 1

$_GET['string'] help [SOLVED]

Posted: Tue Aug 15, 2006 5:27 pm
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.

Posted: Tue Aug 15, 2006 5:33 pm
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.

Posted: Tue Aug 15, 2006 6:30 pm
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.

Posted: Tue Aug 15, 2006 6:41 pm
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']}\">";

Posted: Tue Aug 15, 2006 7:36 pm
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...';
}
?>

Posted: Tue Aug 15, 2006 7:55 pm
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. :)

Posted: Wed Aug 16, 2006 12:27 am
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.

Posted: Wed Aug 16, 2006 12:36 am
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
?>

Posted: Wed Aug 16, 2006 1:11 am
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.

Posted: Wed Aug 16, 2006 1:48 am
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.