Jiliuke

激流客

这篇文章主要介绍了PHP二维数组排序的3种方法和自定义函数分享,需要的朋友可以参考下

关于排序一般我们都是通过数据库或者nosql(eg:redis)先排好序然后输出到程序里直接使用,但是有些时候我们需要通过PHP直接来对数组进行排序,而在PHP里存储数据用到最多的就是对象和数组,但处理较多的就是数组,因为有非常丰富的内置函数库(其实对象一定程度上也可以理解为是数组),这些函数库很大程度上可以帮助我们实现某些功能。常用的系统函数有sort、asort、arsort、ksort、krsort等等,这里我主要说下对二维数组的排序,两种方法: 一、用PHP自带array_multisort函数排序

复制代码代码如下:

67, 'edition' => 2); $data\[\] = array('volume' => 86, 'edition' => 1); $data\[\] = array('volume' => 85, 'edition' => 6); $data\[\] = array('volume' => 98, 'edition' => 2); $data\[\] = array('volume' => 86, 'edition' => 6); $data\[\] = array('volume' => 67, 'edition' => 7); // 取得列的列表 foreach ($data as $key => $row) { $volume\[$key\]  = $row\['volume'\]; $edition\[$key\] = $row\['edition'\]; } array\_multisort($volume, SORT\_DESC, $edition, SORT\_ASC, $data); print\_r($data); ?>

输出结果:

复制代码代码如下:

Array ( [0] => Array ( [volume] => 98 [edition] => 2 ) [1] => Array ( [volume] => 86 [edition] => 1 ) [2] => Array ( [volume] => 86 [edition] => 6 ) [3] => Array ( [volume] => 85 [edition] => 6 ) [4] => Array ( [volume] => 67 [edition] => 2 ) [5] => Array ( [volume] => 67 [edition] => 7 ) )

关于array_multisort官方文档也有比较详细的说明:http://www.php.net/manual/zh/function.array-multisort.php 二、自定义函数排序1

复制代码代码如下:

67, 'edition' => 2); $data\[\] = array('volume' => 86, 'edition' => 1); $data\[\] = array('volume' => 85, 'edition' => 6); $data\[\] = array('volume' => 98, 'edition' => 2); $data\[\] = array('volume' => 86, 'edition' => 6); $data\[\] = array('volume' => 67, 'edition' => 7);    // 取得列的列表 foreach ($data as $key => $row) { $volume\[$key\]  = $row\['volume'\]; $edition\[$key\] = $row\['edition'\]; } $ret = arraySort($data, 'volume', 'desc'); print\_r($ret); /** * @desc arraySort php二维数组排序 按照指定的key 对数组进行排序 * @param array $arr 将要排序的数组 * @param string $keys 指定排序的key * @param string $type 排序类型 asc | desc * @return array */ function arraySort($arr, $keys, $type = 'asc') { $keysvalue = $new\_array = array(); foreach ($arr as $k => $v){ $keysvalue\[$k\] = $v\[$keys\]; } $type == 'asc' ? asort($keysvalue) : arsort($keysvalue); reset($keysvalue); foreach ($keysvalue as $k => $v) { $new\_array\[$k\] = $arr\[$k\]; } return $new\_array; } ?>

输出结果:

复制代码代码如下:

Array ( [3] => Array ( [volume] => 98 [edition] => 2 )    [4] => Array ( [volume] => 86 [edition] => 6 ) [1] => Array ( [volume] => 86 [edition] => 1 ) [2] => Array ( [volume] => 85 [edition] => 6 ) [5] => Array ( [volume] => 67 [edition] => 7 ) [0] => Array ( [volume] => 67 [edition] => 2 ) )

这个自定义函数与系统函数的一个区别就是:自定义函数只支持针对某一个key的排序,如果要支持多个key的排序需要执行多次; 而系统函数array_multisort可以一次性对多个key且可以指定多个排序规则,系统函数还是相当强大的,推荐使用系统函数,毕竟是C底层实现的,这里只是举例说明如果通过自定义函数来对数组进行排序,当然这个自定义函数也可以继续扩展来支持更多的排序规则。在取排名、排行榜、成绩等场景中用到的还是非常多的。 三、自定义函数排序2 以下函数是对一个给定的二维数组按照指定的键值进行排序,先看函数定义:

