在对准备好的语句调用pdoStatement::execute()时,是否有方法执行原始SQL字符串?出于调试目的,这将非常有用。

对于php>=5.1,请查看php.net/manual/en/pdoStatement.debugdumpparams.php

检查一行功能PDO调试。

我找到的最干净的方法是E&U数据库。你只需要做一个$stmt = $pdo->prepare($query); /* ... */ echo $stmt->fullQuery;。它通过扩展pdoStatement类来工作,因此在pdo api允许的情况下也非常优雅。

/**

* Replaces any parameter placeholders in a query with the value of that

* parameter. Useful for debugging. Assumes anonymous parameters from

* $params are are in the same order as specified in $query

*

* @param string $query The sql query with parameter placeholders

* @param array $params The array of substitution parameters

* @return string The interpolated query

*/

public static function interpolateQuery($query, $params) {

$keys = array();

# build a regular expression for each parameter    foreach ($params as $key => $value) {

if (is_string($key)) {

$keys[] = '/:'.$key.'/';

} else {

$keys[] = '/[?]/';

}

}

$query = preg_replace($keys, $params, $query, 1, $count);

#trigger_error('replaced '.$count.' keys');

return $query;

}

你真是太棒了,摇滚!什么是你的贝宝地址,所以我可以给你一个捐赠,认真吗?

三年后我又问了一次。我怎么付钱给你?多年来,这个函数一手为我节省了无数小时调试复杂的准备好的语句。我真的很想报答你。

@史密斯刚刚从www.gittip.com上发了一个邀请,这是表达慷慨的最礼貌和最好的方式:)顺便说一下,再次感谢@bigwebguy!

或者使用比特币。:)

@史密斯:你可以赏金:)

该死。每次我看到这个,我都要给那个家伙50美元;-)到目前为止,大概是250美元!

为什么不直接使用strtr():更快、更简单、结果相同。江户十一〔一〕号

这个的用法是什么?

这种方法很厉害!我一直在用它;-)

我只是想顺便过来感谢一下,因为这门课太小了,太聪明了,我现在已经把它取消了。因此,通过记录应用程序在每个页面上执行的所有查询,对于消除它们的bug非常有用:d

看到这个功能,我很高兴,虽然有些事情我不明白,为什么你要检查$key是一个string,而不是$value?我错过什么了吗?我之所以这样问是因为这个输出,第二个参数不被看作字符串:string(115)"INSERT INTO tokens (token_type, token_hash, user_id) VALUES ('resetpassword', hzFs5RLMpKwTeShTjP9AkTA2jtxXls86, 1);"。

这是一个很好的开始,但如果$param本身的值包含问号("?"),则会失败。.

我假设您的意思是需要最后一个SQL查询,其中插入了参数值。我知道这对调试很有用,但这不是准备好的语句的工作方式。参数不与客户端上准备好的语句组合在一起,因此PDO不应该访问与其参数组合在一起的查询字符串。

SQL语句在您执行prepare()时发送到数据库服务器,参数在您执行()时单独发送。mysql的常规查询日志确实显示了最终的SQL,其中的值是在执行()之后插入的。下面是我的常规查询日志的摘录。我从mysql cli运行查询,而不是从pdo运行,但原理是相同的。

081016 16:51:28 2 Query       prepare s1 from 'select * from foo where i = ?'

2 Prepare     [2] select * from foo where i = ?

081016 16:51:39 2 Query       set @a =1

081016 16:51:47 2 Query       execute s1 using @a

2 Execute     [2] select * from foo where i = 1

如果设置pdo属性pdo::attr_仿真_准备,也可以获得所需的。在此模式下,pdo将参数插入到SQL查询中,并在执行()时发送整个查询。这不是真正准备好的查询。您将通过在execute()之前将变量插入SQL字符串来规避准备好的查询的好处。

@afilina回复评论:

不,执行期间文本SQL查询不与参数组合。所以PDO没有什么可以给你看的。

在内部,如果使用pdo::attr_仿真_准备,pdo会复制SQL查询,并在准备和执行之前将参数值插入其中。但是PDO不会公开这个修改过的SQL查询。

pPostatement对象具有属性$queryString,但它仅在pPostatement的构造函数中设置,并且在用参数重写查询时不会更新。

对于PDO来说,要求他们公开重写的查询是一个合理的特性请求。但即使这样,也不能提供"完整"的查询,除非您使用pdo::attr_仿真_准备。

