我的网站范围相当广泛,最近我刚切换到PHP5(称我为后期开发者)。

我之前所有的MySQL查询都是这样构建的:

"SELECT * FROM tablename WHERE field1 = 'value' && field2 = 'value2'";

这使得它非常容易,简单和友好。

由于明显的安全性原因,我现在正尝试切换到mysqli,并且在bind_param需要特定参数时很难弄清楚如何实现相同的SELECT * FROM查询。

这句话已成为过去吗?

如果是的话,如何处理涉及大量列的查询? 我真的需要每次都把它们全部打出来吗?

这已经是一个月前了,但是哦。

我可能是错的,但是对于您的问题,我感到bindparam并不是这里的真正问题。您始终需要使用bindparam设置?占位符的条件,直接在查询字符串中定义。那不是真正的问题。

我使用MySQLi SELECT *查询时遇到的问题是bind_result部分。那就是它变得有趣的地方。我从Jeffrey Way那里看到了这篇文章:http://jeff-way.com/2009/05/27/tricky-prepared-statements/(此链接不再有效)。该脚本基本上遍历结果并将其作为数组返回-无需知道有多少列,您仍然可以使用准备好的语句。

在这种情况下,它将看起来像这样:

$stmt = $mysqli->prepare(

'SELECT * FROM tablename WHERE field1 = ? AND field2 = ?');

$stmt->bind_param('ss', $value, $value2);

$stmt->execute();

然后使用网站中的代码段:

$meta = $stmt->result_metadata();

while ($field = $meta->fetch_field()) {

$parameters[] = &$row[$field->name];

}

call_user_func_array(array($stmt, 'bind_result'), $parameters);

while ($stmt->fetch()) {

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

$x[$key] = $val;

}

$results[] = $x;

}

现在,$results包含来自SELECT *的所有信息。到目前为止,我发现这是一个理想的解决方案。

太好了,谢谢@Alec!我为自己苦苦挣扎的一些小东西:如果您还想将null值传递给bind_result,则需要在查询中使用null安全的<=>运算符,例如SELECT * FROM tablename WHERE field1 <=> ? AND field2 <=> ?。请参阅<=>运算符上的MySQL文档。

"SELECT * FROM tablename WHERE field1 = 'value' && field2 = 'value2'";

变成

"SELECT * FROM tablename WHERE field1 = ? && field2 = ?";

传递给$mysqli::prepare的内容:

$stmt = $mysqli->prepare(

"SELECT * FROM tablename WHERE field1 = ? && field2 = ?");

$stmt->bind_param("ss", $value, $value2);

//"ss' is a format string, each"s" means string

$stmt->execute();

$stmt->bind_result($col1, $col2);

// then fetch and close the statement

OP评论:

so if i have 5 parameters, i could potentially have"sssis" or something (depending on the types of inputs?)

正确,在准备好的语句中,每个?参数都有一个类型说明符,它们都在位置上(第一个说明符适用于第一个?,该第一个说明符适用于第一个实际参数(这是bind_param的第二个参数))。

mysqli将负责转义和引用(我认为)。

因此,如果我有5个参数,则可能会有" sssis"之类的东西(取决于输入的类型?)

切换时,切换到PDO而不是mysqli,它可以帮助您编写数据库不可知代码,并为准备好的语句提供更好的功能。

http://www.php.net/pdo

PDO的Bindparam:

http://se.php.net/manual/en/pdostatement.bindparam.php

$sth = $dbh->prepare("SELECT * FROM tablename WHERE field1 = :value1 && field2 = :value2");

$sth->bindParam(':value1', 'foo');

$sth->bindParam(':value2', 'bar');

$sth->execute();

要么:

$sth = $dbh->prepare("SELECT * FROM tablename WHERE field1 = ? && field2 = ?");

$sth->bindParam(1, 'foo');

$sth->bindParam(2, 'bar');

$sth->execute();

或使用参数作为数组执行:

$sth = $dbh->prepare("SELECT * FROM tablename WHERE field1 = :value1 && field2 = :value2");

$sth->execute(array(':value1' => 'foo' , ':value2' => 'bar'));

如果您希望将来您的应用程序能够在不同的数据库上运行,则对您来说将更加容易。

我还认为,在与PDO一起工作时,您应该花一些时间使用Zend Framwework的某些类。查看他们的Zend_Db,更具体地说是[Zend_Db_Factory] ??[2]。您不必使用所有框架,也不必将应用程序转换为MVC模式,但是使用框架并仔细阅读它会花费很多时间。

太棒了,我从没听说过PDO,请检查一下

Is this statement a thing of the past?

是。不要使用SELECT *;这是一场维护噩梦。 SO上还有许多其他线程,说明为什么此构造不好,以及如何避免使用它会帮助您编写更好的查询。

也可以看看:

不使用select *的原因是什么?

使用SELECT *时的性能问题?

为什么使用*建立视图不好?

好的...我完全相信您,但是我无法以某种方式找到他们,我可以肯定地向他们学习。 coudl,你给我链接吗?谢谢:)