复制代码代码如下:

function array_sort($arr,$keys,$type=’asc’){ $keysvalue = $new_array = array(); foreach ($arr as $k=>$v){ $keysvalue[$k] = $v[$keys]; } if($type == ‘asc’){ asort($keysvalue); }else{ arsort($keysvalue); } reset($keysvalue); foreach ($keysvalue as $k=>$v){ $new_array[$k] = $arr[$k]; } return $new_array; }

它可以对二维数组按照指定的键值进行排序,也可以指定升序或降序排序法(默认为升序),用法示例:

复制代码代码如下:

$array = array( array(‘name’=>’手机’,’brand’=>’诺基亚’,’price’=>1050), array(‘name’=>’笔记本电脑’,’brand’=>’lenovo’,’price’=>4300), array(‘name’=>’剃须刀’,’brand’=>’飞利浦’,’price’=>3100), array(‘name’=>’跑步机’,’brand’=>’三和松石’,’price’=>4900), array(‘name’=>’手表’,’brand’=>’卡西欧’,’price’=>960), array(‘name’=>’液晶电视’,’brand’=>’索尼’,’price’=>6299), array(‘name’=>’激光打印机’,’brand’=>’惠普’,’price’=>1200) );$ShoppingList = array_sort($array,’price’); print_r($ShoppingList);

上面是对$array这个二维数组按照’price’从低到高的排序。

安装crontab: yum install crontabs  说明: /sbin/service crond start //启动服务 /sbin/service crond stop //关闭服务 /sbin/service crond restart //重启服务 /sbin/service crond reload //重新载入配置  查看crontab服务状态: service crond status  手动启动crontab服务: service crond start  查看crontab服务是否已设置为开机启动,执行命令: ntsysv  加入开机自动启动: chkconfig --level 35 crond on 1,crontab命令 功能说明:设置计时器。 语  法:crontab [-u <用户名称>][配置文件] 或 crontab [-u <用户名称>][-elr] 补充说明:cron是一个常驻服务,它提供计时器的功能,让用户在特定的时间得以执行预设的指令或程序。只要用户会编辑计时器的配置文件,就可以使 用计时器的功能。其配置文件格式如下: Minute Hour Day Month DayOFWeek Command 参  数: -e  编辑该用户的计时器设置。 -l  列出该用户的计时器设置。 -r  删除该用户的计时器设置。 -u<用户名称>  指定要设定计时器的用户名称。 2,crontab 格式 基本格式 : * *  *  *  *  command 分 时 日 月 周  命令 第1列表示分钟1~59 每分钟用或者 */1表示 第2列表示小时1~23(0表示0点) 第3列表示日期1~31 第4列 表示月份1~12 第5列标识号星期0~6(0表示星期天) 第6列要运行的命令 *crontab特殊的符号说明:** ““代表所有的取值范围内的数字。特别要注意哦! “/“代表每的意思,如”/5”表示每5个单位 “-“代表从某个数字到某个数字 “,”分散的数字 crontab文件的一些例子: 30 21 * * * /usr/local/etc/rc.d/lighttpd restart  上面的例子表示每晚的21:30重启 apache。   45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart  上面的例子表示每月1、 10、22日的4 : 45重启apache。   10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart  上面的例子表示每周六、周日的1 : 10重启apache。   0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart  上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。   0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart  上面的例子表示每星期六的11 : 00 pm重启apache。   * */1 * * * /usr/local/etc/rc.d/lighttpd restart  每一小时重启apache   * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart  晚上11点到早上7点之间,每 隔一小时重启apache   0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart  每月的4号与每周一到周三 的11点重启apache   0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart  一月一号的4点重启apache   */30 * * * * /usr/sbin/ntpdate 210.72.145.44  每半小时同步一下时间   -------------------------------- 如何查看crontab的日志记录 ——————————————————– 昨天crontab中的同步任务没有执行,不知道是什么原因没有执行,貌似任务hang住了,想查询一下crontab到底问题出在哪里,或者hang在了什么地方。 1.  linux 看 /var/log/cron这个文件就可以,可以用tail -f /var/log/cron观察 2.  unix 在 /var/spool/cron/tmp文件中,有croutXXX001864的tmp文件,tail 这些文件就可以看到正在执行的任务了。 3. mail任务 在 /var/spool/mail/root 文件中,有crontab执行日志的记录,用tail -f /var/spool/mail/root 即可查看最近的crontab执行情况。

