分享php工作中遇到的一些探究和技巧【1】
一 foreach的引用
$arr = range(,); //[1,2,3]
foreach($arr as &$val) {
}
foreach($arr as $val) {
}
print_r($arr);
上面的代码会输出什么?
Array (
[] =>
[] =>
[] =>
)
这是因为foreach的源代码中,对变量进行了引用。导致其作用之后,将地址赋值于最后一个
例:
tmp是var的引用,指向的是var的存储空间,当tmp改变的时候,var也改变
$var = 123;
$tmp = &$var;
$tmp = 200;
echo $var;
//20
示意图:
解决方法:
//方法1
foreach ($arr as &$value) {
}
unset($value);
foreach ($arr as $value) {
}
print_r($arr); //[1,2,3]
//方法2
foreach ($arr as &$value) {
}
foreach ($arr as $val) {
}
print_r($arr);
//[1,2,3]
//方法3
foreach ($arr as &$value) {
}
foreach ($arr as &$value) {
}
print_r($arr);
//[1,2,3]
二 擅于用array_walk 和 foreach, for
<?php
/**
* array_walk 和 foreach, for 的效率的比较。
* 我们要测试的是foreach, for, 和 array_walk的效率的问题。
*/
//产生一个10000的一个数组。
$max = ;
$test_arr = range(, $max);
$temp;
//我们分别用三种方法测试求这些数加上1的值的时间。
// for 的方法
$t1 = microtime(true);
; $i < $max; $i++) {
$temp = $temp + ;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "就使用for, 没有对数组操作 花费: {$t}\n";
$t1 = microtime(true);
; $i < $max; $i++) {
$test_arr[$i] = $test_arr[$i] + ;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用for 并且直接对数组进行了操作 花费: {$t}\n";
$t1 = microtime(true);
; $i < $max; $i++) {
addOne($test_arr[$i]);
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用for 调用函数对数组操作 花费 : {$t}\n";
$t1 = microtime(true);
foreach ($test_arr as $k => &$v) {
$temp = $temp + ;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用 foreach 没有对数组操作 花费 : {$t}\n";
$t1 = microtime(true);
foreach ($test_arr as $k => &$v) {
$v = $v + ;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用 foreach 直接对数组操作 : {$t}\n";
$t1 = microtime(true);
foreach ($test_arr as $k => &$v) {
addOne($v);
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用 foreach 调用函数对数组操作 : {$t}\n";
$t1 = microtime(true);
array_walk($test_arr, 'addOne');
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用 array_walk 花费 : {$t}\n";
function addOne(&$item) {
$item = $item + ;
}
执行的结果:
就使用for, 没有对数组操作 花费: 0.15388584136963
使用 foreach 没有对数组操作 花费 : 0.076934814453125
使用for 并且直接对数组进行了操作 花费: 0.14769005775452
使用 foreach 直接对数组操作 : 0.076115131378174
使用for 调用函数对数组操作 花费 : 0.32393312454224
使用 foreach 调用函数对数组操作 : 0.25716996192932
使用 array_walk 花费 : 0.17966890335083
在对10000个数的操作过程中,这个实验我们可以得出这样的结论:
foreach 的效率要比for 高很多,也许有很大的一个原因是for 要进行很多次条件判断。所以以后能用foreach的地方就用foreach,可以提高1倍的效率。
如果循环内要调用函数,用array_walk 最好,它的效率要比for 高出1倍,要比foreach高出43%的效率。
还有一个提示就是如果你这个程序对效率的要求是很高的,那不要在很深的循环中调用函数,要调用函数也要用array_walk,最好的直接把代码写在循环里面。
同时,我们来看一下这两个函数的区别:
array_walk 主要是要对数组内的每个值进行操作,操作结果影响原来的数组 array_map主要是对数组中的值进行操作后返回数组,以得到一个新数组 wallk 可以没有返回值 map要有,因为要填充数组
三 为什么要用联合索引 ?
1 在多条件查询时,联合索引效率要高。在允许的范围内,多条件个条件查询的时候,应该根据业务创建多个联合索引。这样效率比分开创建多个索引要快
2 查询条件中出现联合索引第一列,或者全部,则能利用联合索引.
换句话说:查询条件中没有出现联合索引的第一列,而出现联合索引的第二列,或者第三列,都不会利用联合索引查询.
而单一索引:只要条件列中出现索引列,无论在什么位置,都能利用索引查询.
我本地电脑有如下表:
CREATE TABLE `t_log_change_name` ( `id` ) NOT NULL AUTO_INCREMENT, `player_id` ) NOT NULL DEFAULT ', `old_name` varchar() NOT NULL DEFAULT '', `day` ) NOT NULL DEFAULT ', PRIMARY KEY (`id`), KEY `idx_player_id` (`player_id`,`day`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
当我使用联合条件查询,
EXPLAIN and `day`>=';
结果当然是没问题的,直接选中想要的数据,影响行为3行
当我用只使用第一列为条件查询,
EXPLAIN ;
它处于索引的第一列,因此是可以命中索引的
当我使用第二列为条件查询,
EXPLAIN ';
那不好意思,它属于索引的第二列,因此无法命中索引,全部行都检索一遍
所以务必根据业务需求而去建立合适的索引
,同时注意联合索引的顺序,失效情况。
分享php工作中遇到的一些探究和技巧【1】的更多相关文章
- 分享php工作中遇到的一些探究和技巧【2】
1 如何定义linux和window通用的文件分隔符号 DIRECTORY_SEPARATOR : 目录分隔符,是定义php的内置常量.在调试机器上,在windows我们习惯性的使用"\& ...
- 【开源】【前后端分离】【优雅编码】分享我工作中的一款MVC+EF+IoC+Layui前后端分离的框架——【NO.1】框架概述
写博客之前总想说点什么,但写的时候又忘了想说点什么,算了,不说了,还是来送福利吧. 今天是来分享我在平时工作中搭建的一套前后端分离的框架. 平时工作大多时候都是在做管理类型的软件开发,无非就是增.删. ...
- 分享一个工作中遇得到的sql(按每天每人统计拖车次数与小修次数)
查询每人每天的数据 首先先建表 CREATE TABLE `user` ( `name` ) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CR ...
- 工作中常用的 Shell 命令及技巧
调试 bash 脚本的技巧 加 -x 参数运行 bash 脚本时,会显示执行的语句 # 也可以在 demo.sh 中加上 set -x bash -x demo.sh 设置环境变量,然后通过如上方式运 ...
- 分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据
分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据 今天开发找我,说数据库insert不进数据,叫我看一下 他发了一个截图给我 然后我登录上服务器,发现了可疑的地方,而且这个数据库之前 ...
- 博主日常工作中使用的shell脚本分享
前言: 今天给大家分享一篇在我工作中常用的一个shell脚本,里面有一些我们常用到的shell操作.该脚本用于本地电脑和服务器交互上,实现以下功能: 自动拉取自己个人电脑上的源码到服务器上yocto包 ...
- 工作中比较重要的经验分享-2016-bypkm
工作中总有一些经验能让人记忆深刻,能让人终生受用,相比技术而言,经验是宝贵的.无价的.在我的博客中,主要是技术类的博文,那些东西是相对死板的,价值也相对低廉.今天就记录一下我在工作中一次比较重要的经验 ...
- 总结一下工作中遇到的NPOI以及在ASP.NET MVC中的使用
1.前言 相信大家在工作中经常要遇到一些导入导出Execl操作.学习贵在分享,分享使人快乐,园子里的前辈已经有很多好的文章,鄙人也是能力有限,在这里把这些好的文章总结,方便以后再工作中使用. NPOI ...
- 收集一些工作中常用的经典SQL语句
作为一枚程序员来说和数据库打交道是不可避免的,现收集一下工作中常用的SQL语句,希望能给大家带来一些帮助,当然不全面,欢迎补充! 1.执行插入语句,获取自动生成的递增的ID值 INSERT INTO ...
随机推荐
- C# CGI程序
一.控制面板—>程序和功能—>打开或关闭Windows功能 把相关的功能勾上,点“确定” 二.新建一个网站,配置ISAPI和CGI限制.处理程序映射 三.CGI控制台应用程序代码: usi ...
- WinForm(VB.NET)获取当前登录的用户名
运行Windows Task Manager,查看Users标签,可以看到所有登录电脑的用户,现在Insus.NET想命名用VB.NET的WinForm程序去获取当前的用户名. 获取程序简单,可以参考 ...
- Winform开发框架之参数配置管理功能实现-基于SettingsProvider.net的构建
在较早时期,我写过一篇文章<结合Control.FirefoxDialog控件,构造优秀的参数配置管理模块>,介绍过在我的Winform框架基础上集成的参数配置模块功能,但是参数模块的配置 ...
- jQuery Mobile动态刷新页面样式
当我们使用Ajax或者javascript动态在页面上添加元素后,如添加select控件的option元素,添加ul的li元素.添加之后我们会发现,它们显示的样式不是jQuery Mobile的炫酷样 ...
- 更改(修改)mysql自动增序列改变从1000开始
更改(修改)mysql自动增序列改变从1000开始 ************************************************************************** ...
- 让 ListView 在 Android 可回弹
说明:让 ListView 在 Android 可回弹. 适用:Delphi XE5 修改:找出 FMX.Platform.Android.pas 档案,并复制到自己的 Project 路径里,找到 ...
- MAC 卸载 openfire
顺序执行以下命令: sudo rm -rf /Library/PreferencePanes/Openfire.prefPane sudo rm -rf /usr/local/openfire
- jQuery Wookmark Load 瀑布流布局实例演示
瀑布流布局非常适合大量图片的展示,一改过去裁剪图片尺寸统一的排版,每张图片都能完全展示,并错落有致,让人眼前一亮. 版本: jQuery v1.4.3+ jQuery Wookmark Load v1 ...
- EpicEditor – 可嵌入的 JavaScript Markdown 编辑器
EpicEditor 是一款可以嵌入到网页中的 JavaScript Markdown 编辑器,支持全屏编辑.在线预览.自动保存草稿,离线支持等等.对于开发人员,它提供了一个健壮的API,可以很容易定 ...
- javascript --- 事件冒泡与事件捕获
事件冒泡与事件捕获 事件冒泡和事件捕获分别由微软和网景公司提出,这两个概念都是为了解决页面中事件流(事件发生顺序)的问题.考虑下面这段代码,就不写html->head,body之类的代码了,自行 ...