分享php工作中遇到的一些探究和技巧【1】

一 foreach的引用

$arr = range(1,3); //[1,2,3] 

foreach($arr as &$val) { 

}
foreach($arr as $val) { 

}
print_r($arr);

上面的代码会输出什么?

Array (
    [0] => 1
    [1] => 2
    [2] => 2
)

这是因为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 = 10000;
$test_arr = range(0, $max);
$temp;
//我们分别用三种方法测试求这些数加上1的值的时间。

// for 的方法
$t1 = microtime(true);
for ($i = 0; $i < $max; $i++) {
    $temp = $temp + 1;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "就使用for, 没有对数组操作 花费: {$t}\n";

$t1 = microtime(true);
for ($i = 0; $i < $max; $i++) {
    $test_arr[$i] = $test_arr[$i] + 1;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用for 并且直接对数组进行了操作 花费: {$t}\n";

$t1 = microtime(true);
for ($i = 0; $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 + 1;
}
$t2 = microtime(true);
$t = $t2 - $t1;
echo "使用 foreach 没有对数组操作 花费 : {$t}\n";

$t1 = microtime(true);
foreach ($test_arr as $k => &$v) {
    $v = $v + 1;
}
$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 + 1;
}

执行的结果:
就使用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` int(11) NOT NULL AUTO_INCREMENT,
  `player_id` int(11) NOT NULL DEFAULT ‘0‘,
  `old_name` varchar(255) NOT NULL DEFAULT ‘‘,
  `day` int(11) NOT NULL DEFAULT ‘20110101‘,
  PRIMARY KEY (`id`),
  KEY `idx_player_id` (`player_id`,`day`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;

当我使用联合条件查询,

EXPLAIN select * from t_log_change_name where player_id =344 and `day`>=‘20161012‘;

结果当然是没问题的,直接选中想要的数据,影响行为3行

当我用只使用第一列为条件查询,

EXPLAIN select * from t_log_change_name where player_id =344;

它处于索引的第一列,因此是可以命中索引的

当我使用第二列为条件查询,

EXPLAIN select * from t_log_change_name where `day`>=‘20161012‘;

那不好意思,它属于索引的第二列,因此无法命中索引,全部行都检索一遍

所以务必根据业务需求而去建立合适的索引
,同时注意联合索引的顺序,失效情况。

时间: 2024-10-11 07:28:04

分享php工作中遇到的一些探究和技巧【1】的相关文章

工作中,掌握这三个技巧,让你成为一个可靠的人

对于每一个人来说,既然选择一份工作,就像把它做好,不管在奋斗的过程中,遇到多大的困难,都会义无反顾的勇往直前.因为只有这样做,才能够让我们变得越来越坚强.所以在我们的日常办公中多写一点知识对我们今后的发展是很重要的,下面是分享的几个小技巧,一起看看吧! 1.不管做什么事情,都会留心眼 在现如今社会中,光看一个人的表面,并不能够判断出这个人究竟是好是坏.所以当我们进入工作中的时候,无论做什么事情,都要学会留心眼.哪怕那个人是你的好朋友,你都不能够掉以轻心.当你凡事都学会留心眼的时候,你就能够从中获

分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据

原文:分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据 分享工作中遇到的问题积累经验 事务日志太大导致insert不进数据 今天开发找我,说数据库insert不进数据,叫我看一下 他发了一个截图给我 然后我登录上服务器,发现了可疑的地方,而且这个数据库之前有一段经历 在月初的时候这个数据库曾经置疑过,启动不起来 Could not redo log record (163041:116859:5), for transaction ID (0:-1175226963), on

给大家分享12个或许能在实际工作中帮助你解决一些问题的JavaScript的小技巧

使用!!操作符转换布尔值 有时候我们需要对一个变量查检其是否存在或者检查值是否有一个有效值,如果存在就返回true值.为了做这样的验证,我们可以使用!!操作符来实现是非常的方便与简单.对于变量可以使用!!variable做检测,只要变量的值为:0.null." ".undefined或者NaN都将返回的是false,反之返回的是true.比如下面的示例: 01 function Account(cash) { 02 this.cash = cash; 03 this.hasMoney

非广告:《工作中软件分享》--PDF/EXCEL/WORD优化、压缩处理软件

分享原因:工作中通过一体式打印机扫描纸质文件后产生的 PDF 实在是太大,不可以在通过邮箱正常的发送出去. 为了解决这个头痛与苦恼的问题,一直以来都在麻烦度娘. 测试过的方法: 1.pdf打印机再打印. >>>>>>使用cutpdf打印机再打印后,文件变大了 2.使用Adobe Acrobat X Pro . >>>>>>功能完善与强大,可以完成工作要求.但是此软件太大,下载麻烦,而且会惹大问题(大家懂的). 3.使用 NXPower

工作中使用到的技术和工具分享

已经很长时间没有写博客,7月份走出校门距离现在也有4个月了,没出校门之前以为自己懂得很多,真正工作了才发现自己学的东西真的已经落伍和过时了,在这里分享这四个月学习到的或者收藏的一些工作中需要使用的技术和工具,希望对还没走出校门的你们或者急需提升自己技术能力的伙伴有些许的帮助. 一.实用工具介绍 1)FQ工具:一只猫 | Jump Out Google是最好的老师,你遇到的问题和困难前人肯定都遇到过,技术资料不建议百度 2)抓包工具:Fiddler:Fiddler 抓包工具总结.charles 工

分享:程序员开发者在工作中最易犯的错误,你晓得吗?

1.没有明确的职业目标 没有目标的人生,就像无根的浮萍,水流到哪里就飘到哪里,一生漂泊.如果你想要在软件开发领域获得真正的成功,那么就必须知道该何去何从.或许面对遥远的未来,你已经有了一个粗略的目标了.但是除了这点还不够,你应当坚实自己的目标--清楚的定义在实现过程中的每个重要时间点所需要达到的效果. 面对于此,你该怎么做呢?从现在开始,花一些时间来认真规划一下职业并确定最近的目标.一旦你达到了这个目标,你就要选择一个新的目标了.在职业生涯中,这样的目标会一个接着一个. 2.不重视"软技能&qu

我实践工作中的一些软件性能测试经验分享

 首先,对所有的业务都进行性能测试是不可行,也是不现实的. (1)选取业务量较大的业务,比如某电商平台明天上午10点有个特卖会,那么这个特卖会的业务用户访问量较大,所以在上线之前要做好充分的测试验证,才能决定是否上线. (2)需要重点关注的业务,比如对应电子商务平台的用户下单,提交订单,如果在同样的时间段内某个平台生成的订单数量越少,那么对公司来说是不可容忍的. (3)选取业务量不大,但是该业务消耗系统资源的业务. (4)把用户操最常用,最频繁的操作业务拿来做测试(比如对于GIS地图的放大,

openstack运维手册(个人实际工作中整理)

openstack运维手册,是本人在实际工作中整理的,现分享!!!因水平有限,欢迎广大朋友指正.具体文档见附件.

用户研究工作中的14个经典方法

历时2个多月的编撰和设计,#用研方法传遍中国#在今天将告一段落;经过仔细的梳理与总结,@百度商业UED 的用户研究工程师们将用户研究工作中的经典方法一一总结出来,与大家分享讨论,感谢和我们微博互动的同学们,也欢迎更多对用户体验感兴趣的同学加入讨论,大家共同努力.共同进步! 1 .[眼动&脑电研究] 将眼动仪和脑电设备联机同步,可以知道用户是如何看的,以及当时的心理活动. 2 .[可用性测试] 想知道可用测试是什么?可用性测试的目的&作用?适用的场景?测试所需的人数? 3.[信噪比原则] 如