一、环境介绍: 服务器:centos 192.168.1.225 客户端:centos 192.168.1.226 二、安装: NFS的安装配置: centos 5 :

yum -y install nfs-utils portmap

centos 6(在CentOS 6.3当中,portmap服务由rpcbind负责) :

yum -y install nfs-utils rpcbind

三、服务器端配置: 1、创建共享目录:

[root@centos2 /]# mkdir /usr/local/test

2、NFS文件配置:

[root@centos2 /]# vi /etc/exports
#增加一行:
/usr/local/test/ 192.168.1.226(rw,no_root_squash,no_all_squash,sync)

:x保存退出; 使配置生效:

[root@centos2 /]# exportfs -r

注:配置文件说明: /usr/local/test/ 为共享的目录,使用绝对路径。 192.168.1.226(rw,no_root_squash,no_all_squash,sync) 为客户端的地址及权限,地址可以是一个网段,一个IP地址或者是一个域名,域名支持通配符,如:*.youxia.com,地址与权限中间没有空格,权限说明: rw:read-write,可读写; ro:read-only,只读; sync:文件同时写入硬盘和内存; async:文件暂存于内存,而不是直接写入内存; no_root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,也拥有root权限。显然开启这项是不安全的。 root_squash:NFS客户端连接服务端时如果使用的是root的话,那么对服务端分享的目录来说,拥有匿名用户权限,通常他将使用nobody或nfsnobody身份; all_squash:不论NFS客户端连接服务端时使用什么用户,对服务端分享的目录来说都是拥有匿名用户权限; anonuid:匿名用户的UID值,通常是nobody或nfsnobody,可以在此处自行设定; anongid:匿名用户的GID值。 3、启动: centos6: [root@centos2 /]# service rpcbind start

Starting rpcbind: [ OK ]
[root@centos2 /]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS mountd: [ OK ]
Stopping RPC idmapd: [ OK ]
Starting RPC idmapd: [ OK ]
Starting NFS daemon: [ OK ]
[root@centos2 /]#

centos 5

[root@centos2 /]# service portmap start
[root@centos2 /]# service nfs start
[root@centos2 /]#

四、客户端挂载: 1、创建需要挂载的目录:

[root@localhost ~]# mkdir /usr/local/test
[root@localhost ~]#

2、测试挂载:

[root@localhost ~]# showmount -e 192.168.1.225
Export list for 192.168.1.225:
/usr/local/test 192.168.1.226
[root@localhost ~]#

如果显示:rpc mount export: RPC: Unable to receive; errno = No route to host,则需要在服务端关闭防火墙(稍候会详细说)。 3、挂载: [root@localhost ~]# mount -t nfs 192.168.1.225:/usr/local/test /usr/local/test

[root@localhost ~]# mount
/dev/mapper/VolGroup-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
192.168.1.225:/usr/local/test on /usr/local/test type nfs (rw,vers=4,addr=192.168.1.225,clientaddr=192.168.1.226)
[root@localhost ~]#

如果信息如上显示则挂载成功! 4、测试: 客户端生成一个文件:

[root@centos2 /]# cd /usr/local/test/
[root@centos2 test]# echo “hello nfs test”>>test
[root@centos2 test]# ll
total 4
-rw-r–r– 1 root root 15 Apr 9 13:24 test
[root@centos2 test]#

服务端检查:

[root@centos2 /]# cd /usr/local/test/
[root@centos2 test]# ll
total 4
-rw-r–r– 1 root root 15 Apr 9 13:24 test
[root@centos2 test]#

挂载成功! 五、解除挂载: [root@localhost ~]# umount /usr/local/test

[root@localhost ~]# mount
/dev/mapper/VolGroup-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
[root@localhost ~]#

如果遇到:umount.nfs: /usr/local/test: device is busy 可能用命令: [root@localhost /]# fuser -m -v /usr/local/test

                 用户     进程号 权限   命令

