Chaz Meyers (cpm) wrote,
Chaz Meyers

Oracle, PHP, and references. (Oh My!)

I'm pretty sure I stumbled into this problem twice already, so this time I'm going to write about it in hopes of committing this to memory.

Most databases let you bind variables. If not, the library you use to connect to your database might do it for you. Binding means you say something like:

$sth = prepare("SELECT * FROM foo WHERE col=:val"); $result = execute($sth, ["val" => "Some value"]);

"val" gets automatically escaped for you, you are less vulnerable to SQL injection attacks, and life is good.

If you were writing a generalized PHP database library for Oracle on top of the oci_* API, you might in inclined to write something like:

 foreach( $binds as $name => $value ) { 
    oci_bind_by_name($sth, $name, $value); 

However, you would be wrong to do so. $value is passed by reference, not by value. When you're in a foreach loop, the address of $value is the same each time. So if your $binds look like:
["first_name" => "John", "last_name" => "Doe"]

The oracle library is going to think it got:
["first_name" => "Doe", "last_name" => "Doe"]

Because of this, I got ORA-01460 errors, but you might get entirely different errors!

A safer way to accomplish this goal:
 foreach( $binds as $name => $value ) { 
    oci_bind_by_name($sth, $name, $binds[$name]); 

As long as you don't change your $binds array between when you bind and execute, that should be safe.

  • Post a new comment


    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.