存档在 ‘PHP’ 分类

关于PHPUnit的安装问题

2010年1月15日

以前用PHP PEAR装过一次PHPUnit问题不大,现在再讨论一下手动安装PHPUnit的问题。

首先,下载最新的PHPUnit文件

http://pear.phpunit.de/get/

第二,下载后解压到一个目录

注意,这个目录必须位于php 的 include_path参数里面,或者你解压之后,将所在目录添加到include_path里面去
比如:我解压之后PHPUnit文件夹内容都在 E:\library\phpunit\PHPUnit-3.4.6目录里面,那么我在php.ini文件里就要在include_path参数中添加 E:/library/phpunit/PHPUnit-3.4.6这个路径,否则php是找不到phpunit的。

第三,针对windows系统的配置文件修改

官方手册上的手动安装方式见 http://www.phpunit.de/manual/current/en/installation.html
该方法针对非WINDOWS系统,而根据本人操作,WINDOWS系统上的配置相对要简单点。
只要修改 phpunit.bat 就可以了。

苏打绿的春光即将发布——和url有什么关系?

2009年4月23日

今天上haoting.com无意发现苏打绿的新歌有试听了,点开地址:

http://www.haoting.com/play/haotingsonglian.htm?id=344192&id=344193&id=344194&id=344195

很奇怪的,URL里居然有这么多ID,那通过一般的$_GET肯定是得不到的了。

他们为什么这么做?

1.$_GET 返回的只有最后一个id的值

2.$_SERVER['QUERY_STRING'] 含有所有query字符串,上例即是id=344192&id=344193&id=344194&id=344195这串字符串。用explode分解两次[一次&一次=]可以得到所有的id值

3.parse_str($_SERVER[‘QUERY_STRING’],$result) 想将query解析到一个数组里,parse_str 是PHP内置解析字符串函数用于解析URL里传递的参数,magic quote对该函数的影响具有和$_GET,$_POST等一样的效果。如果不提供$result参数,每一个变量会被直接解析为全局变量,有参数的话,变量会保存在指定的数组空间里。 parse_str同样不能处理一样的id变量的情况。

所以对于这种特殊情况的URL,恐怕还是得用手工方式去取值了。

用纯文本显示图片

2009年3月10日

这里不是介绍img 的 src属性里的data而是真正的由文本构成的图片。【有关src data的参考资料见 http://dean.edwards.name/weblog/2005/06/base64-ie/ 】先看看效果吧。

这里 http://demo.thankphp.net/php/pix.php【可能有点慢,PSP,智能机当心点开】

下面看代码,非常非常简单。


$imgname = "http://www.haoting.com/images/logo.jpg";
$im = imagecreatefromjpeg($imgname);
$width = imagesx($im);
$height = imagesy($im);
echo '<style type="text/css">span {font-size:4px;line-height:2px;}</style>'; //good
$space = 1;
for( $i = 0 ; $i < $height ; $i+=$space) {
  for ($j = 0 ; $j < $width ; $j+=$space) {
    $rgb = imagecolorat($im,$j,$i);
    $color = dechex($rgb);
    echo '<span><font color="#'.$color.'">*</font></span>';
  }
  echo "<br />\n";
}

帮米妈下载电子书

2009年3月7日

我没有搞过采集,不知道我下面做的事情算不算采集,也许!

米妈想看电子书,TXT格式的而已,但是网上下载不方便,电炉上也许有,下载也比较麻烦。

在小说网上看到自己想看到的小说,但是总不能一页一页的复制粘贴去啊。于是我义不容辞的做了下面这些事情。


$base_url = "http://www.readnovel.com/novel/23717/";
for($i=1;$i<=59;$i++) {
	$str = file_get_contents($base_url.$i.".html");
	preg_match_all('/\<div class=\"shuneirong\"\>.*\<\/div\>/si',$str,$matches);
	$fp = fopen("congcong".$i.".txt","w");
	$ss = strip_tags(str_replace("<BR>","\r\n",$matches[0][0]));
	fwrite($fp,substr($ss,0,strpos($ss,"设为书签")));
	fclose($fp);
}

很简单,循环页面,抓取 <div class=”shuneirong”></div>之间的内容。然后将<BR>换成换行符,过滤掉所有的html标签,还要把字符串后面一堆与正文内容无关的东西去掉。

这段代码执行完之后,你的文件夹里就有congcong1-congcong59.txt等59个txt文件了。后来米妈又说放到一个文件里,于是我又开始合并文本文件。


