Code: Select all
Fatal error: Allowed memory size of 68157440 bytes exhausted (tried to allocate 11851666 bytes) in /home/xxx/xxx/xxx/resources/classes/database.php on line 136
Code: Select all
$db->query("SELECT b FROM users");
The insert statement of the log class fails to execute, therefore a loop occurs as the database class trys to log this error, causing a build up of memory usage.
Any ideas on what is causing it?
Database Class:
Code: Select all
<?
/**
* News Muncher Database Class
*
* The Database class is meant to simplify the task of accessing
* information from the website's database.
*
* Written by: Ben Web Developer.com
* Last Updated: 25 October 2010
* Version: 0.1.0
*/
class Database {
/**
* The pdo database object
*
* @access private
* @var object
*/
private $dbh;
/**
* The mysqli prepared statement database object
*
* @access private
* @var object
*/
private $stmt;
/**
* Whether to show SQL/DB errors
*
* @since 0.1.0
* @var bool
*/
var $show_errors = false;
/**
* The start time of the query
*
* @since 0.1.0
* @var string
*/
var $query_start_time;
/**
* Time taken to execute the query
*
* @since 0.1.0
* @var string
*/
var $query_time;
/**
* Total time taken to execute all queries
*
* @since 0.1.0
* @var string
*/
var $total_query_time;
/**
* Amount of queries made
*
* @since 0.1.0
* @var int
*/
var $num_queries = 0;
/**
* Amount of queries that contained errors
*
* @since 0.1.0
* @var int
*/
var $num_error_queries = 0;
/**
* Results of the last query
*
* @since 0.1.0
* @var array
*/
var $last_result = array();
/**
* Class constructor
*
* @since 0.1.0
* @var bool
*/
public function __construct() {
try {
// Connect to database
$this->dbh = new PDO("mysql:host=".SERVER.";dbname=".NAME.";", USER, PASS, array( PDO::ATTR_PERSISTENT => true ));
// Set the PDO error mode to exception
$this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
// Show errors if enabled
if($this->show_errors) {
echo $e->getMessage();
echo $e->getLine();
}
return false;
}
}
/**
* Query the database
*
* @access public
* @since 0.1.0
* @var bool
*/
public function query($sql, $params = array()) {
global $log, $page_handler;
// Try and execute the query
try {
// Start query execution time
$this->query_start_time = microtime(true);
// Prepare the sql statement
$this->stmt = $this->dbh->prepare($sql);
// Bind the parameters
if( count($params) > 0 )
$this->stmt = $this->bind_params($this->stmt, $params);
// Execute the statment
$this->stmt->execute();
// Debug
echo size_format(memory_get_usage(), 4).' - '.$sql.' '.$this->stmt->columnCount().'<br />';
// Fetch Results
/**
* Using the column count of the statement we can determine if the sql statement was a update, insert, delete or select etc.
* Therefore we can see if we need to return a result set or not.
*/
if( $this->stmt->columnCount() > 0 )
$this->fetch_all();
else
$this->last_result = array();
// Calculate query time and add it onto the total query time.
$this->query_time = microtime(true) - $this->query_start_time;
$this->total_query_time = $this->total_query_time + $this->query_time;
// Increase the number of queries
$this->num_queries++;
// Return true upon success
return true;
}
catch (PDOException $e) {
/**
* Increase the number of error queries and stop the query time.
*/
$this->num_error_queries++;
$this->query_start_time = 0;
/**
* Log and show the error if enabled
* The exception handler will return a trace of the error, we can use this to determine where the error occured.
* We need to use the template file and not the class file to determine where the error is, hence why we return
* the 2nd row in our array.
*/
$log->add('database', $page_handler->url, $e->getTrace());
if( $this->show_errors ) {
echo '<pre><h4>Database Error</h4>';
echo '<strong>SQL Statement:</strong> '.$e->getMessage().'<br />';
echo '<br /><strong>Error Trace</strong><br /><br />';
foreach ($e->getTrace() as $key => $value) {
echo '<strong>File:</strong> '.$value['file'].'<br />';
echo '<strong>Line Number:</strong> '.$value['line'].'<br /><br />';
}
echo '</pre>';
}
// Return false upon failure
return false;
}
}
/**
* Dynamically bind parameters
*
* @access private
* @since 0.1.0
* @var object
*/
private function bind_params($stmt, $params) {
try {
foreach($params as $key => &$value)
{
$stmt->bindParam($key, $value);
}
return $stmt;
}
catch (PDOException $e) {
// Show errors if enabled
if($this->show_errors)
echo $e->getMessage();
echo $e->getLine();
//Log errors
return false;
}
}
/**
* Get insert id from last query
*
* @access public
* @since 0.1.0
* @var int
*/
public function getLastInsertId() {
return $this->dbh->lastInsertId( );
}
/**
* Fetch all of the records returned from the query
* and set the last_result variable.
*
* @since 0.1.0
* @var array
*/
private function fetch_all() {
$this->last_result = $this->stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Get the number of rows returned from the query
* Applies to select queries.
*
* @since 0.1.0
* @var string
*/
public function get_num_rows() {
return count($this->last_result);
}
/**
* Get number of affected rows from last query
* Applies to update, insert and delete queries
*
* @access public
* @since 0.1.0
* @var int
*/
public function get_affected_rows() {
return $this->stmt->rowCount();
}
}
Code: Select all
<?
/**
* News Muncher Log Class
*
* The Log class is meant to simplify the task of logging
* any errors the website generates.
*
* Written by: Ben Web Developer.com
* Last Updated: 19 December 2010
* Version: 0.1.0
*/
class Log {
public function add($type, $url, $info) {
global $db, $user_management;
$db->query('INSERT INTO log (type, url, information, timestamp, username, ip, read) VALUES (:type, :url, :information, :timestamp, :username, :ip, :read)', array(':type' => $type, ':url' => $url, ':information' => serialize($info), ':timestamp' => time(), ':username' => $user_management->username, ':ip' => $_SERVER['REMOTE_ADDR'], ':read' => '0'));
return true;
}
public function show() {
global $db;
$db->query('SELECT type, url, information, timestamp, read FROM log');
return $db->last_result;
}
}