在foreach循环中退出的PHP脚本没有错误,由echo long字符串解决

I'm currently stuck on a somehow weird error in a PHP-Script that is driving me nuts for two days straight now. Before you ask, I already did some research on the topic an found a few Threads, but none of the suggested answer worked in any way :( Therefore I wanted to give a detailed description of what is happening (or failing :D) and how it can be worked around hoping anyone of you will have some great idea :)

Situation: I'm setting up a Webpage generated by PHP from MYSQL-Data. The targeted Server is running PHP 5.3.3, my local XAMPP-Installation is on PHP 5.3.8. Now I see some strange behavior fetching data from the Database. The failing code looks basically like this:

$results = array();
foreach($a as $b):
  $results[] = get_MYSQL_Data($b);
endforeach;

Now everytime I try to run the code on my local installation, the Script simply stopps executing somewhere inside the loop after 20-25 seconds of loading. All content that is generated after the Loop is simply not output. All error-reporting-options are set to max and not even the Apache-, PHP- or MYSQL-Errorlog show anything. The loop itself is collecting about 40 MYSQL-Records (not that much IMHO). The funny part about it is, that the same script running on the target webserver works like a charm and loads the whole page within 1-2 seconds.

Approaches As the script is working on the webserver, I compared the output of phpinfo() on XAMPP and the Webserver and checked each and every value that somewhat had to do with "buffer", "timeout", "max_size" and so on, just to find out they're equal. I also adjusted the values in the local php.ini to match the webservers configuration. None of this had any effect at all. As mentioned, I also tried possible solutions from several other posts related, just like setting max_execution_time up and so on.

Workaround As I thought this might be a buffer/memory or whatsoever problem, I jokingly tried overloading the buffer as some people do when trying to display a PHP-Progress-Bar. Changing the loop to

$results = array();
foreach($a as $b):
  $results[] = get_MYSQL_Data($b);
  echo str_repeat(' ', 550);
endforeach;

where 550 is the lowest working number of signs echoed ( try and error method :D) suddenly makes the script work. Basically echoing anything having more that 549 characters at the end of the loop word (as I tried also printing out the $results-Array). This workaround might be fine for developing but is no option for production, so I really need (and desire :)) to fix that.

As I couldn't find any other setting or else to change neither in the Apache nor PHP nor MYSQL (although I think it's not related to MYSQL) that I haven't checked and tried, I really hope some of you will have a flash of inspiration to help me out :)

Sincere Thanks in advance for anyone helping and best regards

Alex

-------------------- Update --------------------

Okay, so here we go with full information :) All the PHP-Constants you find are representing MYSQL-Column-Names.

This is the function holding the foreach loop. The passed array $pruefungen is a simple one-dimensional array which is to be expanded and from whom the "PRUEFUNG_ID" for the MYSQL-Condition are taken:

function stgGetSemArray($pruefungen) {
  foreach ($pruefungen as $key => $pruefung):
    /* MYSQL-Parameters are stored in Arrays */
    $selects = array(TAB_PERSON_DETAILS_ID);
    $tables = array(TAB_PERSON, TAB_PRUEFUNG);
    $conditions = array(TAB_PRUEFUNG . '.' . TAB_PRUEFUNG . TAB_DETAILS_ID => $pruefung[TAB_PRUEFUNG . TAB_DETAILS_ID]);
    /* MYSQL-Query is conducted */
    $personIDs = db_multipleColumns($selects, $tables, $conditions);
    /* new Data is stored in $pruefungen */
    $pruefungen[$key][TAB_PERSON . TAB_DETAILS_ID] = $personIDs[0];

    /* MYSQL-Parameters are stored in Arrays */
    $selects = getListViewColumns(TAB_PERSON);
    $tables = array_keys($selects);
    $conditions = array(TAB_PERSON . '.' . TAB_PERSON . TAB_DETAILS_ID => $personIDs[0]);
    /* MYSQL-Query is conducted */
    $personNameData = db_multipleColumns($selects, $tables, $conditions);
    /* new Data is stored in $pruefungen (translateAndFOrmat is just some basic texthandling */
    $pruefungen[$key][TAB_PERSON] = translateAndFormatItem(TAB_PERSON,     $personNameData[0], OUTPUT_FORMAT_HEADDING);

    /* yeah, you know..... */
    echo str_repeat(' ', 550);
  endforeach;

  return $pruefungen;
}

The MYSQL-Tables to get, the tables to take them from and the conditions for MYSQL are stored in Arrays and handled by the function db_multipleColumns(), which look like the following:

function db_multipleColumns($select, $table, $condition = array()) {
  global $con; //the MYSQLi-Connection

  /* Query-Columns */
  $query = 'SELECT ' . implode(', ', $select);

  /* Query-Tables, getDirectRelation returns a String like "pruefung LEFT JOIN dozent ON pruefung.dozentID=dozent.dozentID" */
  $query.= ' FROM '.getDirectRelation($table);

  /* Query-Conditions (only if passed) */
  $conditions = array();
  foreach ($condition as $condColumn => $condValue):
    $conditions[] = $condColumn . ' IN (' . implode(', ', $condValue) . ')';
  endforeach;
  if (!doCheckVarEmpty($conditions)):
    $query .= ' WHERE ' . implode(' AND ', $conditions);
  endif;

  /* submit Query */
  $data = $con->query($query) or die($con->error);

  /* fetch data from Query */
  $resultMatrix = array();
  while ($row = $data->fetch_assoc()):
    $resultMatrix[] = $row;
  endwhile;

  /* clear MYSQL-Memory */
  $data->free();

  return $resultMatrix;
}

The MYSQL-Query generated by the functions looks like:

    SELECT person.person_ID, person.vorname, person.nachname, titel.name FROM person LEFT JOIN titel ON person.titel_ID=titel.titel_ID WHERE person.person_ID=1

The records returned by the first five loop executions are:

    person_ID | vorname     | nachname  | name
    1         | Gerd        | Bacher    | Prof. Dr. rer. nat.
    2         | Franz-Josef | Tegude    | Prof. Dr. rer. nat.
    3         | Roland      | Schmechel | Prof. Dr. rer. nat.
    4         | Frank Einar | Kruis     | Prof. Dr.-Ing.
    5         | Wolfgang    | Mertin    | Dr.-Ing.

As mentioned, the loop runs about 30-40 iterations.

Hope this will get us further somehow :)

if $a has a valid array of valid data that $b can become to run get_MYSQL_Data($b) ... then have you checked to see if get_MYSQL_Data($b) is hanging? I see no source code for get_MYSQL_Data($b) and thus would have to assume it's invalid data being sent to it or it's hanging for some other reason.

Example data (source code, not examples) for $a and function get_MYSQL_Data would be quite useful. :)