我们使用Doctrine,一个PHP ORM。我创建了一个这样的查询:
$q = Doctrine_Query::create()->select('id')->from('MyTable');
然后在函数中,我添加了各种where子句和适当的东西,像这样
$q->where('normalisedname = ? OR name = ?', array($string, $originalString));
稍后,在execute()-ing该查询对象之前,我想打印出原始SQL以检查它,并这样做:
$q->getSQLQuery();
但是,这只打印准备好的语句,而不是完整的查询。我想看看它正在发送什么到MySQL,但相反,它正在打印一个准备好的语句,包括?是否有一些方法可以看到'full'查询?
修改了@dsamblas函数,当参数是日期字符串(如'2019-01-01')时工作,并且当有使用IN传递的数组时工作
$qb->expr()->in('ps.code', ':activeCodes'),
. 所以做dsamblas写的所有事情,但是用这个替换startQuery,或者看看区别,然后添加我的代码。(以防他修改了他的功能,而我的版本没有修改)。
public function startQuery($sql, array $params = null, array $types = null)
{
if($this->isLoggable($sql)){
if(!empty($params)){
foreach ($params as $key=>$param) {
try {
$type=Type::getType($types[$key]);
$value=$type->convertToDatabaseValue($param,$this->dbPlatform);
} catch (Exception $e) {
if (is_array($param)) {
// connect arrays like ("A", "R", "C") for SQL IN
$value = '"' . implode('","', $param) . '"';
} else {
$value = $param; // case when there are date strings
}
}
$sql = join(var_export($value, true), explode('?', $sql, 2));
}
}
echo $sql . " ;".PHP_EOL;
}
}
没有测试太多。
$sql = $query->getSQL();
$obj->mapDQLParametersNamesToSQL($query->getDQL(), $sql);
echo $sql;//to see parameters names in sql
$obj->mapDQLParametersValuesToSQL($query->getParameters(), $sql);
echo $sql;//to see parameters values in sql
public function mapDQLParametersNamesToSQL($dql, &$sql)
{
$matches = [];
$parameterNamePattern = '/:\w+/';
/** Found parameter names in DQL */
preg_match_all($parameterNamePattern, $dql, $matches);
if (empty($matches[0])) {
return;
}
$needle = '?';
foreach ($matches[0] as $match) {
$strPos = strpos($sql, $needle);
if ($strPos !== false) {
/** Paste parameter names in SQL */
$sql = substr_replace($sql, $match, $strPos, strlen($needle));
}
}
}
public function mapDQLParametersValuesToSQL($parameters, &$sql)
{
$matches = [];
$parameterNamePattern = '/:\w+/';
/** Found parameter names in SQL */
preg_match_all($parameterNamePattern, $sql, $matches);
if (empty($matches[0])) {
return;
}
foreach ($matches[0] as $parameterName) {
$strPos = strpos($sql, $parameterName);
if ($strPos !== false) {
foreach ($parameters as $parameter) {
/** @var \Doctrine\ORM\Query\Parameter $parameter */
if ($parameterName !== ':' . $parameter->getName()) {
continue;
}
$parameterValue = $parameter->getValue();
if (is_string($parameterValue)) {
$parameterValue = "'$parameterValue'";
}
if (is_array($parameterValue)) {
foreach ($parameterValue as $key => $value) {
if (is_string($value)) {
$parameterValue[$key] = "'$value'";
}
}
$parameterValue = implode(', ', $parameterValue);
}
/** Paste parameter values in SQL */
$sql = substr_replace($sql, $parameterValue, $strPos, strlen($parameterName));
}
}
}
}
你可以通过将sql prepared语句与绑定结合来构建一个sql字符串,就像这样:
$sql = str_replace_array('?', $query->getBindings(), $query->toSql())
str_replace_array(string $search, array $replacement, string $subject): string
PHP的str_replace_array函数将$subject中的每个$search实例依次替换为$replacement数组中的值。