0

I am looking on my below sample

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

output is:

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

but when I try to apply for my array: view-source:http://vilavaleaprahovei.ro/kimea/allMarks.php that looks similar key structure with the above $array:

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

I recieve two errors: "array_keys() expects parameter 1 to be array" and "Invalid argument supplied for foreach()".

Could you please advice me how to output the allMarks.php array key into option tag?

  • 2
    `file_get_contents` returns a string, not an array. – Barmar Oct 23 '18 at 21:53
  • What is `all_marks.php`? – Barmar Oct 23 '18 at 21:53
  • The allMarks.php is the array link file – Gafwebmaster Oct 23 '18 at 21:56
  • Even if you include (with include or require) the file what is the variable set too in the parent files scope? That is the question ... :-( – ArtisticPhoenix Oct 23 '18 at 21:57
  • That "include" it loading the array values, but I need just to add key value inside of every html select option: $strarray = include('http://vilavaleaprahovei.ro/kimea/allMarks.php'); – Gafwebmaster Oct 23 '18 at 21:59
  • 1
    It looks like you used `var_export` to print an array in that PHP file. If you want this to work, you should `return` the array instead. See Example #5 here: http://php.net/manual/en/function.include.php – Don't Panic Oct 23 '18 at 22:00
  • @Don'tPanic - that's the best way, `eval` dare I say would work too, or he can make a parser for it (well I can make one at least) but it's a waste of time, I would just open the file and add ` – ArtisticPhoenix Oct 23 '18 at 22:01
  • Is not clear what about you asked me "parent files scope"; the array file: http://vilavaleaprahovei.ro/kimea/allMarks.php is made, then I try to create a filter for, reason to add inside of a html option – Gafwebmaster Oct 23 '18 at 22:03
  • If I use: return "allMarks.php"; how can assign the result to a variable "$strarray", in order to make foreach in $strarray, to extract the array keys of it? – Gafwebmaster Oct 23 '18 at 22:06
  • You assign it when doing the include `$var = include 'allMarks.php'` include is like copying and pasting the code. So it takes the `return` value from the included file an puts it in the variable. Right now all you have is a string that happens to look like an array. – ArtisticPhoenix Oct 23 '18 at 22:38
  • Possible duplicate of [Reference - What does this error mean in PHP?](https://stackoverflow.com/questions/12769982/reference-what-does-this-error-mean-in-php) – miken32 Oct 23 '18 at 22:46
  • Thank you @ArtisticPhoenix but still I don't know what is wrong on my code below, see the detailed flow in a readable format code – Gafwebmaster Oct 23 '18 at 22:54
  • @miken32 the post is about echo an array key value that comes from xml, not about what error mean – Gafwebmaster Oct 23 '18 at 22:56
  • Yes, and you can check there to find out how to fix the error. Specifically, don't pass a string to function that's expecting an array. Here you can read about what `file_get_contents()` returns: http://php.net/file_get_contents – miken32 Oct 23 '18 at 22:58
  • @miken32 Yes, but still is not clear where I am wrong on my flow: xml-array-option – Gafwebmaster Oct 23 '18 at 23:04
  • What does `file_get_contents()` return? A string. What does `array_keys()` expect to get? An array. You will need to explain your problem better if you're expecting something else to happen. – miken32 Oct 23 '18 at 23:17

1 Answers1

0

Getting the data

You should include/require the file, but you'll have to make it a proper PHP file first.

 $array = require $pathtoFile;

What do I mean by a proper PHP file. Well it doesn't have the php tag <?php and it should return the array, and don't for get the ; at the end. When you open your file it should look like this (except it wont have the ..... obviously) :

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

Then it will work. You could also use eval maybe if it's not disabled on your server, but that is full of all kinds of security risks. So I don't even wan't to get into that discussion.

Saving the data

When you save a file like this with file_put_contents and var_export you should do it like this:

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

Then it will contain these things that make it syntactically correct.

Fixing what you have now

If your too lazy (like me) to manually edit it you could do this:

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

Just make sure you only do it one time to the file, other wise you'll end up with stuff like this <?php return <?php return array(...);; which will just blow up when you include it.

Once you get the syntax of the file correct you can include it as shown above (just like any PHP file). Remember it has to be a valid PHP file.

Enjoy!

UPDATE

Here maybe this will clearfy things:

$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);

then I try to show inside of html select option just the key of that array:

$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);

