php函数mult_iconv:转换任意维数组的字符集编码(扩展iconv函数功能)

php的iconv函数只支持对字符串的转换编码,如果是数组,就要自己遍历转换了,因此写如上的函数,对任意维数组进行转换,同时转换下标(索引)及值。

注意:不转对象。

function mult_iconv($in_charset,$out_charset,$data)
{
    if(substr($out_charset,-8)=='//IGNORE'){
        $out_charset=substr($out_charset,0,-8);
    }
    if(is_array($data)){
        foreach($data as $key => $value){
            if(is_array($value)){
                $key=iconv($in_charset,$out_charset.'//IGNORE',$key);
                $rtn[$key]=mult_iconv($in_charset,$out_charset,$value);
            }elseif(is_string($key) || is_string($value)){
                if(is_string($key)){
                    $key=iconv($in_charset,$out_charset.'//IGNORE',$key);
                }
                if(is_string($value)){
                    $value=iconv($in_charset,$out_charset.'//IGNORE',$value);
                }
                $rtn[$key]=$value;
            }else{
                $rtn[$key]=$value;
            }
        }
    }elseif(is_string($data)){
        $rtn=iconv($in_charset,$out_charset.'//IGNORE',$data);
    }else{
        $rtn=$data;
    }
    return $rtn;
}

下载程序文件(含示例)

调用示例:

$foobar=mult_iconv('gbk','utf-8','一个数组、字符串或其它类型数据');

一个复杂一点的测试示例(不转对象)

// ******* 一个复杂一点的测试示例 ********************
class MyClass
{
    public $v1='不转对象,恭喜发财';
    public $v2='skipped object';
    public function f()
    {
        return true;
    }
}
$obj=new MyClass();

$foo=array('abcd','随便写点文字'
    ,array('中文下标'=> 789,'天地玄黄'
        =>array('宇宙洪荒'=>'赵钱孙李',300=>'恭喜发财,不转对象'
                    ,array('更深的数组'=>'照样可以转换')
                )
    )
    ,'恭喜发财,不转对象' => $obj
    ,'如需转对象'=>'Do It Yourself!'
    ,'作者很懒'=>'用不到就不写了'
    );
$bar=mult_iconv('gbk','utf-8//IGNORE',$foo);
var_dump($bar);

Microsoft SQL server性能优化必备工具

这里说的工具并不一定是独立软件

1 查看sql语句执行花费的时间、IO开销

在mssql客户端执行sql语句时,先在当前会话里执行下面语句

SET STATISTICS IO ON
SET STATISTICS TIME ON
也可一次性执行
set statistics io,time on

然后再执行sql语句,运行完成的消息框里将给出如下统计信息

SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。

SQL Server 执行时间:
   CPU 时间 = 0 毫秒,占用时间 = 1 毫秒。
SQL Server 分析和编译时间: 
   CPU 时间 = 0 毫秒,占用时间 = 4 毫秒。

(100 行受影响)
表 'your_table'。扫描计数 2,逻辑读取 165 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。

http://msdn.microsoft.com/zh-cn/library/ms190356.aspx

mysql对大表执行update速度慢时,试试改用insert可能会有意想不到的发现

实例:需要根据用户日志的ip地址计算出其地理地址

表结构:

用户日志表(200万条记录),其中address是待填充的字段:

