Browse Source

starts_with, notice backtraces, better database error reporting and return values

feature/formhandler
Sven Slootweg 9 years ago
parent
commit
87a0cadb18
  1. 45
      base.php
  2. 2
      include.exceptions.php
  3. 5
      include.misc.php
  4. 37
      include.mysql.php

45
base.php

@ -102,6 +102,51 @@ if(!empty($cphp_config->autoloader))
spl_autoload_register('cphp_autoload_class');
}
/* https://stackoverflow.com/a/1159235/1332715 */
set_error_handler(function($errno, $errstr, $errfile, $errline, $errcontext) {
if(!(error_reporting() & $errno))
return;
switch($errno) {
case E_WARNING :
case E_USER_WARNING :
case E_STRICT :
case E_NOTICE :
case E_USER_NOTICE :
$type = 'warning';
$fatal = false;
break;
default :
$type = 'fatal error';
$fatal = true;
break;
}
$trace = array_reverse(debug_backtrace());
array_pop($trace);
if(php_sapi_name() == 'cli') {
echo 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
foreach($trace as $item)
echo ' ' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()' . "\n";
} else {
echo '<p class="error_backtrace">' . "\n";
echo ' Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
echo ' <ol>' . "\n";
foreach($trace as $item)
echo ' <li>' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()</li>' . "\n";
echo ' </ol>' . "\n";
echo '</p>' . "\n";
}
if(ini_get('log_errors')) {
$items = array();
foreach($trace as $item)
$items[] = (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()';
$message = 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ': ' . join(' | ', $items);
error_log($message);
}
if($fatal)
exit(1);
});
set_exception_handler(function($e){
/* Intentionally not using the templater here; any inner exceptions
* cause serious debugging issues. Avoiding potential issues by just

2
include.exceptions.php

@ -29,6 +29,8 @@ class PrototypeException extends BaseException {}
class ConstructorException extends BaseException {}
class MissingDataException extends BaseException {}
class DatabaseException extends BaseException {}
class DatabaseDuplicateException extends DatabaseException {}
class DatabaseConstraintException extends DatabaseException {}
class TypeException extends BaseException {}
class DeprecatedException extends BaseException {}

5
include.misc.php

@ -371,6 +371,11 @@ function generate_pagination($min, $max, $current, $around, $start, $end)
}
}
function starts_with($haystack, $needle)
{
return (substr($haystack, 0, strlen($needle)) == $needle);
}
function ends_with($haystack, $needle)
{
return (substr($haystack, -strlen($needle)) == $needle);

37
include.mysql.php

@ -25,7 +25,7 @@ class CachedPDO extends PDO
$query_hash = md5($query);
$parameter_hash = md5(serialize($parameters));
$cache_hash = $query_hash . $parameter_hash;
$return_object = new stdClass;
if($expiry != 0 && $result = mc_get($cache_hash))
@ -73,7 +73,7 @@ class CachedPDO extends PDO
if($result = $statement->fetchAll(PDO::FETCH_ASSOC))
{
if(count($result) > 0)
{
{
if($expiry != 0)
{
mc_set($cache_hash, $result, $expiry);
@ -89,16 +89,41 @@ class CachedPDO extends PDO
}
else
{
/* There were zero results. Return null instead of an object without results, to allow for statements
* of the form if($result = $database->CachedQuery()) . */
return null;
$last_id = $this->lastInsertId();
if($last_id == "0" || !starts_with(strtoupper($query), "INSERT"))
{
/* There were zero results. Return null instead of an object without results, to allow for statements
* of the form if($result = $database->CachedQuery()) . */
return null;
}
else
{
/* This was an INSERT query. Return the primary ID of the created row. */
return $last_id;
}
}
}
else
{
/* The query failed. */
$err = $statement->errorInfo();
throw new DatabaseException("The query failed: {$err[2]}", 0, null, array('query' => $query, 'parameters' => $parameters));
if($err[0] == "23000")
{
if(starts_with($err[2], "Duplicate entry")) /* There does not seem to be a better way of doing this. */
{
throw new DatabaseDuplicateException("The query failed because one of the keys was not unique: {$err[2]}", 0, null, array('query' => $query, 'parameters' => $parameters));
}
else
{
throw new DatabaseConstraintException("The query violates a database constraint: {$err[2]}", 0, null, array('query' => $query, 'parameters' => $parameters));
}
}
else
{
throw new DatabaseException("The query failed: {$err[2]}", 0, null, array('query' => $query, 'parameters' => $parameters));
}
}
}

Loading…
Cancel
Save