/usr/local/test/: root 2798 ..c.. bash
root 2996 ..c.. su
[root@localhost /]# kill -9 2798

[root@localhost /]# kill -9 2996

[root@localhost /]# umount /usr/local/test
[root@localhost /]#

六、服务器端防火墙设置(NFS 开启防墙配置): 1、修改/etc/service,添加以下内容(端口号必须在1024以下,且未被占用) # Local services mountd 1011/tcp #rpc.mountd mountd 1011/udp #rpc.mountd rquotad 1012/tcp #rpc.rquotad rquotad 1012/udp #rpc.rquotad 2、重起Linux NFS服务 service nfs restart 3、此时rpc相关端口已经被固定,可以为Linux NFS添加防火墙规则 #portmap /sbin/iptables -A INPUT -s 192.168.1.0/254 -p tcp –dport 111 -j ACCEPT /sbin/iptables -A INPUT -s 192.168.1.0/254 -p udp –dport 111 -j ACCEPT #nfsd /sbin/iptables -A INPUT -s 192.168.1.0/254 -p tcp –dport 2049 -j ACCEPT /sbin/iptables -A INPUT -s 192.168.1.0/254 -p udp –dport 2049 -j ACCEPT #mountd /sbin/iptables -A INPUT -s 192.168.1.0/254 -p tcp –dport 1011 -j ACCEPT /sbin/iptables -A INPUT -s 192.168.1.0/254 -p udp –dport 1011 -j ACCEPT #rquotad /sbin/iptables -A INPUT -s 192.168.1.0/254 -p tcp –dport 1012 -j ACCEPT /sbin/iptables -A INPUT -s 192.168.1.0/254 -p udp –dport 1012 -j ACCEPT #rpc.statd /sbin/iptables -A INPUT -s 192.168.1.0/254 -p tcp –dport 32768 -j ACCEPT /sbin/iptables -A INPUT -s 192.168.1.0/254 -p udp –dport 32768 -j ACCEPT —TCP方法成功——————————————- -A INPUT -m state –state NEW -m tcp -p tcp –dport 111 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 2049 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 1011 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 1012 -j ACCEPT -A INPUT -m state –state NEW -m tcp -p tcp –dport 32768 -j ACCEPT 客户端在挂载的时候遇到的一个问题如下,可能是网络不太稳定,NFS默认是用UDP协议,换成TCP协议即可: mount -t nfs 192.168.1.225:/usr/local/test /usr/local/test  -o proto=tcp -o nolock /etc/init.d/iptables restart #最后重启防火墙使配置生效 防火墙端口说明: portmap或者rpcbind(CentOS 6.x)使用:tcp/udp 111 nfs使用:tcp/udp 2049 mountd使用: TCP/UDP 892 rquotad使用:tcp/udp 875 status使用: TCP/UDP 1001-1004共四个端口 nlockmgr使用:TCP/32803端口 UDP/32769端口 rpcinfo -p 查看rpcbind使用的端口号

