Ranjit
Ranjit

Reputation: 51

How do I get a PHP program to not end with "killed" in the output?

I am trying to parse a .log file with PHP. My program keeps ending with the "killed" message. I tried running my PHP program on two different servers with the same input .log file.

Ultimately I need to count the instances of a pattern in the .log file. This .log file is a text file with each line having various text. Each line will have a hyphen that will act as a field separator. Any text to the right of a dash "-" on a given line can be discounted and not considered.

I have a recursive function named "caller." I have tried re-writing the code to not use recursion. I had different problems with that approach.

I have tried saving my output to a variable or to a new file. Neither approach gave me a clear advantage. I do not think the output (saving up patterns according to my logic) is causing the memory issue.

I have a nested loop in the code. For each line of the .log file, I am examining each character left-to-right to find the dash "-".

The dmesg command shows a line like this for each time I run the PHP program:

Out of memory in UB 999: OOM killed process 950 (php) score 0 ...

How can I re-write this to not end with a "killed" message?

(My code does not count the patterns yet. I am not ready to complete it. I just want to get to this half-way step where it does not end with the word "killed".)

Here is my code:

<?php

$filea = "good.log";
$newf = fopen("new.txt", "w");
$file = fopen($filea, "r");

$charnum = 0;
$numlines = 0;
$temp = fopen($filea, "r");
while(!feof($temp)){
  $line = fgets($temp);
  $numlines++;
}
fclose($temp);

function caller($newf, $fileline, $charnum){
  if ($fileline[$charnum] == '-') {
    $x = $charnum;
    $stringx = "";
    for ($h = 0; $h < $x; $h++){
      $stringx = $stringx.$fileline[$h];
     }
    fwrite($newf, $stringx);
    fwrite($newf, "\n");
    echo $stringx;
   }
  else {
    $charnum = $charnum + 1;
    caller($newf, $fileline, $charnum);
  }
}
for ($k = 0; $k < $numlines; $k = $k++) {
  $fileline = fgets($file);
  $charnum = 0;
  caller($newf, $fileline, $charnum);
  }
fclose($newf);
fclose($file);
?>

Upvotes: 1

Views: 1084

Answers (3)

Alex Howansky
Alex Howansky

Reputation: 53563

If you're just trying to get the part of each line to the left of the dash, you can do it all in one line:

preg_match_all('/^([^-\n])\-/m', file_get_contents('good.log'), $matches);

After this, $matches[0] will contain a list of the terms that match (including the dash) and $matches[1] will contain the same list without the dash. For example, given:

one two - three - four
no dash on this line
five - six
seven - eight

Then, $matches[1] will be an array containing: one two, five, seven

Upvotes: 0

nl-x
nl-x

Reputation: 11832

So what your code actually does is go through the log file and count the number of lines in the while loop. (Needlessly overwriting $line every time.)

Then in your for loop, you pass in one line at a time to the function caller and indicate charnum 0.

In your function you check whether the char at charnum is a - and if so you go on to do stuff. But if it's not a -, you continue to the next char. ... Your problem is that you do this by calling caller recursively! So for each char in the line, you place a new function call on the call stack. Don't do this. Rather put a for loop in the caller function to increment charnum every time, and use break to break out of the for loop, when you finally find a -. That should fix your problem.

Upvotes: 1

Alan Birtles
Alan Birtles

Reputation: 36399

Presumably one of your log lines doesn't contain "-" so your function recurses infinitely.

Removing the recursion and fixing the bug gives:

function caller($newf, $fileline, $charnum){
  $len = strlen($fileline);
  for ( $i = $charnum; $i < $len; $i++ )
  {
    if ($fileline[$i] == '-') {
      $x = $i;
      $stringx = "";
      for ($h = 0; $h < $x; $h++){
        $stringx = $stringx.$fileline[$h];
       }
      fwrite($newf, $stringx);
      fwrite($newf, "\n");
      echo $stringx;
      return;
     }
  }
}

A simpler way would be to use the built in PHP functions strpos and substr:

function caller($newf, $fileline){
  $pos = strpos($fileline, "-");
  if ( $pos !== FALSE )
  {
    $stringx = substr( $fileline, 0, $pos );
    fwrite($newf, $stringx);
    fwrite($newf, "\n");
    echo $stringx;
  }
}

On a side note the initial loop to count the lines seems unnecessary? You could just do:

while(!feof($file)){
  $fileline = fgets($file);
  $charnum = 0;
  caller($newf, $fileline, $charnum);
  }

Upvotes: 1

Related Questions