NYCPHP Meetup

NYPHP.org

[nycphp-talk] Best practice for escaping data

Paul Houle paul at devonianfarm.com
Mon Feb 19 20:13:08 EST 2007


Randal Rust wrote:
>
> The correct process would be to:
>
> 1. Run fix_magic_quotes() to ensure that all of the backslashes are
> removed (if magic_quotes_gpc is on)
> 2. Run each piece of data through the appropriate function for validation
> 3. Re-insert the slashes using the database specific function
>
    A lot depends on the database you use.  If you use mysql,  you can 
write something like

update x set y='5' where z='50';

where y and z are integer columns of x.

    Postgresql,  MS SQL and many other databases won't accept that.  If 
you're writing your own SQL,  you'll need to quote strings and validate 
numbers.

    Many people claim it's a 'best practice' to use a database API that 
supports place holders...  For instance,  in ADODB,  you can write

$db->Execute("
    Update x set
         y=?
    where
        z=?
",array($y,$z));

    This seems to get good results with MySQL and MS SQL,  but doesn't 
work with access if the fields are numeric.

    Using placeholders is certainly better than not quoting,  but my 
experience is that placeholders + changing code = defects.  Imagine you
write something like

$db->Execute("
    Update x set
       a=?,
       ...24 columns ..
       z=?
    where
       aa=?
       AND ab=?
       AND ac=?
",array($a,$b,$c,$d,...$ac));

    Once you're writing them by the hundreds,  you'll find that it's 
tiresome and error-prone to write your own UPDATE and INSERT 
statements...  Lately I've been using a homebrew active record class 
that lets me write code like

$table=$ar_db->get("characters");
$row=$table->new_record();
$row->firstname="Genma";
$row->lastname="Saotome";
$row->age=45;
$row->insert();

    If I'm using auto-increment columns, with mysql,  I can pick up the 
id  with

$last_insert_id=$row->id;

    In this approach,  strings get quoted and numbers get validated --

$row->age="Forty-Five";

    causes an exception to be thrown.  The real advantage that comes out 
of the active record is that you can build your update/inserts in an 
additive way

$row=$table->new_record();
assign_columns_from_form_elements($row);
assign_complicated_multipart_key($row);
assign_timestamp($row);
$row->insert();

------------

    All that said,  it's a good thing to validate your data;  MySQL, for 
instance,  doesn't throw an error when it gets a bad date,  but it 
stores '0000-00-00',  which probably isn't the behavior you want.  If 
you want your application to behave predictably,  it's good to keep bad 
data out.


   





More information about the talk mailing list