tommyhsu
tommyhsu

Reputation: 27

php return an empty array after foreach

Can I avoid the empty array that generate by foreach ?
here is my code

$file="test.txt";
$open = file_get_contents($file);
$lines = explode(PHP_EOL, $open);
foreach($lines as $line){
    $domain = preg_split('/\s+/', $line,-1,PREG_SPLIT_NO_EMPTY);
    echo "<pre>";
    var_dump($domain);
    echo "$domain[0] OK";
    echo "</pre>";
}

test.txt contains this

www.google.com  2.2.2.3
www.test.com    2.2.2.3
www.example.com 2.2.2.3

after I ran my script the result is this

array(2) {
  [0]=>
  string(14) "www.google.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.google.com OK
array(2) {
  [0]=>
  string(12) "www.test.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.test.com OK
array(2) {
  [0]=>
  string(15) "www.example.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.example.com OK
array(0) {
}
 OK

What cause the array(0) to appear?
There's no new line after www.example.com or other element.
Can I remove it or simply don't get it generated?

Upvotes: 0

Views: 1361

Answers (5)

Krishna
Krishna

Reputation: 1540

I have tested your code and found that it's working perfectly... I got this output by same code

  array(2) {
  [0]=>
  string(14) "www.google.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.google.com OK

array(2) {
  [0]=>
  string(12) "www.test.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.test.com OK

array(2) {
  [0]=>
  string(15) "www.example.com"
  [1]=>
  string(7) "2.2.2.3"
}
www.example.com OK 

I think there is new line [enter] in your text file please remove it using backspace and it will work fine..

Upvotes: 0

AD7six
AD7six

Reputation: 66169

You're better off using preg_match_all for such an example:

Just names

<?php
$file = 'test.txt';
$open = file_get_contents($file);
preg_match_all('/^\S+/m', $open, $matches);
print_r($matches[0]);
Array
(
    [0] => www.google.com
    [1] => www.test.com
    [2] => www.example.com
)

Names and numbers

<?php
$file = 'test.txt';
$open = file_get_contents($file);
preg_match_all('/^(\S+)\s+(\S+)$/m', $open, $matches);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => www.google.com  2.2.2.3
            [1] => www.test.com    2.2.2.3
            [2] => www.example.com 2.2.2.3
        )

    [1] => Array
        (
            [0] => www.google.com
            [1] => www.test.com
            [2] => www.example.com
        )

    [2] => Array
        (
            [0] => 2.2.2.3
            [1] => 2.2.2.3
            [2] => 2.2.2.3
        )

)

$result = array_combine($matches[1], $matches[2]);
print_r($result);
Array
(
    [www.google.com] => 2.2.2.3
    [www.test.com] => 2.2.2.3
    [www.example.com] => 2.2.2.3
)

Upvotes: 0

hakre
hakre

Reputation: 197658

I suggest you use the SplFileObject instead:

$path = "test.txt";
$file = new SplFileObject($path);

$file->setFlags(
    SplFileObject::DROP_NEW_LINE   # new line characters at the end of line
    | SplFileObject::SKIP_EMPTY    # skip empty lines, e.g. the one at the end
);

foreach ($file as $line)
{
    $domain = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY);

    echo "<pre>", var_dump($domain), "$domain[0] OK", "</pre>";
}

It not only has support for your issue build in (see the flags) but also parses the file line by line, so for larger files it would not shift it completely into the memory. See as well the file function.

Upvotes: 0

hsz
hsz

Reputation: 152206

Check what contains the last line with:

var_dump($line);

If it contains empty string, just add some check:

if ( empty($line) ) {
  continue;
}

Upvotes: 0

GolezTrol
GolezTrol

Reputation: 116100

There's an extra linebreak or other whitespace character after the last domain.

Trim the text file contents first:

$open = trim(file_get_contents($file));

You could also check if the line isn't empty inside the loop.

$file="test.txt";
$open = trim(file_get_contents($file));  // Either this..
$lines = explode(PHP_EOL, $open);
foreach($lines as $line){

    if ($line === '') // Or this
        continue;


    $domain = preg_split('/\s+/', $line,-1,PREG_SPLIT_NO_EMPTY);
    echo "<pre>";
    var_dump($domain);
    echo "$domain[0] OK";
    echo "</pre>";
}

Upvotes: 2

Related Questions