分类 "Php" 的存档.

关于PHP array_multisort() 函数的理解

参考自:http://hi.baidu.com/ucolo/blog/item/356263a894169eec1e17a20d.html

今天研究了一下php的array_multisort,理解了之后发现他很强大,而且也不复杂。(手册上关于这个函数的讲解看得很费力)

手册讲解:array_multisort() 函数对多个数组或多维数组进行排序。

参数中的数组被当成一个表的列并以行来进行排序 – 这类似 SQL 的 ORDER BY 子句的功能。第一个数组是要排序的主要数组。数组中的行(值)比较为相同的话,就会按照下一个输入数组中相应值的大小进行排序,依此类推。

一、先看最简单的情况。有两个数组:

$arr1 = array(1,9,5);
$arr2 = array(6,2,4);

array_multisort($arr1,$arr2);

print_r($arr1); // 得到的顺序是1,5,9
print_r($arr2); // 得到的顺序是6,4,2

我估计两个数组的值自始至终都是对应着的:1对应6,9对应2,5对应4。

Read more…

给定的经纬度坐标之间的范围/距离计算 php

用PHP实现 给定的经纬度坐标之间的范围/距离的计算-函数:

/**
*求两个已知经纬度之间的距离,单位为米
*@param lng1,lng2 经度
*@param lat1,lat2 纬度
*@return float 距离,单位米
**/
function getdistance($lng1,$lat1,$lng2,$lat2)//根据经纬度计算距离
{
	//将角度转为狐度 
	$radLat1=deg2rad($lat1);
	$radLat2=deg2rad($lat2);
	$radLng1=deg2rad($lng1);
	$radLng2=deg2rad($lng2);
	$a=$radLat1-$radLat2;//两纬度之差,纬度<90
	$b=$radLng1-$radLng2;//两经度之差纬度<180
	$s=2*asin(sqrt(pow(sin($a/2),2)+cos($radLat1)*cos($radLat2)*pow(sin($b/2),2)))*6378.137*1000;
	return $s;
}

//测试,返回结果 : 759.467618902
echo getdistance(116.4558029, 39.9167328, 116.460197, 39.910801);

Read more…

IE7/IE8下javascript的时间函数Date()不兼容讲解–来自amcharts应用中的问题

最近在使用ammap和amcharts做一些数据可视化展现的工作,amcharts图表功能真的很强大,可自定义的属性很多。这是其官网文档链接。可以简单看看文档,会发现有很多属性,可以对图表中的每块表示数据的区域绑定事件,可以是一个url,也可以是一个js,怎么样,只有这两项,就绝对能满足很多扩展的需要了吧。

这是一个我做的例子,使用了ammap和amcharts,左边中国地图,不同省份的数据不一样,颜色代表不同等级的数据;右边是amcharts做的柱状图和折线图。

ammap和amcharts的案例--好用可扩展的javascript图表插件

ammap和amcharts的案例--好用可扩展的javascript图表插件

问题就在使用图表的过程中了,主要是右下角的那个折线图,在chrome、firefox、opera和IE9下均看过了,没有问题,可是到别人机器上,用的IE8,发现右下角的折线图出问题了。于是开始了JS的调试之旅,使用IE9的开发人员工具,可以很方便的调到IE7和IE8模式,之前一直都是firefox的firebug,现在一直都在用chrome,今天用了用IE9的调试工具,发现也挺好用的,主要是它有一个选项,可以设置为-始终从服务器中刷新,这样,每次IE运行获得的JS和CSS文件等,都不会是缓存中来的,调试起来很方便,不用总去清缓存。见下图:

Read more…

MySQL怎样优化WHERE子句

此次讨论的为处理WHERE子句而进行的优化。例子中使用了 SELECT 语句,同样也适用于DELETE和UPDATE语句中的WHERE子句。

下面列出了MySQL执行的部分优化:

去除不必要的括号:

