NYCPHP Meetup

NYPHP.org

[nycphp-talk] trouble using ob_start(), ob_end_clean() and header() combination

soazine at pop.erols.com soazine at pop.erols.com
Mon Oct 20 09:43:48 EDT 2003


I traced the problem to what I believe is when I use the included content
library script into the viewinterns.php page.  This script will repeatedly
instantiate a DateGroupHTMLGenerator class because I have to constantly
produce these HTML form element fields with different names throughout my
page.  Here is the code I use to reproduce it everytime:

<?php		
			
			$gradArray = array();
			foreach(array('graduation_month', '', 'graduation_year') as $key =>
$val) 
			 $gradArray = $gradArray + array($val => $$val);
			array_push($gradArray, 2); // ADD TEXT FIELD SIZE
			$dateGroup =& new DateGroupHTMLGenerator($gradArray, 1, 0, 1);
			echo $dateGroup->getMonthDropdown() . $dateGroup->getDayDropdown() .
$dateGroup->getYearText();
?>

This is one of the dategroup HTML content snippets throughout the library. 
There are several of them since the form is rather large and requires an
enormous amount of data including several month/day/year groupings, all
having different names (see the foreach() loop for more clarification on
naming convention, etc.).

At the end of this library script I do the following:

<? $dateGroup = null; ?>

I zero-out the object.  Upon review, however, I am convinced that somehow a
latent object or a latent buffer is still floating around.  Here is the
code to DateGroupHTMLGenerator constructor method:

        // CONSTRUCTOR
	function DateGroupHTMLGenerator($classPropertyArray, $hasMonth = 1,
$hasDay = 1, $hasYear = 1) {
		global $REQUEST_URI;

		foreach(array('month', 'day', 'year') as $key => $val) $this->{'has' .
ucfirst($val)} = ${'has' . ucfirst($val)};
		
		$this->propertyArray = $classPropertyArray;
		
		// CONVERT THE INPUT PARAMETER ARRAY INTO A 2-DIM ENUMERATIVE ARRAY TO
PRESERVE KEYS AND VALS AND HAVE ENUMERATION FOR SWITCH
		$enumKeyValArray = array();
		foreach($this->propertyArray as $key => $val) 
		 array_push($enumKeyValArray, array($key, $val));

		// GET THE VALUE OF THE LAST ELEMENT OF THE INPUT PARAMETER ARRAY WHICH
WILL BE THE TEXT FIELD LENGTH
		$textFieldLengthArray =
array_values(array_reverse($this->propertyArray)); 
		$textFieldLength = $textFieldLengthArray[0];

		$this->htmlArray = array();	
				
		$monthArray = array('01' => 'January',
				    '02' => 'February',
				    '03' => 'March',
				    '04' => 'April',
				    '05' => 'May',
				    '06' => 'June',
				    '07' => 'July',
				    '08' => 'August',
				    '09' => 'September',
				    '10' => 'October',
				    '11' => 'November',
				    '12' => 'December'
				   );


		for ($i = 0; $i < sizeof($enumKeyValArray); $i++) {		
		 $html = '';
	 	 switch ($i) {
		  case '2': // TEXT FIELD SLOT IN INPUT ARRAY PARAMETER
		   	if ($this->hasYear) {
			 if ($textFieldLength == 2) $html = '20';
		    	 $html .= '<input name="' . $enumKeyValArray[$i][0] . '" value="' .
str_replace('"', '&quot;', $enumKeyValArray[$i][1]) . '" size="' .
$textFieldLength . '" maxlength="' . ($textFieldLength + 1) . '">';
	 		}
		  	break;

		  case '3': // SIZE OF TEXT FIELD - NOTHING NEEDS TO BE DONE
			// DO NOTHING
		   	break;
		  
		  case '0': // MONTH DROPDOWN
			if ($this->hasMonth) {
			 $html = '<select name="' . $enumKeyValArray[$i][0] . '">';
	 		 foreach($monthArray as $innerKey => $innerVal) {
			  ob_start();
			   preSelect($enumKeyValArray[$i][1], $innerKey);
			   $preSelectText = ob_get_contents();
			  ob_end_clean();
	 		  $html .= '<option value="' . $innerKey  . '" ' . $preSelectText . '>'
. $innerKey . ' - ' . $innerVal . '</option>';
			 }
			 $html .= '</select>';
			}
		  	break;

		  case '1': // DAY DROPDOWN
			if ($this->hasDay) {
			 $html = '<select name="' . $enumKeyValArray[$i][0] . '">';
			 for ($j = 1; $j <= 31; $j++) {
			  $myDay = ($j < 10) ? '0' . $j : $j;
			  ob_start();
			   preSelect($enumKeyValArray[$i][1], $myDay);
			   $preSelectText = ob_get_contents();
			  ob_end_clean();			  
			  $html .= '<option value="' . $myDay . '" ' . $preSelectText . '>' .
$myDay . '</option>';
			 }
			 $html .= '</select>';
			}
			break;

		  default: // THIS WILL BE EXPANDED FOR FUTURE IMPLEMENTATION OF
DATEGROUP, FOR NOW IF ANYTHING ELSE IS FOUND DO NOTHING
		   	// DO NOTHING
			break;
		 }
		 
		 $this->htmlArray[$i] = $html;
		} 		

	}

I have certain fields surrounded by ob_start() and ob_end_clean() because
the function those commands surround does an 'echo' (required).  So to
prevent it from going to stdout that is why I have ob_start() and
ob_end_clean() around them.  However, when the user submits the form
generated by the library using this class object, it will instantiate a
saveData class object that saves everything (no headers produced mind you)
and then does a redirect header() command.  Whenever anyone does that they
get  this specific warning:

Warning: Cannot add header information - headers already sent by (output
started at /var/www/html/development/phillip/libdev/html.inc:160) in
/var/www/html/development/phillip/admin/viewinterns.php on line 659

Mind you, the saveData class in viewinterns.php does NOT instantiate
anything in html.inc, much less a DateGroupHTMLGenerator class instance,
which is exactly what this warning is pointing to (the line 160 in html.inc
is the end of the entire html.inc, classes and all).

I'm totally stumped.  If I replace "header()" with client-side redirection
it works but is EXTREMELY slow (avg download time 20 - 30 seconds per
page), so it's not an option.  I do not know what to do at this point so I
really need help.

Thanks
Phil

--------------------------------------------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .





More information about the talk mailing list