这就是我上面展示使用mysql服务器的常规查询日志的解决方法的原因,因为在这种情况下,即使是带有参数占位符的准备好的查询也会在服务器上重写,参数值会被反写到查询字符串中。但这只在日志记录期间完成,而不是在查询执行期间。

当pdo::attr_仿真准备设置为true时,如何获取孔查询?

@yasen zhelev:如果pdo正在模拟prepare,那么它将在准备查询之前将参数值插入查询中。因此,MySQL从未看到带有参数占位符的查询版本。MySQL只记录完整的查询。

@bill:'参数没有与客户端的准备好的语句组合在一起'-等等-但是它们是在服务器端组合的吗?或者MySQL如何将值插入数据库?

但是我可以只使用完全组合的查询来调试它吗?我不在乎准备好的语句在试图找出我的查询行为不当的原因时的优势。

@阿菲莉娜,不,你不能。看上面我的解释。

哇,投反对票?请不要射杀信使。我只是在描述它是如何工作的。

我修改了该方法,将处理数组输出的语句包括在内(?).

更新:只是增加了对空值和重复的$params的检查,所以实际的$param值不会被修改。

干得好,BigWebguy,谢谢!

/**

* Replaces any parameter placeholders in a query with the value of that

* parameter. Useful for debugging. Assumes anonymous parameters from

* $params are are in the same order as specified in $query

*

* @param string $query The sql query with parameter placeholders

* @param array $params The array of substitution parameters

* @return string The interpolated query

*/

public function interpolateQuery($query, $params) {

$keys = array();

$values = $params;

# build a regular expression for each parameter    foreach ($params as $key => $value) {

if (is_string($key)) {

$keys[] = '/:'.$key.'/';

} else {

$keys[] = '/[?]/';

}

if (is_string($value))

$values[$key] ="'" . $value ."'";

if (is_array($value))

$values[$key] ="'" . implode("','", $value) ."'";

if (is_null($value))

$values[$key] = 'NULL';

}

$query = preg_replace($keys, $values, $query);

return $query;

}

我认为你必须做$values = $params;,而不是$values = array()。

另一个漏掉的小部分是弦。为了捕捉这些,把这个放在is_array支票的上方:if (is_string($value)) $values[$key] ="'" . $value ."'";。

在preg_replace中,此值仅限于一次绑定值。在$values = $params;$values_limit = []; $words_repeated = array_count_values(str_word_count($sql, 1, ':_'));之后加上这一行,如果在foreach $values_limit[$key] = (isset($words_repeated[':'.$key]) ? intval($words_repeated[':'.$key]) : 1);中加上这一行,如果在foreach $values_limit = [];中加上这一行,则在foreach $values_limit = [];中加上这一行,再次使用foreach loop$值,以preg替换为isset($values_limit[$key])。

例如循环$values。埃多克斯1〔15〕

可能有点晚了,但现在有了PDOStatement::debugDumpParams。

Dumps the informations contained by a prepared statement directly on

the output. It will provide the SQL query in use, the number of

parameters used (Params), the list of parameters, with their name,

type (paramtype) as an integer, their key name or position, and the

position in the query (if this is supported by the PDO driver,

otherwise, it will be -1).

您可以在官方的php文档中找到更多信息。

例子:

/* Execute a prepared statement by binding PHP variables */

$calories = 150;

$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories

FROM fruit

WHERE calories < :calories AND colour = :colour');

$sth->bindParam(':calories', $calories, PDO::PARAM_INT);

$sth->bindValue(':colour', $colour, PDO::PARAM_STR, 12);

$sth->execute();

$sth->debugDumpParams();

?>

注意php bug 52384:pDestatement::DebugDumpParams不发出绑定参数值。

pPostStatement具有公共属性$queryString。这应该是你想要的。

我刚刚注意到pDestatement有一个未记录的debugdumpParams()方法,您可能还需要查看它。

debugdumpparams没有文档记录php.net/manual/en/pdoStatement.debugdumpparams.php

不。$querystring不显示包含的参数值。

Mike在代码中添加了更多的内容-通过值添加单引号

/**

* Replaces any parameter placeholders in a query with the value of that

* parameter. Useful for debugging. Assumes anonymous parameters from

* $params are are in the same order as specified in $query

*

* @param string $query The sql query with parameter placeholders

* @param array $params The array of substitution parameters

* @return string The interpolated query

*/