((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
常量重叠:

(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
去除常量条件(由于常量重叠需要):

(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
索引使用的常数表达式仅计算一次。

Read more…

SQL优化实例,看我如何把一个耗时1分钟的请求优化到9秒。

这主要是一个数据统计的web页面,展现统计结果。由于当时需求很紧,要求尽快能出来查询结果就行,而且是说以后会重新对这部分功能进行规划再开发。所以也没有考虑任何性能相关,劈哩啪啦的一天把很多数据统计的功能实现了。
现在,数据量已然有点规模了,但是还没有再开发的计划,目前还使用这个统计程序,但是由于有些数据量了,并且没有考虑过优化,所以目前查询速度很慢。尤其是其中有一个查询,居然耗时1分多,问题很大啊,今天抽点时间,找找问题,优化一下,主要做的工作的是改进sql语句,添加合适的索引。
存储的数据是根据用户的ID末尾的值来简单分表的,所以共有0到9一共10个表,需要遍历这10个表,然后把最后的数据相加,再处理后得到最后结果。由于需求还算比较简单,所以没有采用定时脚本去处理前几日的数据后入库保存的做法,如果采用以上做法,速度会快更多。

Read more…

ThinkPHP 之 文件上传类 UploadFile.class.php 的使用方法

ThinkPHP的文件上传类UploadFile.class.php位于ThinkPHPLibORGNet文件内下,其对于文件上传的处理非常的强大和方便。内置的文件上传类UploadFile类提供了下面的功能:

1、上传检测

2、多文件上传

3、自动生成上传图片缩略图

4、支持覆盖方式上传

5、支持上传类型、附件大小、上传路径定义

6、采用IFrame方式的Ajax上传机制支持

7、支持上传文件命名规则

8、支持对上传文件的Hash规则

9、可设置是否保存附件数据到数据库

在上传表单中可以进行很多参数的设置对上传进行灵活的定义,Action类的_upload方法会自动进行相关处理。
要更好的理解上传保存操作,可以参考ThinkPHP的附件数据表结构,更加详细下面的UploadFile类的参数和使用方法可以参考文件上传类的使用。

Read more…

Session与Cookie。禁用Cookie后Session会不会受影响?

  Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。
  服务器也可以通过URL重写的方式来传递SessionID的值,因此不是完全依赖Cookie。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员透明。
  可以试一下,即使不写Cookie,在使用request.getCookies();取出的Cookie数组的长度也是1,而这个Cookie的名字就是JSESSIONID,还有一个很长的二进制的字符串,是SessionID的值。
  来看一下,即使不写Cookie,通过chrome的开发者工具,也可以看到这么一组cookie的键值 {PHPSESSID : 3e23bc66d024af8b531f2adb192478af}。

Session与Cookie区别-禁用cookie会不会影响session?

Session与Cookie区别-禁用cookie会不会影响session?


Read more…

求解,mysql查询建立索引后查询速度反而不如未建立索引以前

mysql 符合索引,未建立以前用时1.72s,建立一个符合索引后,反而用时2.44s,时间反而更长,是哪的问题呢,求解。。
以下是表结构和mysql explain 后的结果:

mysql> show create table new_bind_mp_weibo_user_info_0;
+----+| Table   | Create Table      |+---+
| new_bind_mp_weibo_user_info_0 | CREATE TABLE `new_bind_mp_weibo_user_info_0` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `weiboid` varchar(20) NOT NULL,
  `weiboun` varchar(100) NOT NULL,
  `mpnumber` varchar(11) NOT NULL,
  `apmac` varchar(100) NOT NULL,
  `bindtime` datetime NOT NULL,
  `source` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `search_key` (`bindtime`)
) ENGINE=MyISAM AUTO_INCREMENT=2768 DEFAULT CHARSET=utf8 | 
+-------------------------------+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table weibo_user_visit_info_0;
+-----------------+| Table    | Create Table |+---------------------------------+
| weibo_user_visit_info_0 | CREATE TABLE `weibo_user_visit_info_0` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `weiboid` varchar(20) NOT NULL,
  `weiboun` varchar(50) NOT NULL,
  `apmac` varchar(100) DEFAULT NULL,
  `usermac` varchar(100) DEFAULT NULL,
  `mpnumber` varchar(11) DEFAULT NULL,
  `visittime` datetime NOT NULL,
  `source` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `weiboid` (`weiboid`)
) ENGINE=MyISAM AUTO_INCREMENT=17952 DEFAULT CHARSET=utf8 | 
+-------------------------+--------------------------------------------+
1 row in set (0.00 sec)

mysql> alter table weibo_user_visit_info_0 add index `search_index` (`apmac`(17),`visittime`);
Query OK, 17944 rows affected (0.21 sec)
Records: 17944  Duplicates: 0  Warnings: 0
mysql> explain select sql_no_cache count(distinct(a.mpnumber)) as mpnumber, date_format(a.bindtime,'%Y-%m-%d') as gDate from new_bind_mp_weibo_user_info_0 a left join weibo_user_visit_info_0 b on a.mpnumber=b.mpnumber  and a.apmac=b.apmac   where b.id is NULL and a.apmac in (select ap_mac from newwifi.business_installedAP_info where businessid=100064)  and a.bindtime between '2012-03-01' and '2012-03-23 23:59:59' group by gDate order by gDate;
+----+--------------------+---------------------------+-------+---------------+--------------+---------+----------------------------+------+-----------------------------+
| id | select_type        | table                     | type  | possible_keys | key          | key_len | ref                        | rows | Extra                       |
+----+--------------------+---------------------------+-------+---------------+--------------+---------+----------------------------+------+-----------------------------+
|  1 | PRIMARY            | a                         | range | search_key    | search_key   | 8       | NULL                       |  394 | Using where; Using filesort | 
|  1 | PRIMARY            | b                         | ref   | search_index  | search_index | 54      | newwifi_visit_info.a.apmac |  142 | Using where; Not exists     | 
|  2 | DEPENDENT SUBQUERY | business_installedAP_info | ref   | search_key    | search_key   | 306     | const,func                 |    1 | Using index                 | 
+----+--------------------+---------------------------+-------+---------------+--------------+---------+----------------------------+------+-----------------------------+
3 rows in set (0.00 sec)

mysql> select sql_no_cache count(distinct(a.mpnumber)) as mpnumber, date_format(a.bindtime,'%Y-%m-%d') as gDate from new_bind_mp_weibo_user_info_0 a left join weibo_user_visit_info_0 b on a.mpnumber=b.mpnumber  and a.apmac=b.apmac   where b.id is NULL and a.apmac in (select ap_mac from newwifi.business_installedAP_info where businessid=100064)  and a.bindtime between '2012-03-01' and '2012-03-23 23:59:59' group by gDate order by gDate;
+----------+------------+
| mpnumber | gDate      |
+----------+------------+
|        4 | 2012-03-01 | 
|       10 | 2012-03-02 | 
|        3 | 2012-03-03 | 
|       10 | 2012-03-04 | 
|       12 | 2012-03-05 | 
|       10 | 2012-03-08 | 
|        4 | 2012-03-09 | 
|       14 | 2012-03-12 | 
|       14 | 2012-03-13 | 
|        7 | 2012-03-14 | 
|       12 | 2012-03-15 | 
|        8 | 2012-03-16 | 
|        7 | 2012-03-17 | 
|       11 | 2012-03-18 | 
|       11 | 2012-03-19 | 
|        8 | 2012-03-20 | 
|        8 | 2012-03-21 | 
|        9 | 2012-03-22 | 
+----------+------------+
18 rows in set (2.44 sec)

mysql> alter table weibo_user_visit_info_0 drop index search_index;
Query OK, 17944 rows affected (0.13 sec)
Records: 17944  Duplicates: 0  Warnings: 0

mysql> explain select sql_no_cache count(distinct(a.mpnumber)) as mpnumber, date_format(a.bindtime,'%Y-%m-%d') as gDate from new_bind_mp_weibo_user_info_0 a left join weibo_user_visit_info_0 b on a.mpnumber=b.mpnumber  and a.apmac=b.apmac   where b.id is NULL and a.apmac in (select ap_mac from newwifi.business_installedAP_info where businessid=100064)  and a.bindtime between '2012-03-01' and '2012-03-23 23:59:59' group by gDate order by gDate;
+----+--------------------+---------------------------+-------+---------------+------------+---------+------------+-------+----------------------------------------------+
| id | select_type        | table                     | type  | possible_keys | key        | key_len | ref        | rows  | Extra                                        |
+----+--------------------+---------------------------+-------+---------------+------------+---------+------------+-------+----------------------------------------------+
|  1 | PRIMARY            | a                         | range | search_key    | search_key | 8       | NULL       |   394 | Using where; Using temporary; Using filesort | 
|  1 | PRIMARY            | b                         | ALL   | NULL          | NULL       | NULL    | NULL       | 17944 | Using where; Not exists                      | 
|  2 | DEPENDENT SUBQUERY | business_installedAP_info | ref   | search_key    | search_key | 306     | const,func |     1 | Using index                                  | 
+----+--------------------+---------------------------+-------+---------------+------------+---------+------------+-------+----------------------------------------------+
3 rows in set (0.00 sec)
mysql> select sql_no_cache count(distinct(a.mpnumber)) as mpnumber, date_format(a.bindtime,'%Y-%m-%d') as gDate from new_bind_mp_weibo_user_info_0 a left join weibo_user_visit_info_0 b on a.mpnumber=b.mpnumber  and a.apmac=b.apmac   where b.id is NULL and a.apmac in (select ap_mac from newwifi.business_installedAP_info where businessid=100064)  and a.bindtime between '2012-03-01' and '2012-03-23 23:59:59' group by gDate order by gDate;
+----------+------------+
| mpnumber | gDate      |
+----------+------------+
|        4 | 2012-03-01 | 
|       10 | 2012-03-02 | 
|        3 | 2012-03-03 | 
|       10 | 2012-03-04 | 
|       12 | 2012-03-05 | 
|       10 | 2012-03-08 | 
|        4 | 2012-03-09 | 
|       14 | 2012-03-12 | 
|       14 | 2012-03-13 | 
|        7 | 2012-03-14 | 
|       12 | 2012-03-15 | 
|        8 | 2012-03-16 | 
|        7 | 2012-03-17 | 
|       11 | 2012-03-18 | 
|       11 | 2012-03-19 | 
|        8 | 2012-03-20 | 
|        8 | 2012-03-21 | 
|        9 | 2012-03-22 | 
+----------+------------+
18 rows in set (1.72 sec)

Read more…

在mysql中获取insert插入数据的id的方法

我们在写数据库程序的时候,经常会需要获取某个表中的最大序号数,或者刚插入的数据的ID值。
一般情况下获取刚插入的数据的id,使用select max(id) from table 是可以的。
但在多线程,高并发的情况下,就不行了。
开始的时候我想的是使用mysql_insert_id(),不知道会不会在并发的时候产生影响,查询了下手册,也是才发现,是根据connection来的,不同用户间不会产生影响。所以也不用去想先把表锁起来,插入取得ID值后再解锁。直接正常插入,然后取值,即可。

int mysql_insert_id ([ resource $link_identifier ] )

mysql_insert_id()返回给定的 link_identifier中上一步 INSERT 查询中产生的 AUTO_INCREMENT 的 ID 号。如果没有指定 link_identifier,则使用上一个打开的连接。

如果上一查询没有产生 AUTO_INCREMENT 的值,则 mysql_insert_id()返回 0。如果需要保存该值以后使用,要确保在产生了值的查询之后立即调用 mysql_insert_id()。
warning: mysql_insert_id() 将 MySQL 内部的 C API 函数 mysql_insert_id()的返回值转换成 long(PHP 中命名为 int)。如果 AUTO_INCREMENT 的列的类型是 BIGINT,则 mysql_insert_id()返回的值将不正确。可以在 SQL 查询中用 MySQL 内部的 SQL 函数 LAST_INSERT_ID() 来替代。

此外,还可以通过QUERY两个SQL语句来执行:

--1 ,查询 LAST_INSERT_ID()
mysql> select LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
|                4 | 
+------------------+
1 row in set (0.00 sec)

--2 查询 @@IDENTITY
mysql> select @@IDENTITY;
+------------+
| @@IDENTITY |
+------------+
|          4 | 
+------------+
1 row in set (0.00 sec)

Read more…

Mysql中,int(10)和int(11)有什么区别?

首先说一下mysql的数值类型,MySQL支持所有标准SQL数值数据类型。这些类型包括严格数值数据类型(INTEGER、SMALLINT、DECIMAL和NUMERIC),以及近似数值数据类型(FLOAT、REAL和DOUBLE PRECISION)。关键字INT是INTEGER的同义词,关键字DEC是DECIMAL的同义词。

BIT数据类型保存位字段值,并且支持MyISAM、MEMORY、InnoDB和BDB表。

作为SQL标准的扩展,MySQL也支持整数类型TINYINT、MEDIUMINT和BIGINT。下面的表显示了需要的每个整数类型的存储和范围。

类型 字节 最小值 最大值
(带符号的/无符号的) (带符号的/无符号的)
TINYINT 1 -128 127
0 255
SMALLINT 2 -32768 32767
0 65535
MEDIUMINT 3 -8388608 8388607
0 16777215
INT 4 -2147483648 2147483647
0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
0 18446744073709551615

Mysql类型关键字后面的括号内指定整数值的显示宽度(例如,INT(4))。该可选显示宽度规定用于显示宽度小于指定的列宽度的值时从左侧填满宽度。显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。

当结合可选扩展属性ZEROFILL使用时, 默认补充的空格用零代替。例如,对于声明为INT(5) ZEROFILL的列,值4检索为00004。请注意如果在整数列保存超过显示宽度的一个值,当MySQL为复杂联接生成临时表时会遇到问题,因为在这些情况下MySQL相信数据适合原列宽度。

所有整数类型可以有一个可选(非标准)属性UNSIGNED。当你想要在列内只允许非负数和该列需要较大的上限数值范围时可以使用无符号值。

所以int(10)与int(11)后的括号中的字符表示显示宽度,整数列的显示宽度与mysql需要用多少个字符来显示该列数值,与该整数需要的存储空间的大小都没有关系,int类型的字段能存储的数据上限还是2147483647(有符号型)和4294967295(无符号型)。

Read more…