PHP - array_push()和$array[]无效?

5

1. PHP函数。

我创建了一个验证函数,以下是它的简化版本:

function my_function($input) {
   $settings = my_source(); // function taht outputs a long array

   foreach ($settings as $setting) {
      $id = $setting['id'];  
      $foo = $setting['foo'];
      $option = get_option('my_theme_settings');

        if($foo == "bar") {
           $valid_input[$id] = $input[$id];
        }  

   } 

   return $valid_input; 
}; 

基本上,它会将 $input 保存为 $valid_input。当它获得新的 $input 时,它会覆盖旧的 #valid_input,以此类推。
我想创建一个额外的 $valid_input[$id] 数组,它不会覆盖自身,而是只会向内部推送新元素。
2. Array_push() 不起作用。
因此,新的更新代码将如下所示:
function my_function($input) {
   $settings = my_source(); // function taht outputs a long array

   foreach ($settings as $setting) {
      $id = $setting['id'];  
      $foo = $setting['foo'];
      $option = get_option('my_theme_settings');

        if($foo == "bar") {
           $valid_input[$id] = $input[$id];
        } 

        else if($foo == "noupdate") { // it doesn't work
           $valid_input[$id] = array();        
           array_push($valid_input[$id], $input[$id]);
        } 

   } 

   return $valid_input; 
}; 

如上评论所述 - 这种方式行不通,输入始终会覆盖选项,它创建一个数组但始终只包含被新选项覆盖的一个元素(我猜array_push可以防止这种情况,对吗?)。

3. 对于 $array[] = 也是同样情况

function my_function($input) {
   $settings = my_source(); // function taht outputs a long array

   foreach ($settings as $setting) {
      $id = $setting['id'];  
      $foo = $setting['foo'];
      $option = get_option('my_theme_settings');

        if($foo == "bar") {
           $valid_input[$id] = $input[$id];
        } 

        else if($foo == "noupdate") { // it doesn't work
           $valid_input[$id][] = $input[$id];
        } 

   } 

   return $valid_input; 
}; 

然而它仍会覆盖$valid_input的旧值而不是将元素推入数组。

有什么想法吗?也许代码有问题吗?整个函数是WordPress回调函数,用于名为register_setting()的函数,但我猜这主要与PHP相关,因为WPSE上的人无法帮助我。

4. 编辑

这正是我想要的,但为什么第3点不起作用呢?

    else if($foo == "noupdate") { // it doesn't work
       $valid_input[$id][] = 'something';
       $valid_input[$id][] = 'something_else';
       $valid_input[$id][] = 'something_else2';
    } 

所以你使用相同的$id传递了多个$setting。你尝试在循环内部调试输出$id$foo,以检查它是否实际上是数据导致了这种行为。我想到了一个场景,其中你的$valid_input[$id]被填充,并且最后一个$setting具有$foo == "bar"并用$input[$id]替换了你的数组。提供一些$settings的示例数据会很有帮助。 - Basti
巴斯蒂,嗯,我猜出了什么问题,因为每个设置都有不同的 $id :> - Wordpressor
4个回答

7

在将$valid_input[$id]作为数组使用之前,需要将其设置为数组。

$valid_input[$id] = array();
array_push(  $valid_input[$id], "some stuff");

同样适用于[]符号的表示方法。
$valid_input[$id] =  array();
$valid_input[$id][] =  "some stuff";

要检查数组是否已被声明,请执行以下操作:
if(!is_array($valid_input[$id]){
   $valid_input[$id] =  array();
}

但是我在第一个示例中将它们设置为数组,这不会改变任何情况。 - Wordpressor
雷,还是没有任何东西,但请检查更新。也许,只有可能,$input[$id]有问题? - Wordpressor
那是我听过的最荒谬的事情。谢谢! - Chris Burbridge
所以在php 7.2中,我需要首先将我的数组定义为一个数组,就像这篇文章所概述的那样。在php 5.5中,以下内容可用于将数组添加到多维数组$response_array['users'][],但在php 7.2中,我必须通过$response_array['users'] = array();来定义$response_array['users']为一个数组,然后才能执行$response_array['users'][] = array('id'=>'someID')。希望这可以帮助某些人,因为我花了至少一个小时的时间来尝试解决这个问题,直到我找到了这篇文章并尝试首先设置为数组。 - William Worley
第二个片段是不正确/误导的。在使用$valid_input[$id][] = "some stuff";(方括号推送语法)将子元素推入父元素之前,不需要先使用$valid_input[$id] = array(); - mickmackusa
显示剩余2条评论

4

问题在于对象是作为引用传递的。在使用array_push函数之前,您需要克隆对象。以下是一个示例函数,可用于克隆对象:

function DeepCopy($ObjectToCopy) {
    return unserialize(serialize($ObjectToCopy));
}

然后你可以这样使用它

array_push($MyObjectsArray, DeepCopy($MyObject));

$valid_input[$id] = array_push($valid_input[$id],unserialize(serialize($input[$id]))); 不返回任何内容。 - Wordpressor
@Wordpressor:你不能这样使用array_push() - 请查看手册。array_push()返回一个整数值,表示现在数组中的元素数量。按照你在评论中的方式操作只会覆盖数组! - WWW
1
搞定了!非常感谢!虽然在将其分配并推送到数组之前,我只是创建了一个新对象: $dataObject = new $className; $dataObject = ...; array_push($dataArray, $dataObject); - Zaphoid

1

你是否尝试将一个已经存在的键值对应的新值推入数组中?在尝试推入值/键对之前,我建议你先检查数组中是否存在该键值。举个例子:

if ( !isset( $arr[ $key ] ) ) {
  $arr[ $key ] = $value;
} else {
  echo " duplicate key value ";
}

b_dubb,做得很好,但那不是情况。 :( - Wordpressor
1
我仍然没有看到你在数组中测试现有的键元素。在尝试将新值推送到 $arr 之前,应该先测试 $arr[key]。 - b_dubb

0

无论是使用array_push()还是使用数组追加运算符[]的变量,都需要实际上是一个数组,否则这些操作将不起作用。在对变量进行数组操作之前,请仔细检查$valid_input[$id]中的内容是否为数组。可以通过以下方式进行检查:

if (is_array($valid_input[$id])) {
    // your code
}

Crontab,它们都是数组。 - Wordpressor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接