-----------------------开启php-fpm慢脚本日志 request_slowlog_timeout = 30s slowlog = /usr/local/php/var/log/php-fpm.log.slow 典型的日志内容如下: [15-Apr-2012 20:56:19] [pool www] pid 9748 script_filename = /var/www/html/htdocs/www.xxx.com/xxx.php [0x00000000090bc270] file_get_contents() /var/www/html/htdocs/www.xxx.com/xxx.php:81 慢脚本文件、具体行数、函数等都很详细的记录了,优化工作相对来说就容易的多。 request_terminate_timeout = 120 #表示等待120秒后,结束那些没有自动结束的php脚本,以释放占用的资源。 当PHP运行在php-fpm模式下,php.ini配置的max_execute_time是无效的,需要在php-fpm.conf中配置另外一个配置项:request_terminate_timeout;以下是官方文档的说明: request_terminate_timeout – The timeout (in seconds) for serving a single request after which the worker process will be terminated. Should be used when ‘max_execution_time’ ini option does not stop script execution for some reason. Default: “5s”. Note: ’0s’ means ‘off’ 注意:set_time_limit()和max_execution_time只影响脚本本身执行的时间。任何发生在诸如使用system()的系统调用,流操作,数据库操作等的脚本执行的最大时间不包括其中. [global] pid = /dev/shm/pid/php-fpm.pid error_log = /usr/local/php/var/log/php-fpm.log log_level = notice [www] listen = 127.0.0.1:9000 ;listen.allowed_clients = 192.168.1.17,127.0.0.1,192.168.1.75 user = www group = www pm = dynamic pm.max_children = 2000 pm.start_servers = 10 pm.min_spare_servers = 5 pm.max_spare_servers = 200 pm.max_requests = 12000 pm.process_idle_timeout = 10s request_terminate_timeout = 120 request_slowlog_timeout = 30s slowlog = /usr/local/php/var/log/php-fpm.log.slow 这里先说一下涉及到这个的几个参数,他们分别是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。 pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。 下面4个参数的意思分别为: pm.max_children:静态方式下开启的php-fpm进程数量。 pm.start_servers:动态方式下的起始php-fpm进程数量。 pm.min_spare_servers:动态方式下的最小php-fpm进程数量。 pm.max_spare_servers:动态方式下的最大php-fpm进程数量。 如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。 如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。 系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程, 然后根据系统的需求动态在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。 那么,对于我们的服务器,选择哪种执行方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。 这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。 对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效 率。 因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100, 那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。 这样可以保证php-fpm只获取够用的内存,将不多的 内存分配给其他应用去使用,会使系统的运行更加畅通。 对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩 溃就应该很正常了。 因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者使用动态方式, 因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。 比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服 务器的负载情况来设置,比较合适的值在5~10之间。 ============================= 127.0.0.1监听本机ip php-fpm.conf listen = 127.0.0.1:9000 nginx.conf location ~ ^(.+\.php)(.*)$ { fastcgi_pass   127.0.0.1:9000; fastcgi_index  index.php; include fcgi.conf; }

使用SDK Manager更新时出现问题Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xml, reason: Connection to https://dl-ssl.google.com refusedFailed to fetch URL http://dl-ssl.google.com/android/repository/addons\_list-1.xml, reason: Connection to http://dl-ssl.google.com refusedFailed to fetch URL https://dl-ssl.google.com/android/repository/addons\_list-1.xml, reason: hostname in certificate didn’t match: <dl-ssl.google.com> != <www.google.com>更新ADT时无法解析https://dl-ssl.google.com/android/eclipse

Android SDK更新以及ADT更新出现问题的解决办法3

方法/步骤

  1. 大家肯定很急,我就不废话了,直接上解决办法了! 打开SDK Manager下Tools->Options,选中“Force https://… sources to be fetched using http://…”,强制使用http协议。 Android SDK更新以及ADT更新出现问题的解决办法45
  2. 上一步选取之后,有的用户可以更新出列表来。如果还是不能,继续下面的操作。 在地址栏里输入:C:\WINDOWS\system32\drivers\etc Android SDK更新以及ADT更新出现问题的解决办法6
  3. 我们会看到hosts文件,右击打开方式选择记事本。在里面把下面文字复制进去,内容如下(_特别强调:是在原本的内容后面粘贴下面的内容,而不是覆盖_): #Google主页 203.208.46.146 www.google.com #这行是为了方便打开Android开发官网 现在好像不VPN也可以打开 74.125.113.121 developer.android.com #更新的内容从以下地址下载 203.208.46.146 dl.google.com 203.208.46.146 dl-ssl.google.com Android SDK更新以及ADT更新出现问题的解决办法7
  4. 有的用户接着就会看到加载出列表了。如果没有变化,重新打开SDK Manager。就会发现问题解决了。如图1 如果还是无法加载出列表,还是出现如图2红色内容,建议过几天再试试! Android SDK更新以及ADT更新出现问题的解决办法8 Android SDK更新以及ADT更新出现问题的解决办法9
  5. 5 更新ADT插件的时候则使用网址http://dl-ssl.google.com/android/eclipse,而不是https://dl-ssl.google.com/android/eclipse,这个在官方开发文档里也有介绍。

