【问题标题】:PHP - Best way to extract associative POST dataPHP - 提取关联 POST 数据的最佳方法
【发布时间】:2025-12-15 18:30:01
【问题描述】:

我有这个 $_POST 数组的东西:

  'name' => string '' (length=0)
  'limit' => string '100' (length=3)

  'timeframe' => 
    array
      'start' => string '00:00' (length=5)
      'end' => string '23:30' (length=5)

  'person' => 
    array
      'test' => string '' (length=0)
      'title' => 
        array
          0 => string 'value1' (length=2)
          1 => string 'value2' (length=3)

我想为名为@9​​87654322@ 的字段提取数据,高效执行此操作的最佳方法是什么?

实际上,我将问题范围缩小到了这个示例,但我更普遍地实现了这一点,因此我可以为代码中的任何数组命名字段提取数据。

提前致谢


更新 1

好吧,我想我还不清楚,问题又来了:

我有一个这种格式的字段名称:name_1[name_2]..[name_n][] 并且它的值在$_POST 关联数组中可用,我需要提取该值(这是一个数组,因为末尾有 [])。

我可以通过运行preg_match 或其他东西从原始字段名中提取子名称,然后循环遍历数组,直到我使用提取的索引找到值。但我不确定这是否真的是最好和/或有效的方法。

抱歉一开始不清楚^^


更新 2

伙计们,我说过我将问题范围缩小到这个例子,但在我的实际应用程序中没有person 的东西。我正在开发一个数据解析器引擎来处理大量数据,而该功能正是它所需要的。希望它;现在很清楚。

谢谢大家,顺便说一句^^

【问题讨论】:

  • $_POST['person']['title'] 会给你数组,但我不确定这是否是你要问的
  • 能否请您分享<?php print_r($_POST); ?> 的结果,因为它有点不清楚。
  • @Jack:感谢您的意见,我更新了我的问题。
  • @metal_fan:这实际上是 var_dump($_POST) 与 xdebug 到位的结果。这是路径:$_POST['person']['title'] 这是一个数组。
  • @artarad 所以数组的深度并不总是相同还是什么?

标签: php arrays performance


【解决方案1】:

我会使用$title = $_POST['perosn']['title']

或者甚至更好地将整个人转换为对象。

$person = (object)$_POST['person'];
echo $person->name // Call it

【讨论】:

  • 为什么你说投射到对象中更好?有意义吗?
  • 根据问题中呈现的结构,如何获取person对象中'title'的内容? $person->title->0 有效吗?
  • 好吧,这里不需要强制转换。这只是偏好问题。
  • 没错,我更喜欢使用对象而不是数组。我只是想我和大家分享这个偏好,猜不是:)
  • 要访问此表单中的标题,应为$person->title[0]
【解决方案2】:

好吧,给你:

/**
 * Extracts value from an associative array by fieldname sequence.
 *
 * Example:
 *
 * This string:
 * my_group[my_subgroup][multiselect_field][]
 *
 * Requests the helper to extract the value of: (if exists)
 * $array[my_group][my_subgroup][multiselect_field]
 *
 * @param  string $name  Fieldname string.
 * @param  array  $array Haystack array to dig.
 *
 * @return array  Extracted value or FALSE on failure.
 */
function _extract_value($name, array $array)
{
    // Check if it's a array fieldname, go for brackets
    if (strpos($name, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $name, $matches))
    {
        $count  = count($matches[0]);
        $keys[] = current(explode('[', $name));

        // Extract fieldname keys
        for ($i = 0; $i < $count; $i++)
        {
            $matches[1][$i] != '' AND $keys[] = $matches[1][$i];
        }

        return _reduce($array, $keys);
    }

    return FALSE;
}

// --------------------------------------------------------------------

/**
 * Helper: Reduces the array by the passed array of keys which leds to find the value!
 *
 * Traverses a multi-dimensional array until the value of the keys specified
 * in keys array is found. Returns FALSE if not found.
 *
 * @param  array   $array Array to reduce.
 * @param  array   $keys  Array keys sequence. Traverse map in fact.
 * @param  integer $i     $keys array index to start from.
 *
 * @return array          Extracted value or FALSE on failure.
 */
