Skip to content

PDO Bind wrong param when string contains hash #18028

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
topnew opened this issue Mar 11, 2025 · 5 comments
Closed

PDO Bind wrong param when string contains hash #18028

topnew opened this issue Mar 11, 2025 · 5 comments

Comments

@topnew
Copy link

topnew commented Mar 11, 2025

Description

How to re-produce the problem:

table: test (a varchar(5), b varchar(10))

$sql = 'insert into test(a,b) values (?, ?)';

$stmt->bindParam(1, 'a # a');
$stmt->bindParam(2, 'b # b');

when there is more then 1 vars binded, and the first var contains "#"

it is actually inserted as ('b # b', 'b # b') -- i.e. the binded 1 is using the 2nd

PHP v 8.3.6
Database v : 10.11.8-MariaDB-0ubuntu0.24.04.1

PHP Version

PHP 8.3.6

Operating System

Ubuntu 24.04

@MorganLOCode
Copy link

MorganLOCode commented Mar 12, 2025

I'm surprised that runs at all, since the second parameter to bindParam is supposed to be a variable name, not a value ("Fatal error: Uncaught Error: PDOStatement::bindParam(): Argument #2 ($var) could not be passed by reference").

Are you sure you aren't wanting bindValue here?

@topnew
Copy link
Author

topnew commented Mar 12, 2025

Could you re-test -- I have been tested dozens of times today: -- please keep mind in php 8.3

And here are the reuslt:

table test (a varchar(5), b varchar(5))

SQL = insert into test(a, b) values (?, ?)

test 1: 1 = a, 2 = b --> works, as no # found in string
test 2: 1 = a, 2 = b # b -- > works as only one # found
test 3: 1 = a # a, 2 = b # b --> no error, but actually inserted as "b # b", "b # b" --> data wrong
test 4: 1 = a # a, 2 = b # very very very long -> failed, error msg said, data too long for columns A

reason: a was inserted as "b # very very long" and more than varchar(5) -- i.e. if a is varchar(255), it will be saved, but with wrong info from b, not from a


Please be adviced, there is no such error on php 8.1 and ubuntu 22.04 -- with exactly same code

and here is the testing code:


try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "INSERT INTO 0_a (a, b) VALUES (?, ?)";

    $stmt = $pdo->prepare($sql);

    $a = 'a#a';
    $b = 'b#b beee d';
    $stmt->bindParam(1, $a);
    $stmt->bindParam(2, $b);
    $stmt->execute();
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

@MorganLOCode
Copy link

Oh, so you are passing them as variable references.

Well, I ran your code (once I substituted values into the DSN), and had no issues on 8.3.6, 8.3.0, 8.1.13, or 8.4.4.

What probably makes these tests irrelevant though is that I ran them against a PostgreSQL database on Windows as I don't have a MariaDB/MySQL install.

@topnew
Copy link
Author

topnew commented Mar 13, 2025

Alright - after a bit more test -- I now find out the actual reason of this "issue"

As I use array to loop the bindParam($k, $v) --> according to PHP docs on bindParam, the $v is pass by reference, thus it is always be replaced by the last $v

I have update to use "bindValue" now this problem solved.

You can close this ticket. as it is a "user error" -- Or i m happy for you to paste the change log of "bindParam" v 8.1 vs 8.3 , as there is no mention of changes of this &$var

@Girgias
Copy link
Member

Girgias commented Mar 13, 2025

As per author, closing as wont fix due to "user error"

@Girgias Girgias closed this as not planned Won't fix, can't repro, duplicate, stale Mar 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants