8 Replies - 3801 Views - Last Post: 28 February 2016 - 04:14 AM Rate Topic: -----

#1 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,104
  • Joined: 06-July 13

PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:24 AM

Getting these every so often in my error log. No idea what causes them.

Quote

[18-Feb-2016 21:00:06 Europe/London] PHP Warning: Error while sending STMT_CLOSE packet. PID=14168 in Unknown on line 0
[20-Feb-2016 19:33:46 Europe/London] PHP Warning: Error while sending STMT_CLOSE packet. PID=29247 in Unknown on line 0


Any idea what I can do to try and debug this problem (if anything at all)?

Is This A Good Question/Topic? 0
  • +

Replies To: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

#2 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 4184
  • View blog
  • Posts: 13,226
  • Joined: 08-June 10

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:27 AM

looks like a database issue to me.
Was This Post Helpful? 0
  • +
  • -

#3 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,104
  • Joined: 06-July 13

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:30 AM

By "database" do you mean actually on the database server, or between PDO and the database?

This post has been edited by chris98: 23 February 2016 - 03:31 AM

Was This Post Helpful? 0
  • +
  • -

#4 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 4184
  • View blog
  • Posts: 13,226
  • Joined: 08-June 10

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:34 AM

now that you mention PDO Iíd look there first. whatís your current PDO error setting?

googling around a bit itís more likely to be a problem with the used driver (e.g. mysqlnd)
Was This Post Helpful? 0
  • +
  • -

#5 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,104
  • Joined: 06-July 13

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:35 AM

<?php
class database extends PDO
{
	public function __construct()
	{
		$opt = array(
			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
			PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
			PDO::ATTR_EMULATE_PREPARES => false
		);

		try
		{
			parent::__construct("mysql:host=*;dbname=*;charset=utf8", '*', '*', $opt);
		}
		catch (PDOException $e)
		{
			$this->error($e->getMessage());
		}
	}

	public function select($table, $fields = '*', $parameters = array(), $where = '', $order_by = '')
	{
		$sql = "SELECT ".$fields." FROM ".$table.((!empty($where)) ? " WHERE ".$where : '').((!empty($order_by)) ? " ORDER BY ".$order_by : '');
		return $this->run($sql, $parameters, 'select');
	}

	public function insert($table, $fields)
	{
		$parameters = array();
		$sql = "INSERT INTO ".$table." (`".implode("`, `", array_keys($fields))."`) VALUES (:".implode(", :", array_keys($fields)).")";
		foreach($fields as $column => $value)
			$parameters[':'.$column] = $value;

		return $this->run($sql, $parameters, 'insert');
	}

	public function update($table, $fields, $where = '', $parameters = array())
	{
		$i = 0;
		$sql = "UPDATE ".$table." SET ";
		foreach ($fields as $column => $value)
		{
			$sql .= (($i > 0) ? ', ' : '').'`'.$column."`=:".$column;
			$parameters[':'.$column] = $value;
			$i++;
		}

		$sql .= (!empty($where) ? ' WHERE '.$where : '');
		return $this->run($sql, $parameters, 'update');
	}

	public function delete($table, $where, $parameters = array())
	{
		$sql = "DELETE FROM ".$table." WHERE ".$where;
		return $this->run($sql, $parameters, 'delete');
	}

	public function run($sql, $parameters = array(), $type = '')
	{
		global $panther_config;
		$this->sql = trim($sql);

		try
		{
			$ps = $this->prepare($this->sql);
			if ($ps->execute($parameters) !== false)
			{
				if (in_array($type, array('update', 'delete', 'insert')))
					return $ps->rowCount();
				else
				{
					$ps->setFetchMode(PDO::FETCH_ASSOC);
					return $ps;
				}
			}
			else
				$this->error('Unable to execute query', $this->sql, $parameters);
		}
		catch (PDOException $e)
		{
			$this->error($e->getMessage(), $this->sql, $parameters);	
		}
	}
	
