【问题标题】:Warning: array_push() expects parameter 1 to be array, string given警告:array_push() 期望参数 1 是数组,给定字符串
【发布时间】:2014-09-04 08:57:13
【问题描述】:

我在这段代码中得到了Warning: array_push() expects parameter 1 to be array, string given in ...array_push()。首次推送时出现警告,如何解决?

$url = $_SERVER['QUERY_STRING'];

$chunk = explode("&",$url);
array_pop($chunk);

foreach($chunk as $key => $value)
{
    $pieces = explode("=",$value);
    if($pieces)
    {
        $val = $pieces[0];
        if(isset($$val))
        {
            array_push($$val,$pieces[1]);
        }else{
            $$val = array();
            array_push($$val,$pieces[1]);
        }
    }
}

注意:我没有使用 $_GET,因为我的查询字符串可以包含多个具有相同名称的参数,像这样

?q=1&q=2&q=3&q=4

【问题讨论】:

  • $url 的值是多少?
  • 为什么不直接使用已经解析并提取了查询字符串的 $_GET 呢?
  • 您可以添加额外的检查if(isset($$val) && is_array($$val))
  • 顺便说一句,代码运行良好,我只是收到此警告并想摆脱它。它不是我制作的,我还是 PHP 新手,以前从未使用过 $$ 变量。
  • 我尝试添加 is_array 附加检查,然后我得到:注意:数组到字符串的转换

标签: php arrays array-push


【解决方案1】:

您不需要分解和推送/弹出查询字符串。只需使用 $_GET 超全局即可。

http://php.net/manual/en/reserved.variables.get.php

编辑:$_GET 是一个数组,你可以像任何其他数组一样循环它。如果您需要单独获取所有这些,则可以这样做:

foreach ($_GET as $key => $value) {
    // whatever
}

Edit2:好的,我仍然认为无论您使用这些参数做什么都是错误的方法,但是如果您需要一个函数,那么您可以尝试这样的事情:

function extractVars($url)
{
    $query = explode('?', $url);

    $extract = array();

    if (!isset($query[1])) {
        return $extract;
    }

    $params = explode('&', $query[1]);
    foreach($params as $param) {
        if (strpos($param, '=') !== false) {
            list($key, $value) = explode('=', $param);
            $extract[$key][] = $value;
        }
    }

    return $extract;
}

$string = 'url?a=1&a=2&a=3&b=1&b=2&b=3';
print_r(extractVars($string));

它给出了这样的输出:

Array
(
  [a] => Array
  (
    [0] => 1
    [1] => 2
    [2] => 3
  )

  [b] => Array
  (
    [0] => 1
    [1] => 2
    [2] => 3
  )
)

【讨论】:

  • 这将需要我重写整个代码并一个一个地获取每个变量,如果你有 1 或 2 个变量,这很好,但如果你有很多变量,那就不行了。代码运行良好,我刚收到此警告,想了解如何摆脱它。
  • $$val 可以是也可以不是数组。相同的查询字符串参数可以重复多次,例如 &q=123&q=456&q=789
  • @BrunoDomingues 不过,您的代码运行不正常。它发出警告。有效的代码不会引发警告。这也违反直觉,大多数 PHP 程序员都希望您使用 $_GET 来获取查询字符串参数。任何不这样做的代码都将具有比应有的更高的“WTF/分钟”比率。 osnews.com/story/19266/WTFs_m
  • 是的,我的意思是它不会导致任何致命错误,项目列表无论如何都会显示并且看起来不错,由于此警告,某处可能缺少某些内容。我只有在打开警告时才看到这一点,这段代码已经工作了一年,从不知道有什么问题。 :)
  • 代码运行不正常。您正在以最低效和最不可维护的方式提取所需的数据。查看我的编辑。
【解决方案2】:

只有当$$val 已经是一个数组时,这段代码才有效。如果不是,则会产生该错误。

array_push($$val,$pieces[1]);

所以试试这个:-

foreach($chunk as $key => $value)
{
    $pieces = explode("=",$value);
    if($pieces)
    {
        $val = $pieces[0];
        if( isset($$val) && is_array($$val) ) {
            array_push($$val,$pieces[1]);
        } else {
            $$val = array();
            array_push($$val,$pieces[1]);
        }
    }
}