做Android开发的朋友最近会发现,更新ADT至22.6.0版本之后,创建新的安装项目,会出现appcompat_v7的内容。并且是创建一个新的内容就会出现。这到底是怎么回事呢?原来appcompat_v7是Google自己的一个兼容包,就是一个支持库,能让2.1以上全使用上4.0版本的界面。下面就让笔者带你慢慢走近这个问题并解决它。 你会发现项目创建好后,workspace栏里除了我们创建的“test”项目,还多了一个名为“appcompat_v7”的包,而且这个包显示有错误(红色x号),而“test”包显示一个红色的感叹号。 解决办法:如果你依旧对appcompat_v7包耿耿于怀,我告诉你一个建项目时不出现appcompat_v7包的方法。既然appcompat_v7包是一个能让2.1以上全使用上4.0版本的界面的支持库,那么如图所示,我们建项目时直接把最小SDK选在Android4.0以上不就不需要这个支持库了吗?结果证明我们的想法是对的。

作者: Laruence 本文地址: http://www.laruence.com/2013/03/26/2884.html 转载请注明出处

关于PHP的浮点数, 我之前写过一篇文章: 关于PHP浮点数你应该知道的(All ‘bogus’ about the float in PHP) 不过, 我当时遗漏了一点, 也就是对于如下的这个常见问题的回答:

  1.     $f=0.58;
  2.     var_dump(intval($f*100));//为啥输出57
  3. ?>

为啥输出是57啊? PHP的bug么? 我相信有很多的同学有过这样的疑问, 因为光问我类似问题的人就很多, 更不用说bugs.php.net上经常有人问… 要搞明白这个原因, 首先我们要知道浮点数的表示(IEEE 754): 浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位). 符号位:最高位表示数据的正负,0表示正数,1表示负数。 指数位:表示数据以2为底的幂,指数采用偏移码表示 尾数:表示数据小数点后的有效数字. 这里的关键点就在于, 小数在二进制的表示, 关于小数如何用二进制表示, 大家可以百度一下, 我这里就不再赘述, 我们关键的要了解, 0.58 对于二进制表示来说, 是无限长的值(下面的数字省掉了隐含的1)..

  1. 0.58的二进制表示基本上(52位)是: 0010100011110101110000101000111101011100001010001111
  2. 0.57的二进制表示基本上(52位)是: 0010001111010111000010100011110101110000101000111101

而两者的二进制, 如果只是通过这52位计算的话,分别是:

  1. 0.58 -> 0.57999999999999996
  2. 0.57 -> 0.56999999999999995

至于0.58 * 100的具体浮点数乘法, 我们不考虑那么细, 有兴趣的可以看(Floating point), 我们就模糊的以心算来看… 0.58 * 100 = 57.999999999 那你intval一下, 自然就是57了…. 可见, 这个问题的关键点就是: “你看似有穷的小数, 在计算机的二进制表示里却是无穷的” so, 不要再以为这是PHP的bug了, 这就是这样的…..

第一步:编写manifest.json

