Jump to content

Using unset is causing a premature end of script headers error.


Vel

Recommended Posts

Hi guys, I'm adding a filter system to out e-commerce solution and all seemed to be going well, until now. I've hit a problem that I can't find any answer to, or even an explanation as to why it is happening.

 

I am loading all my filters into an array and then transferring them into a temp array for sorting and outputting. The way I do this is grab the first one, then go through each one and check to see if any others have more have a higher number of products using the filter. If so then that becomes the one to output and I continue through until the array is exhausted, then output whatever pointer is given to me at the end.

 

That all works fine and the most commonly used filters appear at the top of the list. But to stop them from showing more than once, I then need to remove them from the temp array once they have been echo'd out. And this is when the problem occurs. When trying to unset the filter from the array the website throws a 500 Internal server error. The error logs show a premature end of script headers error. I have no idea why this is doing it. This is my code:

 

class Filters {

public $filters = array();

/* Class Constructor */
function Filters() {
	$this->load_headings();
	if(count($this->filters))
		$this->load_options();
}

/* Load Filter Headings */
function load_headings() {
	global $error;
	$query = "SELECT sfID, sfFilter FROM sectionfilters" . (isset($_GET['cat']) ? " WHERE sfSection = " . (int)$_GET['cat'] : "");
	if(!$result = mysql_query($query)) { $error->trigger(MYSQL_ERROR, "Database error whilst trying to load filter headings in filters.php. Function load_headings. Query: $query", mysql_error(), TRUE); return 'MYSQL_ERROR'; }
	$i = 0;
	while($row = mysql_fetch_assoc($result)) {
		$this->filters[$i]['heading'] = $row;
		$this->filters[$i]['num_opts'] = 0;
		$this->filters[$i++]['options'] = array();
	}
	return FALSE;
}

/* Load Filter Options */
function load_options() {
	global $error;
	$query = "SELECT pfFilter, pfFilterID FROM prodfilters WHERE pfFilterID IN";
	$start = "(";
	foreach($this->filters as $f) {
		$query .= $start . $f['heading']['sfID'];
		$start = ", ";
	}
	$query .= ")";
	if(!$result = mysql_query($query)) { $error->trigger(MYSQL_ERROR, "Database error whilst trying to load filter options in filters.php. Function load_options. Query: $query", mysql_error(), TRUE); return 'MYSQL_ERROR'; }
	while($row = mysql_fetch_assoc($result)) {
		for($i = 0; $i < count($this->filters); $i++) {
			if($this->filters[$i]['heading']['sfID'] == $row['pfFilterID']) {
				$var = $row['pfFilter'];
				if(isset($this->filters[$i]['options']["$var"])) {
					$this->filters[$i]['options']["$var"]++;
				} else {
					$this->filters[$i]['options']["$var"] = 1;
					$this->filters[$i]['num_opts']++;
				}
			}
		}
	}
}

/* Output Filters */
function output() {
	global $showfilternum;
	// First we check to see if any previous filters are stored in session. If there are we check if they are for this category, and if not then clear them. If they are we will use them.
	if(isset($_SESSION['filters'])) {
		if($_SESSION['filters']['cat'] != @$_GET['cat'])
			unset($_SESSION['filters']);
	}
	$k = 0;
	foreach($this->filters as $f) {
		if($f['num_opts']) {
			echo '<div class="filter-title">' . $f['heading']['sfFilter'] . '</div>';
			//We will only show the top 5 options, the rest get outputed in a "show more" div. They also outputed in order, with the most popular at the top. To achieve this we load them into a temporary array and then unset them once they have been outputed.
			$tmp = array();
			$i = 0;
			foreach($f['options'] as $opt => $num) {
				$tmp[$i]['opt'] = $opt;
				$tmp[$i]['num'] = $num;
			}
			$limit = ($f['num_opts'] < 5 ? $f['num_opts'] : 5);
			//Output the first 5, or up to 5 if there are less than 5 filters.
			for($i = 0; $i < $limit; $i++) {
				$out = $this->_temp_first($tmp);
				for($j = 0; $j < $f['num_opts']; $j++) {
					if($i == $j || !isset($tmp[$j]))
						continue;
					if($tmp[$j]['num'] > $tmp[$i]['num'])
						$out = $j;
				}
				echo '<input type="checkbox" name="filter[]" id="filter' . $k . '" value="' . $tmp[$out]['opt'] . '" />
				<label for="filter' . $k++ . '">' . $tmp[$out]['opt'] . (@$showfilternum ? '(' . $tmp[$out]['num'] . ')' : '') . '</label>
				<br clear="all" />';
				unset($tmp[$out]['opt']); //WORKS FINE
				unset($tmp[$out]['num']); //WORKS FINE
				unset($tmp[$out]); //THROWS 500 ERROR?!
			}
			//Output the rest in a hidden div.
			if($f['num_opts'] > 5) {
				echo '<div class="filter-more" id="filter-more-' . $f['heading']['sfID'] . '">';
				for($i = $i; $i < $f['num_opts']; $i++) {
					$out = $this->_temp_first($tmp);
					for($j = 0; $j < $f['num_opts']; $j++) {
						if($i == $j || !isset($tmp[$j]))
							continue;
						if($tmp[$j]['num'] > $tmp[$i]['num'])
							$out = $j;
					}
					echo '<input type="checkbox" name="filter[]" id="filter' . $k . '" value="' . $tmp[$out]['opt'] . '" />
					<label for="filter' . $k++ . '">' . $tmp[$out]['opt'] . (@$showfilternum ? '(' . $tmp[$out]['num'] . ')' : '') . '</label>
					<br clear="all" />';
					//unset($tmp[$out]);
				}
				echo '</div>';
			}
		}
	}
}

/* Find the first temp */
private function _temp_first($tmp, $i = 0) {
	if(isset($tmp[$i]))
		return $i;
	else
		return $this->_temp_first($tmp, ++$i);
}

}

 

