【问题标题】:Could I automatically get a reference of arguments in a PHP function?我可以自动获取 PHP 函数中参数的引用吗?
【发布时间】:2017-03-18 11:53:38
【问题描述】:

目前,我正在审查十年前写的网站。这些网站使用旧的 MySQL API for PHP。 PHP 从 5.3 版本开始就没有升级过,所以我需要将每个数据库请求从旧 API 重写为 PDO。

原始编码器为每个表创建了一个包装 INSERT、SELECT 和 UPDATE 请求的对象。

在有很多行的表上,为每个对象引用每个包装请求的每个参数是非常痛苦的,而且我必须修改十几个站点!

所以,我想了一种方法来减少引用函数的每个参数所花费的时间,方法是将它们放在一个循环中,并在每个函数的两行代码中引用它们......

查看PHP手册后,似乎没有办法获得函数参数的引用。我可以复制或计算它们,但无法获得任何参考。

你有什么想法或技巧可以让这份工作不那么糟糕吗?

这是我不应该做的一个例子:

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);

以及我大概想做的事情:

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

当然$function不是一个真实的对象,它只是用代码解释我的想法的一种方式。

谢谢。

【问题讨论】:

  • func_get_args() 怎么样?
  • func_get_args() 返回一个复制参数的数组,这不是我真正需要的,因为我的参数稍后在代码中被重用。

标签: php arrays reference arguments


【解决方案1】:

这个怎么样(需要 PHP 5.6 或更高版本):

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
}

【讨论】:

  • 它完全不受限制,因为您可以传递任意数量的参数。如果您想将参数的名称保留为关联数组(这样顺序无关紧要),您确实应该使用func_get_arguments()
  • 好吧,我明白多了。我会记住这一点,以备不时之需。谢谢。
【解决方案2】:

您可以使用get_defined_vars 检索范围内所有变量的关联数组,因此只要您在函数顶部使用它,那么您将有效地拥有所有函数参数的命名副本。请注意,这与使用 func_get_args 不同,如果未在调用中提供,则不会包含任何默认参数。

您可以使用以下方式将一些逻辑应用于所有参数(引用等):

<?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

【讨论】:

  • 很好的解决方案,今天我了解到get_defined_vars受范围限制。
【解决方案3】:

如果您参加了 PDO,您需要使用 PDO::prepare,这样您就可以摆脱这个问题。

【讨论】:

  • 我认为你是对的,但我想遵循与原始代码相同的请求逻辑。
  • 是的,但是如果不增加安全性,为什么还要使用 pdo 呢?
  • 我在将每个变量传递给 MySQL 之前引用它们。 PDO::prepare() 不仅仅是引用 ?
  • 您可以查看 The Hitchhiker's Guide to SQL Injection Prevention phpdelusions.net/sql_injection#manual 它更详细地介绍了我们所说的内容 :)
猜你喜欢
  • 2011-08-17
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 2011-09-14
相关资源
最近更新 更多