我认为问题在于绑定变量。我认为" SELECT *"没什么大问题(如果您需要的不仅仅是主键或其他索引列)。

是的,搜索引擎不喜欢查询" SELECT *"。我用几个链接编辑了帖子(第一个链接特别有用)。

您可以在语句中使用get_result()。

http://php.net/manual/zh/mysqli-stmt.get-result.php

您仍然可以使用它(mysqli只是与服务器通信的另一种方式,SQL语言本身已扩展,未更改)。不过,准备好的语句更安全-因为您无需每次都正确地转义值的麻烦。如果愿意,可以保留它们的原样,但是如果切换,则可以减少sql搭载的风险。

有时您甚至需要旧的用法。例如,MySQL无法在准备好的语句中进行多次插入。

它不能吗?这不是大多数人需要做的事情吗?

不,它不能执行将INSERT INTO A(a,b)值(1,2),(3,4),(5,6)之类的操作。并且,如果(并且仅)在速度上是一个问题(在99%的情况下不应该这样-但是我们在最近的项目中只有一个),请考虑以下情况:prepared语句需要1个查询进行3次通信(prepare,set var,execute )

我一直在寻找一个很好的完整示例,该示例如何将多个查询参数动态绑定到任何SELECT,INSERT,UPDATE和DELETE查询。 Alec在他的回答中提到了一种如何绑定结果的方法,对我来说,执行SELECT查询的execute()函数之后的get_result()很好,并且能够将所有选定的结果检索到关联数组的数组中。

无论如何,我最终创建了一个函数,可以将任意数量的参数动态绑定到参数化查询(使用call_user_func_array函数)并获得查询执行的结果。下面是该函数及其文档(使用前请先阅读-特别是$ paremetersTypes-类型规范chars参数对于理解非常重要)

/**

* Prepares and executes a parametrized QUERY (SELECT, INSERT, UPDATE, DELETE)

*

* @param[in] $dbConnection mysqli database connection to be used for query execution

* @param[in] $dbQuery parametrized query to be bind parameters for and then execute

* @param[in] $isDMQ boolean value, should be set to TRUE for (DELETE, INSERT, UPDATE - Data manipulaiton queries), FALSE for SELECT queries

* @param[in] $paremetersTypes String representation for input parametrs' types as per http://php.net/manual/en/mysqli-stmt.bind-param.php

* @param[in] $errorOut A variable to be passed by reference where a string representation of an error will be present if a FAUILURE occurs

* @param[in] $arrayOfParemetersToBind Parameters to be bind to the parametrized query, parameters need to be specified in an array in the correct order

* @return array of feched records associative arrays for SELECT query on SUCCESS, TRUE for INSERT, UPDATE, DELETE queries on SUCCESS, on FAIL sets the error and returns NULL

*/

function ExecuteMySQLParametrizedQuery($dbConnection, $dbQuery, $isDMQ, $paremetersTypes, &$errorOut, $arrayOfParemetersToBind)

{

$stmt = $dbConnection->prepare($dbQuery);

$outValue = NULL;

if ($stmt === FALSE)

$errorOut = 'Failed to prepare statement for query: ' . $dbQuery;

else if ( call_user_func_array(array($stmt,"bind_param"), array_merge(array($paremetersTypes), $arrayOfParemetersToBind)) === FALSE)

$errorOut = 'Failed to bind required parameters to query: ' . $dbQuery . '  , parameters :' . json_encode($arrayOfParemetersToBind);

else if (!$stmt->execute())

$errorOut ="Failed to execute query [$dbQuery] , erorr:" . $stmt->error;

else

{

if ($isDMQ)

$outValue = TRUE;

else

{

$result = $stmt->get_result();

if ($result === FALSE)

$errorOut = 'Failed to obtain result from statement for query ' . $dbQuery;

else

$outValue = $result->fetch_all(MYSQLI_ASSOC);

}

}

$stmt->close();

return $outValue;

}

用法:

$param1 ="128989";

$param2 ="some passcode";

$insertQuery ="INSERT INTO Cards (Serial, UserPin) VALUES (?, ?)";

$rowsInserted = ExecuteMySQLParametrizedQuery($dbConnection, $insertQuery, TRUE, 'ss', $errorOut, array(&$param1, &$param2) ); // Make sure the parameters in an array are passed by reference

if ($rowsInserted === NULL)

echo 'error ' . $errorOut;

else

echo"successfully inserted row";

$selectQuery ="SELECT CardID FROM Cards WHERE Serial like ? AND UserPin like ?";

$arrayOfCardIDs = ExecuteMySQLParametrizedQuery($dbConnection, $selectQuery, FALSE, 'ss', $errorOut, array(&$param1, &$param2) ); // Make sure the parameters in an array are passed by reference

if ($arrayOfCardIDs === NULL)

echo 'error ' . $errorOut;

else