	public function start_transaction()
	{
		try
		{
			$this->beginTransaction();
		}
		catch(PDOException $e)
		{
			$this->error($e->getMessage());
		}
	}
	
	public function end_transaction()
	{
		try
		{
			$this->commit();
		}
		catch(PDOException $e)
		{
			$this->error($e->getMessage());
		}
	}

	private function error($error, $sql = '', $parameters = array())
	{
		global $panther_config, $panther_user;
		ob_end_clean();
		ob_start();

		var_dump($parameters);
		$var_dump = trim(ob_get_contents());
		ob_end_clean();
		ob_start();

		if ($panther_user['is_admin'] || substr(PHP_SAPI, 0, 3) == 'cli')
			$error_data = 'Error: '.$error.'<br /><br />Failed SQL: '.panther_htmlspecialchars($sql).'<br /><br />'.'Parameters: '.$var_dump;
		else
			$error_data = 'More information is available in the server error log.';

		$tpl_main = file_get_contents('templates/db_error.tpl');
		$search = array(
			'{server_admin}' => panther_htmlspecialchars($_SERVER['SERVER_ADMIN']),
			'{error_data}' => $error_data,
		);

		$tpl_main = str_replace(array_keys($search), array_values($search), $tpl_main);
		echo $tpl_main;
		ob_flush();
		exit;
	}
}


Was This Post Helpful? 0
  • +
  • -

#6 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 4184
  • View blog
  • Posts: 13,226
  • Joined: 08-June 10

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 03:46 AM

note: your error handling is not that ideal. the class violates the SRP (Single Responsibility Principle) because it connects to the DB, queries the DB, does DB error handling and output rendering. from the setup the only thing it should do is connecting to the DB. all other stuff (esp. the error output) should be the responsibility of something else.
Was This Post Helpful? 0
  • +
  • -

#7 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,104
  • Joined: 06-July 13

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 04:16 AM

I myself was surprised when I looked at the code how many global variables were used, and how badly the error reporting was done. In fact I moved the MVC to avoid that problem. I was also surprised that I didn't use Twig for it. Here is a version which I've just updated now and tested. Is this any better?

<?php
class database extends PDO
{
	public function __construct($registry)
	{
		$this->registry = $registry;
		$opt = array(
			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
			PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'",
			PDO::ATTR_EMULATE_PREPARES => false
		);

		try
		{
			parent::__construct("mysql:host=*;dbname=*;charset=utf8", '*', '*', $opt);
		}
		catch (PDOException $e)
		{
			$db_error = new db_error($this->registry);
			$db_error->handle($e->getMessage());
		}
	}

	public function select($table, $fields = '*', $parameters = array(), $where = '', $order_by = '')
	{
		$sql = "SELECT ".$fields." FROM ".$table.((!empty($where)) ? " WHERE ".$where : '').((!empty($order_by)) ? " ORDER BY ".$order_by : '');
		return $this->run($sql, $parameters, 'select');
	}

	public function insert($table, $fields)
	{
		$parameters = array();
		$sql = "INSERT INTO ".$table." (`".implode("`, `", array_keys($fields))."`) VALUES (:".implode(", :", array_keys($fields)).")";
		foreach($fields as $column => $value)
			$parameters[':'.$column] = $value;

		return $this->run($sql, $parameters, 'insert');
	}

	public function update($table, $fields, $where = '', $parameters = array())
	{
		$i = 0;
		$sql = "UPDATE ".$table." SET ";
		foreach ($fields as $column => $value)
		{
			$sql .= (($i > 0) ? ', ' : '').'`'.$column."`=:".$column;
			$parameters[':'.$column] = $value;
			$i++;
		}

		$sql .= (!empty($where) ? ' WHERE '.$where : '');
		return $this->run($sql, $parameters, 'update');
	}