$file_prefix = "congcong";
$fp = fopen("congcong.txt","w");
	for($i=1;$i<=59;$i++) {
		$tfp = fopen($file_prefix.$i.".txt","r");
		$t = fread($tfp,20480);
		fwrite($fp,$t);
		fclose($tfp);
	}
fclose($fp);

拷贝到米妈的M8上,OK,任务结束。

米妈一定要加上这句话,我认为也是大势所趋:网络的免费时代快要结束,更多的收费服务即将推出,但是价格不会很贵,以量取胜。

我的理解是:在网上搜索到自己有用的信息会比较困难,人们愿意花费一小部分金钱来节省自己的时间。

10进制转26进制

2009年2月25日

为什么会有这种情况出现呢,都是因为M$公司开发的软件Excel,这个软件里面的单元格定位是采用类似地图标注的定位方式,横坐标是已英文A-Z26个字母的形式增长的,纵坐标是数字递增形式。于是就有了下面10进制转26进制的函数出现。


function dec2excel($num) {
  $str = strtoupper(base_convert($num,10,26));
  for($i=0;$i<strlen($str);$i++) {
    $str{$i} = ord($str{$i}) < 58 ? chr(ord($str{$i}) +16) : chr(ord($str{$i}) + 10);
  }
  return $str;
}

PHP里面有提供一个base_convert函数,可以在任意进制之间进行转换。当然这个任意是有限度的,具体来说是在【2-36】之间。为什么是36呢?回头再讲。

但是这里有个问题,不管那种进制,第一个自然数都是1开头的,但是Excel里面的横坐标是以字母A开始的。于是就面临1-9要顺移到A-I的问题。这里1的ASCII值为49 A的ASCII值为65 所以简单判断ASCII值,小于58【9的ASCII值为57】的 递增16,否则递增10。但是这里出现了一个问题,0怎么处理?????这个函数没有对0进行处理,或者说0的处理是完全错误的,0的ASCII值为48,48+16 = 64 ,而ASCII码值为64的是@。


/**
 * 自然数              0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
 * base_convert之后    0 1 2 3 4 5 6 7 8 9 a  b  c  d  e  f  g  h  i  j  k  m  n  o  p  q  10 11
 * 实际的A-Z组成的26进制   A B C D E F G H I J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Y  Z  AA
 */

看来这个函数不能这么搞。问题的关键就出在 自然数是[1-9]+0 而26进制是[A-Z]的循环。

难道要回归原始的根据每一位所代表的权重用计算的方式把A-Z的26进制弄出来?不行,再想办法。

今天回家的地铁里左思又想也得不到结果,有朋友推荐我去看Excel的相关函数,我想这么简单的东西,算我笨好了,一晚上总想得出来的吧。

终于被我想到了解决方法。我就用死算的方法好了:


function ori_dec2excel($num) {
	$a = array('A','B','C','D',...,'T','U','V','W','X','Y','Z');
	$yushu = $num % 26;
	$jixuchuli = ($num - $yushu) / 26 ;
	if($jixuchuli <= 26) {
		return $a[$jixuchuli-1].$a[$yushu-1];
	} else {
		return ori_dec2excel($jixuchuli).$a[$yushu-1];
	}
}

但是下面这个表达式的结果确不是我想要的,52的26进制应该是AZ。 用base_convert的方式表达是20。



 $k = ori_dec2excel(52);

问题的关键就出在A-Z之中没有“0”。

或者说按照上面的函数 $num % 26 之后,如果余数为0的话,要把这个26给退回来,不能放到高权重的位去处理。于是最后的解决方式出笼了。

function ori_dec2excel($num) {
	$a = array('A','B','C','D','E',...,'V','W','X','Y','Z');
	$yushu = $num % 26;
	$yushu = $yushu == 0 ? 26:$yushu;
	$jixuchuli = ($num - $yushu) / 26 ;
	if($jixuchuli <= 26) {
		return $a[$jixuchuli-1].$a[$yushu-1];
	} else {
		return ori_dec2excel($jixuchuli).$a[$yushu-1];
	}
}

最后附上我的26进制转10进制的函数,这个的思路就比10进制转26进制要简单的多了。


function ori_excel2dec($num) {
	$v=0;
	$l = strlen($num);
	$a = array('A','B','C','D','E',...,'U','V','W','X','Y','Z');
	for($i=0;$i<$l;$i++) {
		$v += (array_search($num{$i},$a)+1)*pow(26,($l-$i-1))."\r\n";
	}
	return $v;
}

为什么PHP的base_convert最大只提供到36进制的转换呢,那是因为:0-9 十个数字加上 a-z 26个字母,可以用来表达不同位的字符只有36个。所以,这下明白了吧。