public function interpolateQuery($query, $params) {

$keys = array();

$values = $params;

# build a regular expression for each parameter    foreach ($params as $key => $value) {

if (is_string($key)) {

$keys[] = '/:'.$key.'/';

} else {

$keys[] = '/[?]/';

}

if (is_array($value))

$values[$key] = implode(',', $value);

if (is_null($value))

$values[$key] = 'NULL';

}

// Walk the array to see if we can add single-quotes to strings

array_walk($values, create_function('&$v, $k', 'if (!is_numeric($v) && $v!="NULL") $v ="\'".$v."\'";'));

$query = preg_replace($keys, $values, $query, 1, $count);

return $query;

}

非常有用,我做了一些修改来重写pdoStatement类的bindparam函数,并验证该值是带有pdo:params值的字符串还是整数。

我们在哪里能看到?

您可以扩展pPostatement类来捕获有界变量并存储它们以供以后使用。然后可以添加两个方法,一个用于变量清理(debugbinderables),另一个用于打印带有这些变量的查询(debugquery):

class DebugPDOStatement extends \PDOStatement{

private $bound_variables=array();

protected $pdo;

protected function __construct($pdo) {

$this->pdo = $pdo;

}

public function bindValue($parameter, $value, $data_type=\PDO::PARAM_STR){

$this->bound_variables[$parameter] = (object) array('type'=>$data_type, 'value'=>$value);

return parent::bindValue($parameter, $value, $data_type);

}

public function bindParam($parameter, &$variable, $data_type=\PDO::PARAM_STR, $length=NULL , $driver_options=NULL){

$this->bound_variables[$parameter] = (object) array('type'=>$data_type, 'value'=>&$variable);

return parent::bindParam($parameter, $variable, $data_type, $length, $driver_options);

}

public function debugBindedVariables(){

$vars=array();

foreach($this->bound_variables as $key=>$val){

$vars[$key] = $val->value;

if($vars[$key]===NULL)

continue;

switch($val->type){

case \PDO::PARAM_STR: $type = 'string'; break;

case \PDO::PARAM_BOOL: $type = 'boolean'; break;

case \PDO::PARAM_INT: $type = 'integer'; break;

case \PDO::PARAM_NULL: $type = 'null'; break;

default: $type = FALSE;

}

if($type !== FALSE)

settype($vars[$key], $type);

}

if(is_numeric(key($vars)))

ksort($vars);

return $vars;

}

public function debugQuery(){

$queryString = $this->queryString;

$vars=$this->debugBindedVariables();

$params_are_numeric=is_numeric(key($vars));

foreach($vars as $key=>&$var){

switch(gettype($var)){

case 'string': $var ="'{$var}'"; break;

case 'integer': $var ="{$var}"; break;

case 'boolean': $var = $var ? 'TRUE' : 'FALSE'; break;

case 'NULL': $var = 'NULL';

default:

}

}

if($params_are_numeric){

$queryString = preg_replace_callback( '/\?/', function($match) use( &$vars) { return array_shift($vars); }, $queryString);

}else{

$queryString = strtr($queryString, $vars);

}

echo $queryString.PHP_EOL;

}

}

class DebugPDO extends \PDO{

public function __construct($dsn, $username="", $password="", $driver_options=array()) {

$driver_options[\PDO::ATTR_STATEMENT_CLASS] = array('DebugPDOStatement', array($this));

$driver_options[\PDO::ATTR_PERSISTENT] = FALSE;

parent::__construct($dsn,$username,$password, $driver_options);

}

}

然后您可以使用这个继承的类来调试目的。

$dbh = new DebugPDO('mysql:host=localhost;dbname=test;','user','pass');

$var='user_test';

$sql=$dbh->prepare("SELECT user FROM users WHERE user = :test");

$sql->bindValue(':test', $var, PDO::PARAM_STR);

$sql->execute();

$sql->debugQuery();

print_r($sql->debugBindedVariables());

导致

SELECT user FROM users WHERE user = 'user_test'

Array (

[:test] => user_test

)

为了我自己的需要,我花了很多时间研究这种情况。这个和其他几个这样的线程帮助了我很多,所以我想分享我的想法。

虽然在故障排除时可以访问插入的查询字符串是一项重要的好处,但我们希望能够只维护某些查询的日志(因此,为此目的使用数据库日志并不理想)。我们还希望能够在任何给定时间使用日志重新创建表的条件,因此,我们需要确保正确地转义了内插字符串。最后,我们希望将此功能扩展到整个代码库,必须尽可能少地重新编写代码(截止日期、市场营销等;您知道它是怎样的)。