	public function delete($table, $where, $parameters = array())
	{
		$sql = "DELETE FROM ".$table." WHERE ".$where;
		return $this->run($sql, $parameters, 'delete');
	}

	public function run($sql, $parameters = array(), $type = '')
	{
		$this->sql = trim($sql);

		try
		{
			$ps = $this->prepare($this->sql);
			if ($ps->execute($parameters) !== false)
			{
				if (in_array($type, array('update', 'delete', 'insert')))
					return $ps->rowCount();
				else
				{
					$ps->setFetchMode(PDO::FETCH_ASSOC);
					return $ps;
				}
			}
			else
				db_error::handle('Unable to execute query', $this->sql, $parameters);
		}
		catch (PDOException $e)
		{
			$db_error = new db_error($this->registry);
			$db_error->handle($e->getMessage(), $this->sql, $parameters);	
		}
	}
	
	public function start_transaction()
	{
		try
		{
			$this->beginTransaction();
		}
		catch(PDOException $e)
		{
			$db_error = new db_error($this->registry);
			$db_error->handle($e->getMessage());
		}
	}

	public function end_transaction()
	{
		try
		{
			$this->commit();
		}
		catch(PDOException $e)
		{
			$db_error = new db_error($this->registry);
			$db_error->handle($e->getMessage());
		}
	}
}



<?php
class db_error
{
	public function __construct($registry)
	{
		$this->registry = $registry;
		$this->user = $registry->user;
		$this->template = $registry->template;
	}

	public function handle($error, $sql = '', $parameters = array())
	{
		ob_end_clean();
		ob_start();

		var_dump($parameters);
		$parameters = trim(ob_get_contents());
		ob_end_clean();
		ob_start();

		$this->template->data = array(
			'error' => $error,
			'sql' => $sql,
			'parameters' => $parameters,
			'is_cli' => (substr(PHP_SAPI, 0, 3) == 'cli' ? true : false),
			'panther_user' => $this->user,
			'SERVER' => $_SERVER,
		);

		$this->template->render('db_error', false);
		exit;
	}
}


There are only two things I don't like about this approach - the first, is having to do this:

		catch(PDOException $e)
		{
			$db_error = new db_error($this->registry);
			$db_error->handle($e->getMessage());
		}


Originally I made the function static and did this:

		catch(PDOException $e)
		{
			db_error::handle($e->getMessage());
		}


But I got a Fatal error: Using $this when not in object context. - I then tried self::user instead but I think it's because of the construct__ function. Any idea how I can fix this?
Was This Post Helpful? 0
  • +
  • -

#8 Dormilich  Icon User is online

  • 痛覚残留
  • member icon

Reputation: 4184
  • View blog
  • Posts: 13,226
  • Joined: 08-June 10

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 23 February 2016 - 04:52 AM

Quote

Is this any better?

not really. you should have a class that does the connection and does the connection only. then you can create that object from your config and pass it to the class that does all the querying (have a look at DBAL for example). and neither of those classes should catch the exceptions either. dealing with database errors should be left to the business logic. and from there you can decide whether to use the content view or the error view.

Quote

Any idea how I can fix this?

change the system. you have these problems because you intertwine your classes too much.
Was This Post Helpful? 0
  • +
  • -

#9 chris98  Icon User is offline

  • D.I.C Lover

Reputation: 40
  • View blog
  • Posts: 1,104
  • Joined: 06-July 13

Re: PHP Warning: Error while sending STMT_CLOSE packet. PID=X in ...

Posted 28 February 2016 - 04:14 AM

I'm going to continue looking into this, I think I will find it fairly difficult to solve with the current setup. Back to the original question though, I've received another error in my error log:

Quote

[28-Feb-2016 05:27:58 Europe/London] PHP Warning: Error while sending STMT_CLOSE packet. PID=26800 in Unknown on line 0


Is there anything I can do to trace or see what could be causing this?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1