【问题标题】:Php errors on parsing an array that comes from xml解析来自 xml 的数组时出现 PHP 错误
【发布时间】:2018-10-23 21:49:37
【问题描述】:

我正在查看下面的示例

$array = [
    'Name1' => [
        'diametru' => [7,6]
    ],
    'othername' => []
];
$output = array_keys($array);
$option = '';
foreach ($output as $val) {
    $option .= "<option>$val</option>";
}
print_r($option);

输出是:

<option>Name1</option>
<option>othername</option>

但是当我尝试申请我的数组时:view-source:http://vilavaleaprahovei.ro/kimea/allMarks.php 看起来与上面的 $array 相似的键结构:

$strarray = file_get_contents('allMarks.php');
$output = array_keys($strarray);
$option = '';
foreach ($output as $val) {
    $option .= "<option>$val</option>";
}
print_r($option);

我收到两个错误:“array_keys() 期望参数 1 是数组”和“为 foreach() 提供的参数无效”。

您能告诉我如何将 allMarks.php 数组键输出到选项标签中吗?

【问题讨论】:

  • file_get_contents 返回一个字符串,而不是一个数组。
  • 什么是all_marks.php
  • allMarks.php是数组链接文件
  • 即使你包含(包含或需要)文件,在父文件范围内设置的变量是什么?这就是问题... :-(
  • 您似乎使用var_export 在该 PHP 文件中打印了一个数组。如果你想让它工作,你应该 return 代替数组。请参阅此处的示例 #5:php.net/manual/en/function.include.php

标签: php arrays compiler-errors


【解决方案1】:

获取数据

您应该包含/要求该文件,但您必须先使其成为正确的 PHP 文件。

 $array = require $pathtoFile;

正确的 PHP 文件是什么意思。好吧,它没有 php 标签&lt;?php,它应该是return 数组,并且不要在最后得到;。当你打开你的文件时,它应该是这样的(除非它显然没有.....):

<?php
     return array( ..... ); //don't forget the semi-colon

然后它将起作用。你也可以使用eval,如果它没有在你的服务器上被禁用,但它充满了各种安全风险。所以我什至不想参与讨论。

保存数据

当您使用file_put_contentsvar_export 保存这样的文件时,您应该这样做:

file_put_contents($pathtofile, '<?php return '.var_export($array, true).';');

然后它将包含使其语法正确的这些内容。

修复现有问题

如果您(像我一样)懒得手动编辑它,您可以这样做:

   file_put_contents($pathtofile, '<?php return '.file_get_contents($pathtofile).';');

只要确保您只对文件执行一次,否则您最终会得到像 &lt;?php return &lt;?php return array(...);; 这样的东西,当您包含它时就会爆炸。

一旦你得到正确的文件语法,你就可以如上所示包含它(就像任何 PHP 文件一样)。请记住,它必须是有效的 PHP 文件。

享受吧!

更新

也许这会澄清一些事情:

$jante = "http://vilavaleaprahovei.ro/kimea/feeds/alcarRO_wheels_feed.xml";

$xml=simplexml_load_file($jante);

$items = [];
foreach($xml->Produs as $child)
{
   $marca = (string)$child->Marca;
   if(!isset($items[$marca])) {
       $items[$marca] = [];
   }
   $items[$marca]['diametru'][] = (int)$child->Diametru;
   $items[$marca]['latime'][] = (int)$child->Latime;
   $items[$marca]['pcd'][] = (int)$child->PCD;
   $items[$marca]['pcd1'][] = (int)$child->PCD1;
   $items[$marca]['et'][] = (int)$child->ET;
   $items[$marca]['cb'][] = (int)$child->CB;
}

foreach($items as $marca => $item) {
    ///$myfile = fopen("allMarks.php", "w") or die("Unable to open file!"); //not needed
    $items[$marca]['diametru'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['latime'] = array_unique($items[$marca]['latime']); 
    $items[$marca]['pcd'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['pcd1'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['et'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['cb'] = array_unique($items[$marca]['diametru']);

    //fwrite($myfile, var_export($items, true)); //not needed

    /* -NOTE-
     This file is overwritten here on each iteration of the loop, you don't 
    see it because you are writing the top level $items, and then
    progressively overwriting it and ending with the last (fully populated)
    array in the file, but it wastes a lot of resources for nothing.
    */

    //fclose($myfile); //not needed
}

 $myfile = 'allMarks.php'; //not sure where this was set.
//add this
file_put_contents($myfile, '<?php return '.var_export($items, true).';');

//$strarray = file_get_contents('allMarks.php');
// var_dump($strarray);

然后我尝试在 html 选择选项中显示该数组的键:

$array = require 'allMarks.php';
//return $array; //not needed
//file_put_contents('allMarks.php', '<?php return '.file_get_contents('allMarks.php').';'); //not needed
$output = array_keys($array);
$option = '';
foreach ($output as $val) {
    $option .= "<option>$val</option>";
}
print_r($option);

请注意,如果这是在同一个文件中,或者是同一个请求,那么将其保存到文件中是没有意义的,因为您已经拥有数据并且可以简单地使用它。如果您需要跨请求的持久性,您只需将其存储在某个地方。比如缓存的原因。您读取数据创建文件,然后下一个请求只需要读取您创建的文件而不是创建它:

//file_put_contents($myfile, '<?php return '.var_export($items, true).';');
//$array = require 'allMarks.php';
//just use the data
 $output = array_keys($items);

您也可以消除整个循环:

foreach($items as $marca => $item) {
    ///$myfile = fopen("allMarks.php", "w") or die("Unable to open file!"); //not needed
    $items[$marca]['diametru'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['latime'] = array_unique($items[$marca]['latime']); 
    $items[$marca]['pcd'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['pcd1'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['et'] = array_unique($items[$marca]['diametru']);
    $items[$marca]['cb'] = array_unique($items[$marca]['diametru']);

    //fwrite($myfile, var_export($items, true)); //not needed
    //fclose($myfile); //not needed
}

通过设置$items[$marca]['{...}'] 中的键,PHP 中的数组键是唯一的(不能有两个具有相同值的键),因此您可以利用它们来利用这一点,并避免执行另一个循环来调用它们的唯一数组。

在那之前的循环中:

foreach($xml->Produs as $child)
{
   $marca = (string)$child->Marca;
   if(!isset($items[$marca])) {
       $items[$marca] = [];
   }
   $diametru = (int)$child->Diametru;
   $items[$marca]['diametru'][$diametru] = $diametru; //save as key and value
   $latime = (int)$child->Latime;
   $items[$marca]['latime'][$latime] = $latime; 
   $pcd = (int)$child->PCD;
   $items[$marca]['pcd'][$pcd] = $pcd;
   $PCD1 = (int)$child->PCD1;
   $items[$marca]['pcd1'][$PCD1] = $PCD1;
   $et = (int)$child->ET;
   $items[$marca]['et'][$et] =  $et;
   $cb = (int)$child->CB;
   $items[$marca]['cb'][$cb] = $cb; 
}

如果您需要它们编号,您已经知道如何执行array_keys(您可以使用相反的array_values 将其删除)。甚至可以通过简单地(对他们每个人)执行以下操作来更轻松地设置这些:

 $items[$marca]['diametru'][$x=(int)$child->Diametru] = $x;
 $items[$marca]['latime'][$x=(int)$latime] = $x;
 //..... etc

但这有点难以理解,所以我不想让你感到困惑。基本上,我们将$child's 属性的值分配给被设置的$x= 单等号是赋值),然后我们可以将它用于键和值。然后我们就在下一行回收它。

无论如何,你最终会得到这个$items[$marca]['diametru']["value"] = "value" 而不是$items[$marca]['diametru'][0] = "value",这个值既是值又是键。你可以用array_values 删除它(我不知道这些变量的值,所以我必须弥补):

    //your original array (with the 2 loops) would look something like this,
    //with numeric keys
    $items[$marca]['diametru'] = [   
       0 => "value0",
       1 => "value1",
       2 => "value1", //duplicate
    ];

    //by removing the second loop and using the value for both the key and value

    $items[$marca]['diametru'] = [   
      "value0" => "value0",
      "value1" => "value1",
       //no duplicates possible as the keys are unique
    ];

Sandbox

现在我必须强调您不必删除密钥,大多数时候它们是否存在并不重要,只有当您特别需要对它们进行编号时,您才需要循环并删除它们.即使这样,您也将在较小的数组上循环,因此您仍然可以节省一些性能(取决于有多少副本,副本越多,您保存的越多)。

看看这就是共享代码的好处。通常有更有效和更简单的方法来做事,像我一样做一个懒惰的程序员,不要做超过你需要的工作。

这是我在没有看到XML 的情况下能做的最好的事情,但是您仍然会遇到问题,因为您每次循环时都会覆盖文件,所以我不确定修复会产生什么影响数组结构去。现在,如果您执行array_keys($items),它将为您提供$marca 的列表。这使得你正在做的很多事情变得多余,除非这里还有更多事情要做。因为如果你只需要那个,那么你就不需要在数组$items[$marca]中跳过这个了

干杯!

【讨论】:

  • file_put_contents('allMarks.php', '$val"; } print_r($option);该代码会产生与我的第一篇文章相同的两个错误
  • 您没有像我展示的那样包含文件,您仍然在字符串上调用数组函数。换句话说,您永远不会在代码中添加$array = require 'allMarks.php';(您必须在下一行将其从$strarray 更改为$array
  • 另一种方式但仍然相同的两个错误:file_put_contents('allMarks.php', '$val"; } print_r($option);
  • 再一次,你从来没有包含过文件,你所做的只是把你的文件弄得越来越乱......
  • 我来自vilavaleaprahovei.ro/kimea/allMarks.php的数组不正常?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多