{

  “name”: “Back To Top”,

  “description”: “返回顶部”,

  “version”: “0.1”,

  “content_scripts”: [   //在内容中加载js

    {

      “matches”: [“http:///“],   //匹配页面,哪些页面需要显示

      “js”: [“top.js”]   //加载的js

    }

  ],

  “manifest_version”: 2,

  “default_icon”: “icon_128.png”,  //设置默认图片

  “icons”: { “128”: “icon_128.png” }  //图标

}

第二部:添加返回顶部的纯js

(function() {

    var btnId = ‘__gotop’;

    var isIE = !!window.ActiveXObject && /msie (\d)/i.test(navigator.userAgent) ? RegExp[‘$1’] : false;

    function $() {

        return document.getElementById(arguments[0]);

    }

    function getScrollTop() {

        return (‘pageYOffset’ in window) ? window.pageYOffset

            : document.compatMode === “BackCompat”

            && document.body.scrollTop

            || document.documentElement.scrollTop ;

    }

    function bindEvent(event, func) {

        if (window.addEventListener) {

            window.addEventListener(event, func, false);

        } else if (window.attachEvent) {

            window.attachEvent(‘on’ + event, func);

        }

    }

    bindEvent(‘load’,

        function() {

            var css = ‘background-color:#999;width:50px;height:50px;position:fixed;right:100px;bottom:30px;border-radius:10px;cursor:pointer;display:none;’;

            if (isIE && isIE < 7) {

                css += ‘_position:absolute;_top:expression(eval(document.documentElement.scrollTop+document.documentElement.clientHeight-30-this.offsetHeight-(parseInt(this.currentStyle.marginTop,10)||0)-(parseInt(this.currentStyle.marginBottom,10)||0)))’;

                var style = document.createStyleSheet();

                style.cssText = ‘*html{background-image:url(about:blank);background-attachment:fixed;}’;

            }

            var html = ‘

‘;

            var el = document.createElement(‘DIV’);

            el.id = btnId;

            el.style.cssText = css;

            el.innerHTML = html;

            document.body.appendChild(el);

            el.onclick = function() {

                (function() {

                    var top = getScrollTop();

                    if (top > 0) {

                        window.scrollTo(0, top / 1.2)

                        setTimeout(arguments.callee, 10);

                    }

                })();

            };

            el.onmouseover = function() {

                $(btnId).firstChild.style.borderBottom = ‘14px solid #ddd’;

                $(btnId).firstChild.firstChild.style.backgroundColor = ‘#ddd’;

            };

            el.onmouseout = function() {

                $(btnId).firstChild.style.borderBottom = ‘14px solid #fff’;

                $(btnId).firstChild.firstChild.style.backgroundColor = ‘#fff’;

            };

        }

    );

    bindEvent(‘scroll’,

        function() {

            var top = getScrollTop(), display = ‘none’;

            if (top > 0) {

                display = ‘block’;

            }

            $(btnId).style.display = display;

        });

})();

第三步:打包上传

Lamp环境下编写PHP代码时出现错误:Warning: Unknown: failed to open stream: Permission denied in Unknown on line 0 Fatal error: Unknown: Failed opening required ‘X’ (include_path=’X’) in Unknown on line 时的解决办法。 在出现此问题时,是文件权限出了问题,可以通过以下两中方法进行解决: 一、在图形界面直接更改权限 右键点击文件选择权限,然后直接更改,如图: 1 更改完权限之后为: 2 更改完之后就应该为什么问题了。 二、通过命令行直接进行权限的更改 直接将文件的权限更改为777 例如:文件为a.php 则进入所在的文件夹,通过命令chmod 777 a.php 更改权限。 具体777是什么意思,大家看看书或上网搜一下,在这里就不再赘述啦!

Configure: 项目安装: 比如用源码包安装gaim 的 ./configure –prefix=/opt/gaim make make install 如果安装mlterm ./configure –prefix=/opt/mlterm make make install 把源码包安装的软件,都指定安装在 /opt目录中 项目删除: 如果删除,就删除相应的软件目录; 有些软件要在解压安装目录中执行 make uninstall 这样就卸载掉了 CMake: 项目安装: 1、首先安装CMake工具 wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz tar xvzf cmake-2.8.4.tar.gz cd cmake-2.8.4 ./configure make make install 以安装MySQL 5.5.9为例,执行: tar zxvf mysql-5.5.9.tar.gz cd mysql-5.5.9/ rm CMakeCache.txt cmake -DCMAKE_INSTALL_PREFIX=/usr/local/webserver/mysql/-DMYSQL_DATADIR=/home/mysql/data/-DEFAULT_CHARSET=utf8 -DMYSQL_TCP_PORT=3306-DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DWITH_DEBUG=0-DWITH_INNOBASE_STORAGE_ENGINE=1-DMYSQL_USER=mysql 这些参数的意思: -DCMAKE_INSTALL_PREFIX=/data/mysql 准备安装到那里 -DEFAULT_CHARSET=utf8 默认的字符集 -DMYSQL_TCP_PORT=3306 数据库的监听端口 -DMYSQL_UNIX_ADDR=/tmp/mysql3306.sock 本机连回数据库的unix socket -DWITH_DEBUG=0 关闭debug模式 -DWITH_INNOBASE_STORAGE_ENGINE=1 打开innodb引擎 make && make install 项目删除: CMake 默认不提供 uninstall 这个 target,想要的话,输入: xargs rm < install_manifest.txt 对于不修改配置的项目足够了,manifest.txt 是CMake 生成的安装文件列表。

0%