我的解决方案是扩展默认pDestatement对象的功能以缓存参数化值(或引用),在执行语句时,使用pdo对象的功能在参数被注入回查询字符串时正确地转义这些参数。然后我们可以连接到语句对象的execute方法,并记录当时执行的实际查询(或者至少尽可能忠实于复制)。

如我所说,我们不想修改整个代码库来添加这个功能,所以我们覆盖pdoStatement对象的默认bindParam()和bindValue()方法,缓存绑定数据,然后调用parent::bindParam()或parent::bindValue()。这允许我们现有的代码库继续正常工作。

最后,当调用execute()方法时,我们执行插值,并将结果字符串作为新属性E_PDOStatement->fullQuery提供。这可以输出以查看查询,或者,例如,写入日志文件。

该扩展以及安装和配置说明在GitHub上提供:

https://github.com/noaheck/e pdoStatement(网址:http://github.com/noaheck/e pdoStatement)

免责声明:显然,正如我提到的,我编写了这个扩展。因为它是在许多线程的帮助下开发的,所以我想在这里发布我的解决方案,以防其他人遇到这些线程,就像我所做的那样。

谢谢分享。不赞成票,因为答案太长,代码太少

解决方法是自动在查询中输入错误并打印错误消息:

//Connection to the database

$co = new PDO('mysql:dbname=myDB;host=localhost','root','');

//We allow to print the errors whenever there is one

$co->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//We create our prepared statement

$stmt = $co->prepare("ELECT * FROM Person WHERE age=:age"); //I removed the 'S' of 'SELECT'

$stmt->bindValue(':age','18',PDO::PARAM_STR);

try {

$stmt->execute();

} catch (PDOException $e) {

echo $e->getMessage();

}

标准输出:

SQLSTATE[42000]: Syntax error or access violation: [...] near 'ELECT * FROM Person WHERE age=18' at line 1

需要注意的是,它只打印查询的前80个字符。

我不知道为什么会投反对票。它很简单而且很有效。它工作得很快。比打开日志,在日志中搜索正确的行,然后禁用日志,然后清除日志文件快得多。

上面提到的$querystring属性可能只返回传入的查询,而不使用其值替换参数。在.NET中,我让查询执行器的catch部分用提供的值对参数进行简单的搜索替换,以便错误日志可以显示用于查询的实际值。您应该能够在PHP中枚举参数,并用它们的赋值替换这些参数。

我知道这个问题有点老了,但是,我从很久以前就开始使用这个代码(我使用了@chris go的response),现在,这些代码在php 7.2中已经过时了。

我将发布这些代码的更新版本(主要代码来自@bigwebguy、@mike和@chris go,它们都是这个问题的答案):

/**

* Replaces any parameter placeholders in a query with the value of that

* parameter. Useful for debugging. Assumes anonymous parameters from

* $params are are in the same order as specified in $query

*

* @param string $query The sql query with parameter placeholders

* @param array $params The array of substitution parameters

* @return string The interpolated query

*/

public function interpolateQuery($query, $params) {

$keys = array();

$values = $params;

# build a regular expression for each parameter    foreach ($params as $key => $value) {

if (is_string($key)) {

$keys[] = '/:'.$key.'/';

} else {

$keys[] = '/[?]/';

}

if (is_array($value))

$values[$key] = implode(',', $value);

if (is_null($value))

$values[$key] = 'NULL';

}

// Walk the array to see if we can add single-quotes to strings

array_walk($values, function(&$v, $k) { if (!is_numeric($v) && $v !="NULL") $v ="\'" . $v ."\'"; });

$query = preg_replace($keys, $values, $query, 1, $count);

return $query;

}

注意,代码的更改是在array_walk()函数上进行的,用匿名函数替换create_函数。这使得这些代码具有良好的功能性,并与php 7.2兼容(也希望将来的版本)。

我需要在绑定参数之后记录完整的查询字符串,所以这是我代码中的一部分。希望,它对每个有相同问题的人都有用。

/**

*

* @param string $str

* @return string

*/

public function quote($str) {

if (!is_array($str)) {

return $this->pdo->quote($str);

} else {

$str = implode(',', array_map(function($v) {

return $this->quote($v);

}, $str));

if (empty($str)) {

return 'NULL';

}

return $str;

}

}

/**

*

* @param string $query

* @param array $params

* @return string

* @throws Exception

*/