{

echo 'obtained result array of ' . count($arrayOfCardIDs) . 'selected rows';

if (count($arrayOfCardIDs) > 0)

echo 'obtained card id = ' . $arrayOfCardIDs[0]['CardID'];

}

将错误消息作为函数参数只是一件奇怪的事情。错误应该是错误。 php.net/manual/en/function.trigger-error.php

$ isDMQ和$ paremetersTypes应该是可选的

感谢您的评论-已修改为使用fetch_all()函数。我了解这种实现并不完美,请随时根据需要编辑功能。就可选参数而言-正如函数名所指示的那样,其目的是仅执行参数化查询(对于非参数化查询,无需使用此功能)。

php中select from,关于php:SELECT * FROM MySQLi相关推荐

  1. SQL Server中SELECT会真的阻塞SELECT吗?

    在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...

  2. pandas使用query函数查询dataframe指定数据列的内容(数值)包含在特定列表中的数据行(select rows which column values contain in list)

    pandas使用query函数查询dataframe指定数据列的内容(数值)包含在特定列表中的数据行(select rows which column values contained in a li ...

  3. linux获取fifo中的数据数量,Linux select()和多个套接字的FIFO排序?

    您可以使用IP_PKTINFO将数据包被发送到组播组的地址 - 即使套接字认购一堆组播组.完成此操作后,您将按顺序获取数据包并按组地址进行过滤.看下面的例子: #include #include #i ...

  4. shell编程中for/while/util/case/select/break/continue

    2019独角兽企业重金招聘Python工程师标准>>> Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.w ...

  5. CSS-解决苹果点击高亮、安卓select灰色背景(select下拉框在IOS中背景变黑、出现阴影问题)

    CSS-解决苹果点击高亮.安卓select灰色背景(select下拉框在IOS中背景变黑.出现阴影问题) 参考文章: (1)CSS-解决苹果点击高亮.安卓select灰色背景(select下拉框在IO ...

  6. ruby hash方法_Ruby中带有示例的Hash.select方法

    ruby hash方法 哈希选择方法 (Hash.select Method) In this article, we will study about Hash.select Method. The ...

  7. /*1. 查询SC表中的全部数据。*/ SELECT * FROM SC /*2. 查询计算机系学生的姓名和年龄。*/ SELECT Sname,Sex FROM Student WHERE Sd

    1.  查询SC表中的全部数据. SELECT * FROM SC 2.  查询计算机系学生的姓名和年龄. SELECT Sname,Sex FROM Student WHERE Sdept='计算机 ...

  8. mysql dump select_mysql5.5中mysqldump: Got error: 1142: SELECT,LOCK TABL com

    在mysql5.5中,增加了performance_schema,当我们进行mysqldump的时候,会报如下错误信息: mysqldump: Got error: 1142: SELECT,LOCK ...

  9. mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名)

    1.mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名) 的查询结 ...

  10. mysql select表达式_MySQL数据库SELECT查询表达式解析

    数据的管理在很大一部分是在进行查找工作,而SELECT占据了很大的一部分 SELECT select_expr [,select_expr...] [ FROM table_reference WHE ...

最新文章

  1. 利用计算机技术执行去自动化,计算机技术和自动化的关系.doc
  2. 汽车模型身上出现反射效果
  3. nginx的upstream问题记录
  4. 3.1 哈尔空间 V0
  5. C# delegate
  6. CTFshow 命令执行 web30
  7. CSS3--2D3D的使用
  8. 从0-1教你利用服务器做属于自己的个人博客
  9. Hadoop 停止hdfs和yarn的命令
  10. SQL Server 的通用分页显示存储过程
  11. 用脚本js把结果转化为固定小数位的形式
  12. IBM Power System P550双机系统方案
  13. java并发AtomicReference
  14. 获得系统异常的详细信息
  15. Android---- android计量单位--dip、px、sp之间区别与联系pixs =dips * (densityDpi/160). dips=(pixs*160)/d...
  16. 【Hive】Hive分区表
  17. IDEA ideaIU点击无反应
  18. emoji语言抽象话大全_当抽象话也成为一种暗语
  19. 个人管理 - 时间管理GTD流程图
  20. 蓝牙Mesh开发五 Ble Mesh友谊FriendShip之TLSR8258低功耗节点

热门文章

  1. Git是什么?有什么用?
  2. 【ChatGPT】| 最全七大场景50+小场景应用指南合集——内部指导版本(AI训练师必备,带案例)
  3. spdif数字传输规范
  4. IE 浏览器证书错误常见问题解答
  5. Lexical Simplification with Pretrained Encoders 论文精读
  6. 亚马逊查询关键词排名的工具_拼多多关键词排名查询工具怎么查关键词的?
  7. Unknown error finalizing or resetting statement (5: database is locked)
  8. 牛刀:房价泡沫的破灭只是人性的回归
  9. python运维工程师前景及待遇_【运维工程师就业前景】百度2020年运维工程师待遇怎么样-看准网...
  10. 从表征到行动---意向性的自然主义进路(续八)