当然使用 PHP 自动为你准备的 $_GET 数组会更容易

您发表评论后的其他想法

这个警告的原因可能是你使用的是旧版本的 PHP 并且有参数register_globals = on

所以假设一个网址为www.xx.com?q=1&q=2&q=3

这意味着 PHP 已经为您创建了一个 $q 变量。所以第一次通过你的代码会发现查询字符串中的所有变量都已经作为字符串存在,即 PHP 已经创建了这样的变量,对你来说是不可见的。

$q = '1';
$q = '2';
$q = '3';

因此,当您的代码第一次尝试 array_push($$val,$pieces[1]); $$val 时,它等同于 $q$q 已经是一个标量字符串变量,因此您的错误消息。

您可以通过添加来检查是否是这种情况

print_r($GLOBALS);

就在您发布的脚本部分之前。然后根据已经存在的变量检查 url。

另一个想法

解释此警告的唯一方法是,无论出于何种原因,您尝试在此代码 sn-p 中创建的一个或多个变量已经存在。

这段代码很可能最初在没有警告的情况下工作,但此后代码被修改,并且有人在代码的早期出于某种临时目的创建了一个或多个变量。

因为您的查询字符串参数等同于变量,如

cid, val, np, wgt, w, l, h

很可能有人在循环中使用 $w 或 $l 或 $h 来保存一个值,特别是为了一些临时目的。通常的做法是使用单字母变量名称来表示该变量仅在您可以在屏幕上看到的几行中使用。但很少有人在不再需要它们时将其销毁。

不管怎样,看看在你的代码 sn-p 之前是否已经创建了一个或多个这些变量是值得的。

添加一个

print_r($GLOBALS) 

就在您的代码 sn-p 之前,看看这些变量是否已经存在。

【讨论】:

  • $$val 可以是也可以不是数组。相同的查询字符串参数可以重复多次,例如 &q=123&q=456&q=789
  • 这解释了为什么你不使用 $_GET 数组。
  • 根据您的评论查看我的补充
  • PHP 版本为 5.5.11,auto_globals_jit = On
  • 我认为不会导致这个问题。尝试在执行代码之前添加 `print_r($GLOBALS) 以查看这些变量是否确实存在。
【解决方案3】:

鉴于网址类似于 www....php?a=b&c=d&e=f,您将其分解为几个元素 a=b、c=d、e=f。你放弃 a&b,然后继续 c=d 和 e=f。然后你拿起 c=d,把它分解成 c 和 d 的值。因此 c 不太可能是一个数组,这已被错误消息证明。

尝试通过添加 print_r($val) 和 print_r($$val) 来查看内容。它应该让您大致了解实际评估的内容,并从那里开始工作。我想你会发现 variable 变量也没有按预期工作。

【讨论】:

  • 网址不是这样的,可以是a=b&a=c&a=d&b=1&b=2&b=3
  • 给定代码,默认情况下它仍然没有为您提供 $$a 的数组。您需要先定义它,或者作为一个替代结构,如 $$a[] = $b 可以工作,但是我无法在我现在所在的位置对其进行测试。
【解决方案4】:

好的,伙计们,我按照您的建议解决了这个问题,即去掉循环代码并用正确的代码替换它。

它现在运行良好,而且是一个简单的解决方案。

$h   = $_GET["h"];
$w   = $_GET["w"];
$l   = $_GET["l"];
$wgt = $_GET["wgt"];
$np  = $_GET["np"];
$cid = $_GET["cid"];

if (!is_array($h))   $h   = [$h];
if (!is_array($w))   $w   = [$w];
if (!is_array($l))   $l   = [$l];
if (!is_array($wgt)) $wgt = [$wgt];

第一部分将参数一个一个的拿到变量中,第二部分是字符串的时候转换成数组。

感谢您的帮助和建议。 :)

【讨论】:

    【解决方案5】:

    只需删除 $$val 中的一美元 ($)。

    【讨论】:

    猜你喜欢
    • 2021-12-29
    • 2013-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多