Note if this is in the same file, or the same request then saving it to a file is pointless as you already have the data an can simply use it. You only need to store it somewhere if you need persistence across requests. Such as for caching reasons. You read the data create the file, then the next request for this only needs to read the file you created and not create it:

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

You can also eliminate this entire loop:

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
}

By setting the keys in $items[$marca]['{...}'] Array keys in PHP are unique (you cannot have 2 keys with the same value) so you can take advantage of this by using them and avoid doing another loop to call array unique on them.

In the loop before that one:

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; 
}

If you need them numbered you already know how to do array_keys (you can use the opposite array_values to remove it). And even these can be set easier by simply doing this (to each of them):

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

But it's a bit harder to understand so I didn't want to confuse you. Basically we assign the value of the $child's property to $x that gets set (= single equal sign is assignment) and then we can use it for both the key and the value. Then we just recycle it on the next line.

Anyway you will wind up with this $items[$marca]['diametru']["value"] = "value" instead of $items[$marca]['diametru'][0] = "value" the value will be both the value and the key. Which you can remove with array_values (I don't know the value of any of these variables, so I have to make stuff up):

    //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

Now I have to stress you do not have to remove the keys, most of the time it doesn't matter if they are there, only if you specifically need them to be numbered would you need to loop back through and remove them. Even then you will be looping over smaller arrays, so you still save some performance (depending on how many duplicates there are, more duplicates the more you saved).

See this is the benefits of sharing your code. There is often more efficient and easier ways to do things, be a lazy programmer like me and don't do more work then you need to.

That's the best I can do without seeing the XML but your still going to have issues because you were overwriting the file each time it looped, so I am not sure what carry on effects fixing that will have as far as the array structure goes. Right now if you do array_keys($items) it will give you a list of $marca. Which makes a lot of what you are doing redundant, unless there is more going on here then just this. Because if all you need is the that then you don't need to go past this in the array $items[$marca]

Cheers!

ArtisticPhoenix
  • 21,464
  • 2
  • 24
  • 38
  • file_put_contents('allMarks.php', '$val"; } print_r($option); That code create the same two errors as my first post – Gafwebmaster Oct 23 '18 at 22:12
  • You didn't include the file as I showed, your still calling an array function on a string. In other words you never put `$array = require 'allMarks.php';` in your code (and you have to change it from `$strarray` to `$array` in the next line. – ArtisticPhoenix Oct 23 '18 at 22:13
  • Another way but still the same two errors: file_put_contents('allMarks.php', '$val"; } print_r($option); – Gafwebmaster Oct 23 '18 at 22:15
  • Again, you never included the file, all you are doing is messing your file up more and more.... – ArtisticPhoenix Oct 23 '18 at 22:16
  • My array that comes from http://vilavaleaprahovei.ro/kimea/allMarks.php is not ok? – Gafwebmaster Oct 23 '18 at 22:25
  • It's not your array, if you save it as text (in a php file) that PHP file still needs to have the correct syntax to work, the correct format. Otherwise it's just a text file. – ArtisticPhoenix Oct 23 '18 at 22:29
  • Should I do like that? $array = require 'allMarks.php'; return $array; file_put_contents('allMarks.php', '$val"; } print_r($option); – Gafwebmaster Oct 23 '18 at 22:30
  • I don't know I can't read that, I've outlined everything you need to make it work above (in the answer) – ArtisticPhoenix Oct 23 '18 at 22:31
  • The file is made extracting values from a xml file, I am not doing with my hands. That code is doing the allMarks.php $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; } – Gafwebmaster Oct 23 '18 at 22:35
  • foreach($items as $marca => $item) { $myfile = fopen("allMarks.php", "w") or die("Unable to open file!"); $items[$marca]['diametru'] = array_unique($items[$marca]['diametru']); $items[$marca]['latime'] = array_unique($items[$marca]['latime']); $items[$marca]['pcd'] = array_unique($items[$marca]['diametru']); ......['diametru']); $items[$marca]['et'] = array_unique($items[$marca]['diametru']); $items[$marca]['cb'] = array_unique($items[$marca]['diametru']); fwrite($myfile, var_export($items, true)); fclose($myfile); } $strarray = file_get_contents('allMarks.php'); – Gafwebmaster Oct 23 '18 at 22:35