function _reduce($array, $keys, $i = 0)
{
    // Not an array, or a wrong index to start
    if ( ! is_array($array) OR ! isset($keys[$i]))
    {
        return $array;
    }

    // Go deep, find the value
    return isset($array[$keys[$i]])
        ? _reduce($array[$keys[$i]], $keys, $i + 1)
        : FALSE;
}

// --------------------------------------------------------------------

$titles = _extract_value('', $_POST);
var_dump($titles);

取自 CodeIgniter 的 Form_validation 库。

【讨论】:

  • 好吧,终于!!我会测试并报告回来^^
  • 是的!抱歉回复晚了,我刚刚忘记了^^再次感谢您
【解决方案3】:

要非常具体的问题:

我想为名为 person[title][] 的字段提取数据,什么是 有效地做到这一点的最佳方法?

好吧,&lt;? $person[title][]?&gt; --- 我们不能用它来阅读。 如果您尝试按照您的方式阅读,PHP 将产生致命错误。 我们使用[] 将新元素推送到给定数组。 再次 - 只添加新项目。 为了读取这些,您只能访问数组中所需的key

在您的情况下,您可以访问$_POST['person']['title']

您是在询问最好的方法,但这完全取决于您正在处理的任务。

好吧,如果我们谈论的是$_POST,那么我们可能正在处理一个表单。为了让你的代码保持干净和可维护,你真的应该像你一样使用更深的数组。

为什么?

你会得到&lt;input type="text" name="name_of_the_current[]"&gt;(看我们正在定义一个数组)不需要让它更深。

更新

嘿,我们正在处理简单的表单。为什么 $_POST 太深了?好吧,反正这不是一个好主意,原因如下:

1) 维护现有的HTML/PHP 代码有点困难。想象一下,如果您必须更新/修改代码中的某些内容。我想这需要一些时间。

2) Deep array 也意味着需要更多时间来迭代它。 (大约 ~0.0008 毫秒(在你的情况下),如果我错了,请纠正我)

我很抱歉,但我必须建议你一些更合适的东西:)

1) 首先,这个人是PRIMARY AND UNIQUE KEY,对吧?我想是的。

例如, 大多数 php 开发人员通常会这样做:

<?php
//suppose we have it from database or from
$persons = array
(
  'john_123' => array('age' = 40, 'gender' =>'M', 'location' => 'somewhere'),
  'linde_22' => array('age' = 30, 'gender' =>'F', 'location' => 'somewhere_else')  
);

//
print $persons['john_123']['age']; //prints 40...
?>

好处

  1. 很干净
  2. 易于维护
  3. 不要太深
  4. 快一点

【讨论】:

  • 我更新了问题,metal_fan。请你看看好吗? ty
  • 感谢您的解释,我知道您在说什么,但这不是重点,我只是设置了 person 名称作为示例目的。我正在开发一个数据解析器引擎,它通常需要这样的功能(正如我在更新中所说的那样)。无论如何你:D
  • @artarad 老实说,我无法完全解决您的问题,但尝试了。好吧,那就用&lt;?php foreach ($_POST as $index =&gt; $array){ if (is_array($array)){ /* Do deep iteration right here and don't forget to break the loop */ } }
  • 感谢您的宝贵时间,真的。你知道,我正在寻找一种更通用的方式来面对这个巨大的数组。我会用更多细节更新这个问题。你,你^^
  • @artarad 听着,当我们开发数据引擎解析器时,我们总是关注,我说的是“更一般的方式”,1)数据的种类(即数据分析器,如验证函数等等...... 2)数组的最大允许深度 3)数据验证器和提取器(两者都是某些类中的自定义函数或方法) 4)数据收集器(即一些成功的数组)。这是要走的路,至少我认为。因为我做了类似这样的事情(使用深度数组解析器的数据),它对我很有用。
【解决方案4】:

Pre-optimization is the devil - 直到你真正遇到这段代码导致你的软件开发工作出现瓶颈的地方,你真的应该避免任何优化,你的瓶颈更有可能将在数据库中,在您注意到速度下降之前。

首先 - 让它发挥作用。 第二 - 改进它。

从您提供的数组中,您可以执行以下操作:

foreach ($arr['person']['title'] as $title){
  if ($title == $match_condition) // do something
}

【讨论】:

  • 我明白你在说什么 Itai,但我正在开发一个数据解析器引擎,它通常需要这样的功能(正如我在更新中所说的那样)。这只是它的目的,而不是瓶颈:p