Can someone please explain why simply unsetting that filter is throwing the error?

Link to comment
Share on other sites

OK, a little more information that I think totally screws my approach to this.

 

I saw that using unset($tmp[$out]['opt']) worked, so I thought I would unset that and then check if that was unset instead, so I modified _temp_first to

if(isset($tmp[$i]['opt'])) return $i; else ...

Same problem, 500 error, Premature end of script headers. So, I can't check for an unset variable in my header.

 

So next I tried to set $tmp[$out] to NULL, same problem. When checking if it exactly equals null I get internal server error, same error in the logs.

 

I then tried setting $tmp[$out]['opt'] == ""; and $tmp[$out]['num'] == -1; and then in _temp_first check for $tmp[$i]['num'] == -1. In theory this should have worked, but for some reason the first option outputted again instead of the second option (no 500 error though, making progress).

 

I just need to debug why the -1 was outputted instead of the +1 now.

Link to comment
Share on other sites

Do you have php's error_reporting set to E_ALL and either display_errors or log_errors set to ON?

 

The 500 http response means that nothing was output in response to the http request. If php's error_reporting is set to not report any php errors, php errors won't be reported and if display_errors is off, reported errors won't be displayed and if log_errors is off, reported errors won't be logged.

Link to comment
Share on other sites

Do you have php's error_reporting set to E_ALL and either display_errors or log_errors set to ON?

 

The 500 http response means that nothing was output in response to the http request. If php's error_reporting is set to not report any php errors, php errors won't be reported and if display_errors is off, reported errors won't be displayed and if log_errors is off, reported errors won't be logged.

Unfortunately our web host forces display_errors off. Not the ideal situation, I know. I've tried forcing them on using a php_ini file to no avail. We are in the process of getting a development server to solve that problem. In the mean time, I can't work on WAMP, or something like that as the website uses .htaccess files.

 

I've solved the problem of the -1 being outputted instead of the +1. I wasn't incrementing the counter when putting the filters into $tmp, so $tmp only had one field, yet the script expected multiple.

 

That still doesn't solve the initial problem, although I now have a work around. I'd like to know why it was throwing a Premature end of script headers error though, if anyone can explain?

Link to comment
Share on other sites

I can't work on WAMP

 

Why not? All you are trying to do is get the php code on one page to run so that you can debug it. In fact, you only need that problematic portion of the code to run. A .htaccess file has no bearing on the php code after the php code has been invoked.

Link to comment
Share on other sites

Also, I use .htaccess files with Wamp Server all the time.

.htaccess only work on Linux. If you try to run them on windows you just get a 500 internal server error, or at least that's the result I get ever single time I've ever tried. Or maybe that's just for URL rewite, which is what we use .htaccess for.

I can't work on WAMP

 

Why not? All you are trying to do is get the php code on one page to run so that you can debug it. In fact, you only need that problematic portion of the code to run. A .htaccess file has no bearing on the php code after the php code has been invoked.

Good point,  although it wouldn't be exactly the same as running it where it is right now, it should be similar enough.

Link to comment
Share on other sites

.htaccess only work on Linux.

 

Nope. You might be using a server module that you need to enable in the httpd.conf (or have php settings in it when php is not running as an Apache module), but .htaccess files work on windows.

 

Have you checked the Apache error log to find out what is actually causing the 500 server error?

Link to comment
Share on other sites

I guess my PCs are all magical then, because I've been running Wamp Server on my windows PCs for years, and using .htaccess files all the time.

K, if you see one of my posts, please, don't bother responding. What PFM put was helpful. You're just an ass.

Link to comment
Share on other sites

1. Calm down.

2. I never even look at who posts stuff, so no. If you don't post things that are categorically false, I won't respond in that way. If your post makes sense you get a much more helpful answer.

Link to comment
Share on other sites

1. Calm down.

2. I never even look at who posts stuff, so no. If you don't post things that are categorically false, I won't respond in that way. If your post makes sense you get a much more helpful answer.

Someone told me that htaccess doesn't work on Windows. From my own experience that seemed to be true, so I took it as that. PFM pointed out I was wrong, you just posted something sarky. And this is the second time you've done that when I've posted something incorrect. I'm still learning and I know I'll get things wrong, but that's no reason to be like that about it. You'll find people much more receptive to you if you just help them instead of insulting them.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.