0

Currently, I am reviewing websites written ten years ago. These websites uses the old MySQL API for PHP. PHP hasn't been upgraded since version 5.3, that's why I need to rewrite each database request from the old API to PDO.

The original coder has create for each table an object that wraps INSERT,SELECT and UPDATE requests.

On tables with a lot of rows, it is very painful to quote for each object each argument of each wrapped request, and there a dozen of sites that I must revise !

So, I think about a way to reduce the time spent on quoting each argument of the function by getting these in a loop and quote each of them in two lines of code in each function...

After viewing PHP manual, it seems that there is no way to get a reference of a function arguments. I can copy or count them, but can't get any reference.

Have you got any ideas or tips that will make this job sucks less ?

Here is an example of what I shouldn't do :

public function insert($titre, $tva, $intra, $remise = 0,
    $tx_remise = 0, $frais = 0, $code = 0, $nom = '', 
    $design = '', $adr = '', $cp = '', $ville = '',
    $tel = '', $fax = '', $rcs = '', $marq = '',
    $marq_g = '')
{
    $ville      = htmlspecialchars($ville);
    $design     = htmlspecialchars($design);
    $nom        = htmlspecialchars($nom);
    $adr        = htmlspecialchars($adr);
    $marq       = htmlspecialchars($marq);
    $marq_g     = htmlspecialchars($marq_g);

    $titre      = $this->db->quote($titre);
    $tva        = $this->db->quote($tva);
    $intra      = $this->db->quote($intra);
    $remise     = $this->db->quote($remise);
    $tx_remise  = $this->db->quote($tx_remise);
    $frais      = $this->db->quote($frais);
    $code       = $this->db->quote($code);
    $cp         = $this->db->quote($cp);
    $tel        = $this->db->quote($tel);
    $fax        = $this->db->quote($fax);
    $rcs        = $this->db->quote($rcs);

And what I approximately want to do :

    public function insert(...)
    {
        foreach($function->argumentsReference as $ref)
            $ref = quote($ref)

Of course $function isn't a real object, it is just a way to explain my idea with code.

Thanks.

2
  • 2
    How about func_get_args()? Commented Nov 4, 2016 at 15:24
  • func_get_args() returns an array of copied arguments, it is not what I really need because my arguments are reused later in the code. Commented Nov 4, 2016 at 15:34

3 Answers 3

2

You can use get_defined_vars to retrieve an associative array of all variables in scope, so as long as you use this at the top of your function then you'll effectively have a named copy of all the function arguments. Note that this is different to using func_get_args, which won't contain any default arguments if not provided in the call.

You can apply some logic to all the arguments (quoting, etc) using something like:

<?php
function foo($a, $b, $c) {
  foreach (get_defined_vars() as $key => $value) {
    ${$key} = $value * 2;
  }

  echo implode(', ', [$a, $b, $c]);
}

foo(1, 2, 3);
// 2, 4, 6
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent solution, today I learned get_defined_vars is subject to scope.
0

If you took PDO you need to use PDO::prepare and you get that rid of that problem.

4 Comments

You're right I think, but I wanted to follow the same request logic from the original code.
yes but why do you want to use pdo if you dont add more security ?
I am quoting each variable before passing them to MySQL. PDO::prepare() does more than just quoting ?
You can see The Hitchhiker's Guide to SQL Injection prevention phpdelusions.net/sql_injection#manual it cover in more detail what we are speaking :)
0

What about this (PHP 5.6 or higher required):

function insert(...$data){
   var_dump($data); // This returns an array of all passed arguments.

   array_map($data, function($datum){
       return htmlspecialchars($datum);
   }

   // Boom, now all entries in the $data array are "htmlspecialcharsified".

   list($titre, $tva, $intra, $remise, $tx_remise, $frais, $code, $nom, $design, $adr, $cp, $ville, $tel, $fax, $rcs, $marq, $marq_g) = $data;

   // As long as all parameters are passed in the correct order, you now have the desired variables available.

  // Do your magic here
}

2 Comments

It's not limited at all, because you can pass as much arguments as you would like. If you want to keep the arguments' names as an associative array (so that the order doesn't matter), you should indeed use func_get_arguments().
Ok I understand much better. I'll keep that in mind for further needs. Thanks.

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.