0

Want to convert dynamic GET variables to two internal variables so that I can use these values in SQL query.

I am passing a variable string to a URL like this

http://localhost/api-data?serial=1923473
http://localhost/api-data?manufacturer=jaguar
http://localhost/api-data?location=london
http://localhost/api-data?country=uk

I want to convert the GET data into two different variables, for example serial becomes $data1 and 1923473 becomes $data2. GET data is always in above format I just want to convert into two different variables.

print_r($_GET);

I can see the variable is passed like an array. My question, if data passed in following format AAAAA=BBBBB as get variable, how do I convert AAAAA into variable $data1 and BBBBBB into £data2. Bear in mind GET data will always be unique.

Once I have this data in 2 unique variables, I want to run a SQL query.

select blah1, blah2, blah4, blah5 from datastore where $data1 = "$data2";

Thank you in advance.

user2107349
  • 191
  • 2
  • 3
  • 16
  • `if(isset($_GET["serial"])) { $data1 = "serial"; $data2 = $_GET["serial"]; }` maybe... But you really need to use a prepared statement https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1 – AbraCadaver Feb 11 '20 at 18:36
  • I know it will work, but the problem is that I don't know what data user will pass, serial was an example, user can post or send GET any unique data. – user2107349 Feb 11 '20 at 18:39
  • You will only have certain columns in your database so you need to check if the get var is allowed or not. – AbraCadaver Feb 11 '20 at 18:40
  • Problem right here `where $data1 = "$data2"`; you cannot "parametrize" column names. – DinoCoderSaurus Feb 11 '20 at 18:41
  • @DinoCoderSaurus: But you can the data. – AbraCadaver Feb 11 '20 at 18:43

4 Answers4

1

$_GET is an array of all parameters passed. So, a URL of ?abc=def&foo=bar would result in a $_GET of

array(2) { 
    ["abc"]=> string(3) "def" 
    ["foo"]=> string(3) "bar" 
}

Using this, you can loop through each item and append it to a query:

foreach($_GET as $key => $val) {
    $query .= " AND $key = '$val'";
}

However, be sure you account for SQL injections. The best option for countering this in this scenario is to verify each key with a list of valid keys.

kzhao14
  • 2,470
  • 14
  • 21
1

Your approach is not the best and will need to be reworked when you have more than one GET variable, but in general:

$allowed = ['serial', 'manufacturer']; //etc...
$col = key($_GET);

if(in_array($col, $allowed)) {
    $val = $_GET[$col];

    //Then prepare and execute using whatever DB library you are using
    $st = $db->prepare("SELECT blah1, blah2, blah4, blah5 FROM datastore WHERE $col = ?");
    $st->execute([$val]);
}
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
0

This is one way of doing it in a plain and declarative manner.

I would highly recommend checking PDO and PDOStatement to build the query. Didn't add this example because it was not the question.

<?php

// given 
$_GET = ['serial' => 342, 'something-else' => 'not used'];
$allowedVariables = ['serial', 'manufacturer', 'location', 'country'];

// filter values from the query for only allowed keys
$data = array_filter($_GET, function ($value, $key) use ($allowedVariables) {
    return in_array($key, $allowedVariables);
}, ARRAY_FILTER_USE_BOTH);

// create an array of strings like "$data1 = $data2"
$query = array_map(function ($key, $value) {
    return "$key = $value";
}, array_keys($data), array_values($data));

// build the query while combining values with the "AND" keyword
$query = "select * from datastore where " . implode(' and ', $query);

var_dump($query);
// string(42) "select * from datastore where serial = 342"

Christoph Kluge
  • 1,947
  • 8
  • 23
  • Though this work, it does have too many loops and instructions that traverse the array. I worry here about performance if that matters at all. The stats show this: 1x`array_filter`, 1x`in_array`, 1x`array_map`, 1x`array_keys`, 1x`array_values`, 1x`implode`. – asiby Feb 11 '20 at 19:05
  • @asiby you are totally right. We could also consider validation and sanitisation but all of this this was not the question. Tried to answer as best as possible without putting my personal bias into it. – Christoph Kluge Feb 11 '20 at 19:12
  • I understand @christoph-kluge. I think my comment came out the wrong way. See, I work on platforms where at any given moment, you have more than 10,000 connections to some part of the system running so sort of script. In that scenario, you will be surprised to see the performance impact of a some single instructions. Because of that, I tend to advise people to find a balance between lean, readable, efficient, secure and maintainable code. That was the motivation behind my comment. – asiby Feb 11 '20 at 19:29
-2

For that, you can use extract($inputArray) (read more on php.net)

The keys in the input array will become the variable names and their values will be assigned to these new variables.

Also, if you want to filter the keys so that someone does not just inject unwanted variable in your current scope, then do the following before calling the extract() function...

<?php
// Pick only the data keys that are expected. Their names must be compatible with the PHP variable naming conventions.
$filteredData = array_intersect_key($_GET /* or $_POST*/, array_flip(['serial', 'manufacturer', 'location', 'country']));

// Extract the names into variables in the current scope.
extract($filteredData);
?>
asiby
  • 3,229
  • 29
  • 32