public function interpolateQuery($query, $params) {

$ps = preg_split("/'/is", $query);

$pieces = [];

$prev = null;

foreach ($ps as $p) {

$lastChar = substr($p, strlen($p) - 1);

if ($lastChar !="\") {

if ($prev === null) {

$pieces[] = $p;

} else {

$pieces[] = $prev ."'" . $p;

$prev = null;

}

} else {

$prev .= ($prev === null ? '' :"'") . $p;

}

}

$arr = [];

$indexQuestionMark = -1;

$matches = [];

for ($i = 0; $i < count($pieces); $i++) {

if ($i % 2 !== 0) {

$arr[] ="'" . $pieces[$i] ."'";

} else {

$st = '';

$s = $pieces[$i];

while (!empty($s)) {

if (preg_match("/(\?|:[A-Z0-9_\-]+)/is", $s, $matches, PREG_OFFSET_CAPTURE)) {

$index = $matches[0][1];

$st .= substr($s, 0, $index);

$key = $matches[0][0];

$s = substr($s, $index + strlen($key));

if ($key == '?') {

$indexQuestionMark++;

if (array_key_exists($indexQuestionMark, $params)) {

$st .= $this->quote($params[$indexQuestionMark]);

} else {

throw new Exception('Wrong params in query at ' . $index);

}

} else {

if (array_key_exists($key, $params)) {

$st .= $this->quote($params[$key]);

} else {

throw new Exception('Wrong params in query with key ' . $key);

}

}

} else {

$st .= $s;

$s = null;

}

}

$arr[] = $st;

}

}

return implode('', $arr);

}

有点关联…如果您只是想清理一个特定的变量,那么可以使用pdo::quote。例如,如果您使用有限的框架(如cakephp)搜索多个部分类似的条件:

$pdo = $this->getDataSource()->getConnection();

$results = $this->find('all', array(

'conditions' => array(

'Model.name LIKE ' . $pdo->quote("%{$keyword1}%"),

'Model.name LIKE ' . $pdo->quote("%{$keyword2}%"),

),

);

preg_replace对我不起作用,当binding_超过9时,binding_1和binding_10被str_replace替换(将0留在后面),因此我向后替换:

public function interpolateQuery($query, $params) {

$keys = array();

$length = count($params)-1;

for ($i = $length; $i >=0; $i--) {

$query  = str_replace(':binding_'.(string)$i, '\''.$params[$i]['val'].'\'', $query);

}

// $query  = str_replace('SQL_CALC_FOUND_ROWS', '', $query, $count);

return $query;

}

希望有人发现它有用。

在您使用"重用"绑定值之前,Mike的答案是有效的。例如:

SELECT * FROM `an_modules` AS `m` LEFT JOIN `an_module_sites` AS `ms` ON m.module_id = ms.module_id WHERE 1 AND `module_enable` = :module_enable AND `site_id` = :site_id AND (`module_system_name` LIKE :search OR `module_version` LIKE :search)

麦克的回答只能取代第一个:搜索,而不是第二个。所以,我重写了他的答案,使其能够正确地使用多个参数。

public function interpolateQuery($query, $params) {

$keys = array();

$values = $params;

$values_limit = [];

$words_repeated = array_count_values(str_word_count($query, 1, ':_'));

# build a regular expression for each parameter    foreach ($params as $key => $value) {

if (is_string($key)) {

$keys[] = '/:'.$key.'/';

$values_limit[$key] = (isset($words_repeated[':'.$key]) ? intval($words_repeated[':'.$key]) : 1);

} else {

$keys[] = '/[?]/';

$values_limit = [];

}

if (is_string($value))

$values[$key] ="'" . $value ."'";

if (is_array($value))

$values[$key] ="'" . implode("','", $value) ."'";

if (is_null($value))

$values[$key] = 'NULL';

}

if (is_array($values)) {

foreach ($values as $key => $val) {

if (isset($values_limit[$key])) {

$query = preg_replace(['/:'.$key.'/'], [$val], $query, $values_limit[$key], $count);

} else {

$query = preg_replace(['/:'.$key.'/'], [$val], $query, 1, $count);

}

}

unset($key, $val);

} else {

$query = preg_replace($keys, $values, $query, 1, $count);

}

unset($keys, $values, $values_limit, $words_repeated);

return $query;

}

