【问题标题】:PHP: When an associative array is within a function, and the function is called more than once, does it create the array multiple times?PHP:当一个关联数组在一个函数中,并且该函数被多次调用时,它会多次创建数组吗?
【发布时间】:2016-06-28 21:52:11
【问题描述】:

所以我有一个名为 vendorGet() 的函数,它包含一组供应商名称及其徽标。我在另一个数组中调用 vendorGet() 函数并传递一个字符串参数来告诉它从供应商数组中输出哪个供应商。这样做会导致 PHP 脚本在每次调用函数时创建这个数组,还是在函数中创建一次并每次都引用自己?

希望这是有道理的。如果有什么我可以澄清的,请告诉我。 这是一些(缩短和简化的)代码作为参考,

// Vendor Fetcher
function vendorGet($data)
{
  $vendor = array(
    'foo' => array(
      'name' => 'Foo Products',
      'image' => (VENDOR_IMG . 'foo/foo-logo.png'),
    ),
    'bar' => array( // ABT
      'name' => 'Bar Inc.',
      'image' => (VENDOR_IMG . 'bar/bar-logo.png'),
    ),
  );

  return $vendor[$data];
}

// Array calling vendorGet() function
$catalogue = array(
  'chapter-1' => array(
    'vendors' => array(
      1 => vendorGet('foo'),
      2 => vendorGet('bar'),
    ),
  ),
);

