在测试使用我的数据库实用程序类的应用程序时,我遇到了意外的致命错误(请参见下面的代码)。这是执行的测试的简要记录:
结果:
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]The DELETE statement conflicted with the REFERENCE constraint "FK_Orders_Products". The conflict occurred in database "AppTEST", table "dbo.Orders", column 'productID'.' in C:\xampp\htdocs\App\classes\utility\DB.php:140 Stack trace: ...
$stmt->execute();
,位于query()
方法的下面的代码。这是我的数据库实用程序类中有关此问题的相关部分:
namespace classes\utility;
use \PDO,
\Exception,
\PDOException;
class DB
{
private $_pdo, # stores PDO object when it's instantiated
$_error, # stores whether query failed or not
$_results, # stores dataset returned by query
$_count = 0; # stores number of data rows returned
/*connect to database*/
private function __construct()
{
try
{
$connection = new \PDO('sqlsrv:Server=' . DB_HOST . ';Database=' . DB_NAME);
$connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); //to capture error messages returned by db
$this->setPdo($connection);
}
catch(\PDOException $e)
{
exit((DEBUGMODE) ? $e->getMessage() : 'There was a problem connecting to the database.');
}
}
# generic query method - uses named placeholders for parameter binding
private function query($sql, $parameters = [])
{
try
{
$this->setError(false);
$stmt = $this->getPdo()->prepare($sql); //assign to a variable with a short name
if ($stmt):
if (count($parameters)):
foreach($parameters as $name => $parameter):
$stmt->bindValue(':'.$name, $parameter);
endforeach;
endif;
$stmt->execute();
$this->setCount($stmt->rowCount());
if ($stmt->rowCount() == -1): //conditionally do the following if SQL stmt was a SELECT
$this->setResults($stmt->fetchAll(\PDO::FETCH_OBJ));
$this->setCount($stmt->rowCount()); //overwrite count attribute with number of rows returned by SELECT stmt
endif;
endif;
return $this;
}
catch (\PDOException $e)
{
$this->setError(true);
throw $e;
}
}
// setter and getter methods for private variables not shown
}
编辑:
这是调用query()
方法的代码。此方法也是DB
类的一部分。
public function runQuery($operation, $sql, $parameters)
{
try
{
$this->query($sql, $parameters); //call query method all $operation types (read, write)
if ($operation == 'read'):
if ($this->getCount()):
if ($this->getCount() > 1): //for "read all"
$data = $this->getResults();
else: //for "read one"
$data = $this->getFirstResult();
endif;
$data = Arr::objectToArray($data);
return $data;
else:
throw new \Exception("No data to display."); //throw an exception if query runs fine but returns zero rows
endif;
endif;
}
catch (\PDOException $e)
{
throw (DEBUGMODE) ? $e : new \Exception("A database error occurred. The $operation operation failed.");
}
}
答案 0 :(得分:0)
该问题原来是在调用方法中缺少反斜杠。我在所有对DB类中的全局类的引用中都加了反斜杠,但在其他具有catch块的命名空间中的其他类中则没有反斜杠。
实际上有两种方法可以解决此问题。
一种方法是将catch (Exception $e)
更改为catch (\Exception $e)
。
或者,在整个代码中都按原样保留catch (Exception $e)
,并在命名空间声明之后和类定义起作用之前添加use \Exception;
。