0

I am really stuck with this one.

I am trying to pass a list of codes to a MySql statement, but not in the right format for it to work.

My list comes from a form textarea called "uniquecode"

Example codes (all on a new line) from the text area would be:

fg3456 tg7844 de3902 .. etc

I attempt to explode and implode the list with:

$ar = $_POST['uniquecode']
$in = "'".implode("','", explode("\n", $ar))."'";

The result of $in then gets passed to a Mysql statment:

$sql = "SELECT code, size, price from stock WHERE code IN ($in)";

When I echo the $sql, I get the following:

SELECT housecode, name, cost, size, price FROM stock where code IN ('fg3456 ','tg7844 ', ','de3902')

As you can see only the LAST item, 'de3902' is formatted correctly. Notice the first item in the list has a space then a single quote then a comma: 'fg3456 ',

Because of this issue, when I attempt to loop through the result set from the query, only the last item is returned:

$result = $mysqli->query($sql); 
if ($result = mysqli_query($mysqli, $sql)) {
        while($row = $result->fetch_array()) {
            $code = $row['code'];
            $name = $row['name'];
            $size = $row['size'];
            $price = $row['price'];
        }   

 echo $code; //returns last item in the list: de3902

So my question is how to explode/implode the list into the correct format for the IN clause of the Mysql query so it reads correctly and returns all the codes???

SELECT code, name, size, price from stock WHERE code IN ('fg3456','tg7844','de3902')

Kind regards

6
  • 1
    The correct way (in my opinion...) would be to loop over your values and add a question mark for every value and then bind the values to these placeholders after you have prepared the statement. Right now you have an sql injection problem. Commented Dec 18, 2014 at 14:01
  • Explode in a separate var, do a trim and add them to the implode only if trimmed lenght > 0 Commented Dec 18, 2014 at 14:02
  • Please post the output from var_dump($_POST['uniquecode']) as copied from the browser page source, not as rendered on screen. You have something spurious in there (not an extra line break, I think) that is breaking your implode(), maybe correctable with arary_filter(). But steps need to be taken to protect this from SQL injection. Commented Dec 18, 2014 at 14:02
  • var_dump($ar) result: string(23) "fg3456 tg7844 de3902" Commented Dec 18, 2014 at 14:06
  • @Hexana The string shown only has 20 characters so perhaps you should use preg_split() instead to explode on multiple spaces or new-line characters as well. Commented Dec 18, 2014 at 14:09

2 Answers 2

1

As mentioned in the comments, I would loop over your values and add a question mark for every value and then bind the values to these placeholders after you have prepared the statement. Right now you have an sql injection problem.

However, to make sure you get the string you want with the input you seem to be receiving, you could use preg_split() to explode on multiple spaces, tabs or new-line characters.

For example:

$st = trim(" \n fg3456   tg7844  \n  \n de3902  \n ");
$ar = preg_split('#\s+#', $st);
var_dump($ar);
$in = "'".implode("','", $ar)."'";
var_dump($in);

Result:

array(3) {
  [0]=>
  string(6) "fg3456"
  [1]=>
  string(6) "tg7844"
  [2]=>
  string(6) "de3902"
}
string(26) "'fg3456','tg7844','de3902'"

You can use the first part of this to prepare a statement:

$st = trim(" \n fg3456   tg7844  \n  \n de3902  \n ");
$ar = preg_split('#\s+#', $st);
$in = trim(str_repeat('?,', count($ar)), ',');
$sql = "SELECT code, size, price from stock WHERE code IN ($in)";
var_dump($sql);

Result:

string(57) "SELECT code, size, price from stock WHERE code IN (?,?,?)"

By the way, personally I would use PDO as that would make the binding a lot easier.

Sign up to request clarification or add additional context in comments.

1 Comment

BINGO !!! Smart Cookie. This line did the trick $ar = preg_split('#\s+#', $st); Thank you so much. I do however need to sort the injection problem though :)
1

Why are you exploding on \n it seems like your should explode on a space (' '). Otherwise, the implode looks fine.

Alternately you could do a preg_replace to replace any number of spaces with (quote comma quote). $in = "'" . preg_replace('/\s+/',"','", $ar) . "'";.

2 Comments

Have tried: $ar = "'" . preg_replace('/\s+/,"','",' $ar) . "'" ; but gives me a parse error !!
It should be $in=..., I'll edit. Oh, and I missed a quote around the regex.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.