【问题讨论】:

  • php.net/manual/en/functions.arguments.php PHP supports passing arguments by value (the default), ... 这意味着传递一个大数组将复制该数组。
  • $vendor 将在每次vendorGet() 返回时被删除。该函数每次调用都会重新创建$vendor;只有返回子数组在函数调用之间继续存在。为避免这种情况,请将vendorGet() 放入具有创建$vendor[] 的构造函数的类中。当您创建该类的实例时,$vendor[] 将存在,$vendorGet() 可以在每次调用时引用它。
  • @JuanTomas 啊好的,谢谢你的建议!
  • static $vendor = array(... 只会创建一次。
  • @RyanVincent 酷,我会试试看。你能解释一下为什么会发生这种情况,这是好的还是坏的做法?

标签: php arrays function


【解决方案1】:

您编写的代码将在每次调用函数时重新创建数组。

您可以在此函数之外创建数组,并且如果它在使用“this”的类中,则该函数仍然可以引用该数组,或者您可以将数组作为变量传递给函数。

【讨论】:

    【解决方案2】:

    简而言之,每次调用函数时都会设置数组,因为您是在函数中定义它

    如果你想避免这种情况,你可以使用一个类

    class vendor {
    
       public static $vendor = array(
           'foo' => array(
             'name' => 'Foo Products',
             'image' => (VENDOR_IMG . 'foo/foo-logo.png'),
           ),
           'bar' => array( // ABT
             'name' => 'Bar Inc.',
             'image' => (VENDOR_IMG . 'bar/bar-logo.png'),
           ),
        );
    
    
        public static function get($data) {
             return self::$vendor[$data];
        }
    }
    

    【讨论】:

    • 很高兴知道,谢谢!我对 OOP 还是很陌生,但我会给这个模型一个机会。由于您举了一个示例来配合您的答案,因此我会将您的答案标记为正确。
    【解决方案3】:

    您不需要函数来执行此操作。数组允许您通过键访问。

    // Vendor Array
    $vendor = array(
        'foo' => array(
            'name' => 'Foo Products',
            'image' => (VENDOR_IMG . 'foo/foo-logo.png'),
        ),
        'bar' => array( // ABT
            'name' => 'Bar Inc.',
            'image' => (VENDOR_IMG . 'bar/bar-logo.png'),
        ),
    );
    
    // Array getting vendor by key
    $catalogue = array(
        'chapter-1' => array(
            'vendors' => array(
                1 => $vendor['foo'],
                2 => $vendor['bar'],
            ),
        ),
    );
    

    数组允许您访问一个键并返回其对应的值。您还可以像这样深入到该数组中:

    echo $vendor['foo']['name'];
    

    这将输出:

    Foo Products
    

    【讨论】:

    • 我最初是这样的,除了我不想通过索引访问,因为如果单个供应商数组中的数据发生变化,我将不得不一一更改索引调用。通过使用函数,我可以单独指定供应商名称。这是因为我有一个 for 循环,它遍历供应商的数组并输出它的信息(名称、图像、链接等)。
    • @mcjordalini:无论您将供应商称为$vendor['foo'] 还是vendor::get('foo'),您仍将使用密钥并且必须在每个使用它的地方更新密钥。
    • 这是真的,我认为误解了您第一次阅读的意思。我很抱歉。我想我仍然想在数组周围包装一个类,它的方法就像其他人建议的那样。
    • @mcjordalini :这完全取决于您的范围以及您需要此数组和数据的可重用程度。我的回答是最简单的方法。 Machavity 的答案没有错,只是更复杂。使用适合您的需求。
    【解决方案4】:

    澄清一下:

    • PHP 恰好有 两个 作用域:“本地”和“全局”。在函数之外声明的任何变量都是“全局的”。在函数中声明的任何变量都是“局部变量”,除非global 指令用于表示它实际上是全局变量。
    • PHP 完全支持递归:一个函数可以(直接或间接)调用自己。该函数的每个活动实例的局部变量都是该实例私有的。
    • 变量通常“按值”传递到函数中,这意味着会产生重复。
    • 如果您有许多需要共享公共数据的相关函数,请考虑创建一个class,函数是该类的“方法”。现在,他们都可以访问$this,它指的是他们所属的对象实例。另请注意,属性(和方法)可以声明为 publicprivate,这是防止代码的其他部分看到 的有效方法(因此,可能会干扰...)时间>他们。

    【讨论】:

    • 我肯定要做一个供应商课程。谢谢:)
    【解决方案5】:

    是的,它会在您每次调用该函数时创建数组。

    执行内存使用会断言它。

    <?php 
    
    function vendorGetArray()
    {
      return array(
        'foo' => array(
          'name' => 'Foo Products',
          'image' => ( 'foo/foo-logo.png'),
        ),
        'bar' => array( // ABT
          'name' => 'Bar Inc.',
          'image' => ( 'bar/bar-logo.png'),
        ),
      );
    
    }
    
    function memoryUsage()
    {
        echo "memory: ".(memory_get_peak_usage(false)/1024/1024)." MiB<br>";
    }
    
    
    $vendorArray = vendorGetArray();
    
    // Array calling vendorGet() function
    $catalogue = array(
      'chapter-1' => array(
        'vendors' => array(
          1 => $vendorArray['foo'],
          2 => $vendorArray['bar']
        ),
      ),
    );
    
    memoryUsage();
    
    ?>
    

    以上代码打印:

    内存:0.231658935547 MiB

    而你的代码

    <?php
    
    function vendorGet($data)
    {
      $vendor = array(
        'foo' => array(
          'name' => 'Foo Products',
          'image' => ( 'foo/foo-logo.png'),
        ),
        'bar' => array( // ABT
          'name' => 'Bar Inc.',
          'image' => ( 'bar/bar-logo.png'),
        ),
      );
    
      return $vendor[$data];
    }
    
    function memoryUsage()
    {
        echo "memory: ".(memory_get_peak_usage(false)/1024/1024)." MiB<br>";
    }
    
    
    // Array calling vendorGet() function
    $catalogue = array(
      'chapter-1' => array(
        'vendors' => array(
          1 => vendorGet('foo'),
          2 => vendorGet('bar'),
        ),
      ),
    );
    
    memoryUsage();
    

    将打印:

    内存:0.231948852539 MiB

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 1970-01-01
      相关资源
      最近更新 更多