php pdo预处理查询,关于php:从PDO预处理语句中获取原始SQL查询字符串相关推荐

  1. mysql 查询多个号段_数据库中如何使用SQL查询连续号码段(转载)

    转自:http://www.poluoluo.com/jzxy/200801/9937.html 在ITPUB上有一则非常巧妙的SQL技巧,学习一下,记录在这里. 最初的问题是这样的: 我有一个表结构 ...

  2. Java 中如何使用 SQL 查询文本

    [摘要]         使用 SQL 查询语言,你只能查询位于数据库里面的数据,但是当你面对的数据是一些 Excel 表格或者 Txt 文本格式时,有什么办法能直接对着文件进行 Select 查询呢 ...

  3. 用于存储过程的ASP.NET Core Blazor和EF Core原始SQL查询

    目录 介绍 背景 先决条件 使用代码 创建数据库和表 步骤1:创建ASP.NET Core Blazor服务器应用程序 运行测试应用程序 步骤2:安装软件包 连接字符串 步骤3:建立模型类 创建DBC ...

  4. java 查询sql_Java 中如何使用 SQL 查询文本

    [摘要] 使用 SQL 查询语言,你只能查询位于数据库里面的数据,但是当你面对的数据是一些 Excel 表格或者 Txt 文本格式时,有什么办法能直接对着文件进行 Select 查询呢?去乾学院看个究 ...

  5. Hibernate中的命名SQL查询

    2019独角兽企业重金招聘Python工程师标准>>> 1.  命名查询指的是用<sql-query>标签在影射文档中定义的SQL查询,可以通过使用Session.get ...

  6. 如何获取查询生成器以字符串形式输出其原始SQL查询?

    本文翻译自:How Do I Get the Query Builder to Output Its Raw SQL Query as a String? Given the following co ...

  7. 关于oracle查询语句中like '%中文的%' 查询不到数据的问题

    关于oracle查询语句中like '%中文的%' 查询不到数据的问题 问题描述: 关于oracle查询语句中like '%中文的%' 查询不到数据的问题解决 起因: 在Windows10 系统环境下 ...

  8. 查缺补漏系统学习 EF Core 6 - 原始 SQL 查询

    推荐关注「码侠江湖」加星标,时刻不忘江湖事 这是 EF Core 系列的第五篇文章,上一篇文章盘点了 EF Core 中的几种数据查询方式. 但是有有时候,我们可能无法用标准的 LINQ 方法完成查询 ...

  9. 执行sql语句_一条SQL查询语句是如何执行的?

    本篇文章将通过一条 SQL 的执行过程来介绍 MySQL 的基础架构. 首先有一个 user_info 表,表里有一个 id 字段,执行下面这条查询语句: select * from user_inf ...

最新文章

  1. docker基本操作
  2. InstallShield 2011中数字签名失败的问题
  3. 剑指offer 算法 (抽象建模能力)
  4. 澎湖县地产泡沫的破灭
  5. php如何替换 前的空格,php空格如何替换
  6. JavaScript中发布/订阅模式的理解
  7. 史上最全 BAT 大厂面试题整理
  8. 【计算机网络复习 物理层】2.3 物理层设备
  9. 找到bug的根源,问五次为什么
  10. iOS Category 和 Extention 的本质区别【面试必备】
  11. MITRE 发布“2021年最重要的硬件弱点”榜单
  12. 修复Ubuntu系列pip
  13. NHibernate Inheritance Mapping 继承映射
  14. Kafka如何保证不丢数据?
  15. MacOS基金管理软件
  16. HDS AMS 更换控制器和控制器缓存
  17. RE: C与C++社区混战,C#会重蹈覆辙吗?
  18. 用python画皇冠_【推荐】手把手教你如何用Python画一棵漂亮樱花树含源码
  19. 笛卡尔树(Cartesian Tree)
  20. STM32中的DFSDM应用介绍

热门文章

  1. 通过Log4net来配置我们需要的日志文件格式
  2. 选择“关机”还是“睡眠”?
  3. sql注入_1-8_宽字节注入
  4. 2020年第十一届蓝桥杯 - 国赛 - Java研究生组 - F.循环小数
  5. LeetCode Algorithm 240. 搜索二维矩阵 II
  6. Maximum Profit Aizu - ALDS1_1_D
  7. C语言中的各输出格式含义
  8. 【Qt】Qt中的快捷键汇总
  9. 【Android】Android中WIFI开发总结(一)
  10. java内存图解_图解JAVA内存模型(JMM:JAVA Memory Model)