CREATE TABLE `tmp_open_ip` (
  `email` varchar(60) NOT NULL DEFAULT '',
  `address` varchar(50) NOT NULL DEFAULT '',
  `ip` int(10) unsigned NOT NULL DEFAULT '0',
  KEY `email` (`email`),
  KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

另ip地址数据库表(44万条记录)

CREATE TABLE `ip` (
`s` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '开始ip',
`e` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '结束ip',
`a` varchar(50) NOT NULL DEFAULT '',
KEY `s` (`s`),
KEY `e` (`e`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8

需要根据用户日志表 tmp_open_ip 里的 ip字段到ip地址数据库表里查询出对应的地理地址,将地址填充到address字段。

使用如下update语句执行:

UPDATE tmp_open_ip AS u 
INNER JOIN ip 
ON u.ip BETWEEN ip.s AND ip.e 
SET u.address = ip.a

在笔者的电脑上运行了速度非常之慢,执行了一个多小时(4500s)都没有完,也不知道还要多久。

实在看不过去,于是想到使用insert 是否会快一些,于是重新导一张表 tmp_open_log 与tmp_open_log完全一致。

创建一张表 tmp_open_address,是insert的目标表,为了速度更快,没建索引:

CREATE TABLE `tmp_open_address` (
`email` varchar(60) NOT NULL DEFAULT '',
`address` varchar(50) NOT NULL DEFAULT '',
`ip` int(10) unsigned NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8

执行insert 语句

insert into tmp_open_address (email,address,ip)
select l.email,ip.a,l.ip
 from  tmp_open_log as l inner join ip on l.ip between ip.s and ip.e ;
/* Affected rows: 2,543,124  Found rows: 0  Warnings: 0  Duration for 3 queries: 16.922 sec. */

不到17s!本来还想去倒杯水、稍事休息一下,结果已经执行完毕。

到本文写完时,前面的update语句已经执行了5000s,结束仍是遥遥无期。

所以,对于大数据量执行update时,可以考虑改用insert 语句实现,可能麻烦一些,但高速带来的收益远大于麻烦!

后记:

直接杀死了update进程,去看看update执行了多少:运行

SELECT * FROM `tmp_open_ip` where address!=''

结果只有 11,373 ,照这个速度,要运行N天....

使用cygwin下的wget采集特殊的网页内容

需要采集一批数据,是一网站上的产品信息,产品本身信息很简单,使用火车采集器轻松实现;但产品价格数据是ajax响应数据,使用firebug + live http headers抓到该请求,并测试重发,发现该ajax请求必须带一个http头“X-Requested-With: XMLHttpRequest”,没有就返回404错误。

gnu/linux下有大量的杀手级工具,这种情况,要动用其中的wget. wget有很多参数,这里需要使用其中两个:-O,--header. 其中:

-O, 把请求结果保存到指定文件,但我们要使用的却是一个特殊的值:“-”,它可以将结果输出到标准输出

--header, 结http请求加上自定义的头(http header)

于是对于每条产品数据,都发送这样的请求:

wget --header="X-Requested-With: XMLHttpRequest" -O save_123.txt "http://www.website.com/request/path/?Id=123"

这样每条产品都保存到save_123.txt,save_124.txt,save_125.txt....这样的一系列文件中。不过有个问题是,每条数据一个文件,后期分析不方便。所以将其存储到单一的文件里。

方案:先将wget结果指向到标准输出,然后再使用重定向符 >> 定向到单一的文件里。

不过,还有一个问题,每个http响应里没有产品id号,数据跟采集到的产品信息对不上号。于是在每写一笔采集结果前,往文件里先写入该产品的id号。

这里使用echo 命令,要用到echo 的参数:-e, 作用是使用转义符输出换行。示例:echo -e "aaa\nbbb"

于是构造这样的bash脚本:

echo -e "\n"10011"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10011" >>data.log; 
echo -e "\n"10012"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10012" >>data.log; 
echo -e "\n"10013"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10013" >>data.log; sheep 1;
echo -e "\n"10014"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10014" >>data.log; 
echo -e "\n"10015"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10015" >>data.log; 
echo -e "\n"10016"\t"  >>data.log ;wget --header="X-Requested-With: XMLHttpRequest" -O- "http://www.website.com/request/path/?Id=10016" >>data.log; sheep 1;

第三行加一个sheep 1, 即每采三条暂停1秒钟,作用是防止请求过于密集而影响服务器响应,暂停秒数按实际情况设置。

所有数据都保存到data.log文件里,里面格式如下

10011    
{"data":.....}
10012    
{"data":.....}
10013    
{"data":.....}
10014    
{"data":.....}

每两行一笔数据,其中第一行是产品id号,第二行是采集到的数据。这样就可以方便的提取其中数据了。

其实,对于而需要提取的数据,完全可以通过grep从定向到标准输出的wget结果里提取。只是这里不么做了。

 

ms sql server 查看服务器当前的连接会话及会话信息(客户端ip地址,协议,时间,读写情况等)

ms sql server 查看服务器当前的连接会话及会话信息(客户端ip地址,协议,时间,读写情况等)

select * from sys.dm_exec_connections

这实际上是master数据库里的一个系统视图,读出来后有不少字段,如client_net_address, protoco_type, connect_time, num_read, num_write等,很明白,就不多说了。

btw,master数据库里有很多系统视图,如:dm_exec_sessions, dm_fts_memory_pools, dm_os_hosts, dm_os_memory_allocations, dm_os_memory_objects, dm_os_threads, sql_logins, types等,很有参考意义

一个使用tar实现对目录作增量备份的bash脚本

一个使用tar实现对目录作增量备份的bash脚本

#!/bin/bash
#program:
#  auto backup the folder $to_backup
#        to $save_to
#  History:
# 2012/11/28  yqf First release

# do NOT change the variable $filename
#  except you REALY know what you are doing exactly
filename=`date +%Y%m%d_%H%M%S`

# sample
# ##whitch folder you want to backup, full path (start with "/")
#to_backup="/var/www/html/foo"
# ##where you whant to save the backup files,folder, MUST end by "/"
#save_to="/var/www/backup/foo/"
# ##the incremental file, file name, full path
#incremental_file="/var/www/backup/incremental_file/foo.incre"
#
#tar -g $incremental_file \
# ## each files or folders that no need to backup, (ingore),
# ##    [Careful] without end slash even folder
#  -C $to_backup \
#  --exclude data/cache \
#  --exclude data/tmp \
#  -cpjf $save_to$filename.tar.bz2 .
# sample end
#
# mysite.com
to_backup="/var/www/html/mysite/html/"
save_to="/home/myhome/backup/mysite/"
incremental_file="/home/myhome/backup/incremenntal_list/mysite.increment_file"

tar -g $incremental_file \
  -C $to_backup \
  --exclude data/static_cache \
  --exclude data/templates_c \
  --exclude data/templates_cache \
  --exclude data/cache \
  -cpjf $save_to$filename.tar.bz2 .

下载脚本附件 tar_incremental_backup_sample
其中....似乎很简单,不用说什么了

grub-install安装grub时出错:/boot/grub/stage1 not read correctly.

在U盘上安装grub,之前是fat32的,格式化成exfat再安装grub,U盘设置文件为/dev/sdc4, 挂载于/media/c0f80392-62db-4156-a4f5-c64fc7515795/,但在运行grub-install时却出错了,如下:

[root@fsc feng]# grub-install --root-directory=/media/c0f80392-62db-4156-a4f5-c64fc7515795/ /dev/sdc4
The file /media/c0f80392-62db-4156-a4f5-c64fc7515795//boot/grub/stage1 not read correctly.

印象中以前都是这样安装grub的,检查没发现问题,于是google,说是/etc/fstab 里作过配置,刚才确实改过但没有重启机器,于是重启。再运行grub-install,还是照例出错,消息完全一样。于是继续google,啃英文文章,一时间没有找到方案。又尝试了N多其它方式:再次格式化U盘、直接拷/boot/grub 到U盘再grub-install等,都不行。

准备把U盘上分区重新删掉,重建分区再尝试。突然想到分区格式与分区表中不一致,使用“磁盘实用工具”查看时,该分区/dev/sdc4是w95 fat32(0x0b),删掉,再建ext2分区,设置为可启动(可以通过磁盘实用工具设置,或fdisk修改都可以),为/dev/sdc1,格式化为ext2,再次运行grub-install,成功

[root@fsc feng]# grub-install --root-directory=/media/287801d6-91aa-4563-a45e-d34073af2ff9 /dev/sdc1
Probing devices to guess BIOS drives. This may take a long time.
Installation finished. No error reported.
This is the contents of the device map /media/287801d6-91aa-4563-a45e-d34073af2ff9/boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install'.

(fd0)    /dev/fd0
(hd0)    /dev/sda
(hd1)    /dev/sdb
(hd2)    /dev/sdc
[root@fsc feng]#
Pages: Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 Next