Archive for the ‘php/javascript’ Category

Iframe跨域访问Cookie和Session的问题

Posted by 机器人 on 17th 三月 2010 in php/javascript

最近忙的一个项目,主要是做一些登录系统的整合,其中遇到的一个最关键的问题为在一个统一的后台里需要无障碍的访问另外一个系统后台,这个系统是第三方提供的一个加过密的系统,后台自动登录接口是自己分析出来的,没有单独提供,当从统一后台通过自动登录接口登录时,系统直接跳转到系统后台首页,后台登录成功后所跳转的URL这里没法指定,控制不了跳转的页面,如果在统一后台里需要链接到这个系统后台的另外一个页面,而非后台默认首页时,也就是将第三方系统后台的菜单功能放到我们这个统一后台里。

对于这样的一个需要,这里会遇到一个问题,为了能正常访问第三方系统的后台栏目,必需确保已经登录该系统,否则会提示用户登录,所以在点击这些菜单链接时,系统必需已经登录。 Read the rest of this entry »

php中,怎么对大文件进行读取操作

Posted by 机器人 on 3rd 十二月 2009 in php/javascript

在php中,对于文件的读取时,最快捷的方式莫过于使用一些诸如file、file_get_contents之类的函数,简简单单的几行代码就能很漂亮的完成我们所需要的功能。但当所操作的文件是一个比较大的文件时,这些函数可能就显的力不从心, 下面将从一个需求入手来说明对于读取大文件时,常用的操作方法。

需求

有一个800M的日志文件,大约有500多万行, 用php返回最后几行的内容。

实现方法

1. 直接采用file函数来操作

注:由于 file函数是一次性将所有内容读入内存,而php为了防止一些写的比较糟糕的程序占用太多的内存而导致系统内存不 Read the rest of this entry »

抽空做的一个网址缩短服务

Posted by 机器人 on 2nd 九月 2009 in linux/server, mylife, php/javascript

用过 twitter的用户都知道,整个输入框只能输入140个字符,如果需要发布一些URL地址,但这些地址又比较长的话,会占用很多字符,然后自己能输入的字符就十分有限,为了解决这个问题,随之就兴起了很多第三方应用,它可以将一个很长的地址缩短成很短的字符串,在发布信息时,只需要发现这些很短的字符串即可,只要点击这些短地址,就可以跳转到原地址。
国外比较著名的网址缩短服务提供商有。
TinyURL Qurl Jitty 等。

国内也有相应的服务,比如新浪为了配合它的新产品新浪围脖,也启用 sinaurl.cn这个域名来提供网址缩短服务。

昨天也抽空做了一个这样的服务。 体验地址。 http://cut.hqlong.com/

机器人 2009年09月02日 13:23 于 北京 阴

这样的一个需求的实现

Posted by 机器人 on 29th 六月 2009 in php/javascript

需求:

一个表格的单元格所对应的坐标由字母组合而成,具体排列方式如下:

第  1  行: A          B         C          D           E      …..     Z
第  2  行:AA       AB      AC      AD        AE   …..    AZ
第  3  行: BA       BB       BC      BD        BE    …..    BZ


第 27 行:ZA       ZB       ZC       ZD        ZE  …..     ZZ
第 28 行:AAA   AAB    AAC   AAD   AAE …    AAZ
依次类推
….
….

分别由26个英方字母组合而成,而每一个单元格都由唯一的一个数字与其对应,如:1 对应第1行第一列的A,26对应第1行第26列的Z,27对应第2行第1列的AA,26 * 27 = 702对应第27行26列的ZZ,703对应第28行第1列的AAA,等等。

请编写一个函数,接受一个数字参数,然后返回该数字所对应的单元格的字母组合。

分析:

由上面的需求可知,表格只有26列,而行数没有限制,数字26对应Z,27则对应AZ了,从而可以看出,列只要到了26,再加1的话,行就需要扩展一位。所以可以把这个问题看成是求26进制数的问题,即,怎么将一个十进制转换成一个26进制数。

所以第一步只需要请求出给出数字所对应26进制数即可,对于求26进制的方式和求一个十进制数的二进制的方式类似,通过不停的求商取余,直接到最后的商为0,然后对余数取反。

第二步则是建立一个字母和数字的映射数组,然后将第一步所求得的26进制数映射成对应的字母即可。

大致实现方法如下:

$a = array();
$a = array();
do {
    $n = $num % 26;
    $num = (int)($num / 26);
    array_push($a,$n);
} while ($num != 0);
$a = array_reverse($a)

将所取得的余数全部放入数组,等求解结束后,再将保存余数的数据里的元素反转。

接下来选建立一个映射数组。

$map = array(
	 0 => 'Z', 1 => 'A', 2 => 'B', 3 => 'C', 4 => 'D',
	 5 => 'E', 6 => 'F', 7 => 'G', 8 => 'H', 9 => 'I', 
	10 => 'J',11 => 'K',12 => 'L',13 => 'M',14 => 'N',
	15 => 'O',16 => 'P',17 => 'Q',18 => 'R',19 => 'S',
	20 => 'T',21 => 'U',22 => 'V',23 => 'W',24 => 'X',
	25 => 'Y'
);

但很快就会发现一个这样的规律。
25 对应的26进制数为 0 25, 映射字母为 ZY
26 对应的26进制数为 1 0, 映射字母为 ZA
27 对应的26进制数为 1 1, 映射字母为 AA
702对应的26进制数为 1 1 0,映射字母为 AAZ
703对应的26进制数为 1 1 1,映射字母为AAA
由上面的分析结果,可知,下面两种情况的映射结果不正确。

1.所有能被26整除的数所对应的字母对应关系不正确,而这样的数在被转成26进制数时,最后一数都为0,次最后一位数为1。

2.所有第一行内的数字对应的十进制数也不正确,最高位都为0,如果把最高位的0去掉,对应关系就正确了。

对于第一种情况,仔细观察可以发现,数据不正确,是因为数字刚才被26整除,需要进位所引起的,如果把进的位再退一位,就会发现对应关系就看起来对多了,可能还是有些地方不对。
如:
本来26应该对应Z的,而现在对应的是ZA,假设上面的分析结果正确,那么先对26所对应的26进制数进行退位分析。26对应的26进制数为1 0,由上面可知,高位的1是由于数字刚好被整除进位引起的,所以需要对其进行退位减1。
1 0 -> 0 0。
同样的分析方法来分析 702。
1 1 0 -> 1 0 0。
似乎看来起来还是不正确,但我们再仔细一看就发现了,这里是由于进行两次进位引起的,所以也需要进行两次即位。即。
1 1 0 -> 1 0 0 -> 0 0 0.
这下看起来似乎就正确很多了。这里的结果似乎和第一行内的数字结果很相似,如果将最高位的0去掉,结果就正确了。
于是,暂时得出如下结论:
结论 1: 如果转换后的26进制数中有0,需要对其次高位减1,次高位不存在时,则不进行任何操作。
结论 2: 如果转换后的26进制数中最高位为0,则需要将该位删除。

对于上面的几特殊情况运行上面的两条结论:
就可以得出正确结论。

大致实现代码如下:

$cnt = count($a);
for ($i = 0; $i < $cnt; $i++) {
		//将0所在位的次高位减1
    if ($a[$i] == 0 && isset($a[$i+1])) {
        $a[$i+1] -= 1;
    }
    //映射字母
    $a[$i] = $map[$a[$i]];
}
//最高位为0时,将其删除。由于已经做了映射转换,0转换为了Z
if ($a[$cnt -1] == 'Z') unset($a[$cnt-1]);

结合上面的分析,完全实现如下:

function num2name($num) {
	$map = array(
		 0 => 'Z', 1 => 'A', 2 => 'B', 3 => 'C', 4 => 'D',
		 5 => 'E', 6 => 'F', 7 => 'G', 8 => 'H', 9 => 'I', 
		10 => 'J',11 => 'K',12 => 'L',13 => 'M',14 => 'N',
		15 => 'O',16 => 'P',17 => 'Q',18 => 'R',19 => 'S',
		20 => 'T',21 => 'U',22 => 'V',23 => 'W',24 => 'X',
		25 => 'Y'
	);    
    $a = array();
    do {
        $n = $num % 26;
        $num = (int)($num / 26);
        array_push($a,$n);
    } while ($num != 0);
    $cnt = count($a);
    for ($i = 0; $i < $cnt; $i++) {
        if ($a[$i] == 0 && isset($a[$i+1])) {
            $a[$i+1] -= 1;
        }
        $a[$i] = $map[$a[$i]];
    }
    if ($a[$cnt -1] == 'Z') unset($a[$cnt-1]);
    $a = array_reverse($a);
    return join("",$a);
}

测试代码

$d = array(702,703,25,3234,24,1324,314,128,2,41);
foreach($d as $v) {
    echo num2name($v)."\n";
}

测试如果

ZZ
AAA
Y
DTJ
X
AXX
LB
DX
B
AO

另外附上一种运用递归的实现方法。(网友提供)

function num2name($num) {
    //定义一个数组
    if($num==0) return '';
    $arr ='ZABCDEFGHIJKLMNOPQRSTUVWXY';
    $n = intval(($num-1)/26); //取得整数倍
    $m = $num%26; //取得余数
    $name = num2name($n).$arr{$m};
    return $name;
}

哈哈,好像这种方式简洁多了!
机器人 2009-06-29 16:16 于 北京 晴

vim执行php或者c/c++的快捷键

Posted by 机器人 on 23rd 六月 2009 in c/c++, linux/server, php/javascript, phpoo, vim

经常我们会编写一些测试代码,这些代码一般只是临时测试某一个函数,测试过后基本上就没什么用了。
如果使用IDE,这好办,基本上都有一些快速运行的键,比如在ZendStudio里,将代码编写好了以后,只需要按一下F5,就可以马上出来执行结果,而且这个文件都可以不用保存。

如果使用VIM来编写代码,可能很多朋友就会想了,有没有什么方法来建立一个快捷键,能快速的运行我们所编写的代码呢?!!
答案当然是肯定了的,不然也不会写这篇日志来讨论这个问题了。

在介绍方法之前,先来谈一下自己以前的执行方式吧!

先拿PHP来讲吧,最传统的方式就是将编写好的代码放在apache的根目录,然后通过浏览器来运行,或者使用php命令来运行php.可以使用php的r参数

hqlong@~$ php -r "echo 'hqlong';"

来快速测试,或者使用q参数

hqlong@~$ php -q test.php

来运行。

接下来讲怎么将vim支持一键执行。
大致原理是使用键盘映射,将快捷键映射到执行的命令。

在.vimrc中添加

nmap < F5 > < ESC >:!clear && php -q < C-R >%< cr >

即当我们按下F5时,就相当于执行了如下操作。
1.按下ESC,然后再按下:,进入vim命令行模式
2.执行clear清屏操作。
3.然后运行当前脚本。
4.最后执行回车操作.
下面有几个指令需要解释一下:
< C - R >%:得到当前文件的名字,包括路径.(按ctrl+r,然后再按%)

接下来可以测试一下.
vim /tmp/test.php

< ? php
    echo "hqlong";
?>

保存后,按F5,
就是快速的得出执行结果。

基于c/c++也同样可以做出映射来,比如我们用F6来执行C++代码。
那么就只需在.vimrc中添加

nmap < F6 > < ESC >:!clear && g++ < C-R >% -o test && ./test< cr >

这里如果我们测试如下代码。
vim test.cpp

# include < iostream >
using namespace std;
 
int main() {
     cout << "hqlong";
    return 0;
}

将会在当前上当下生成一个test可执行文件,并执行它。
所以的这一切都是由于nmap的强大映射功能。

希望对大家有所帮助,欢迎对不明白的地方进行讨论。
机器人 2009-06-23 22:59 于 北京 晴

IE浏览器的专有条件注释

Posted by 机器人 on 22nd 四月 2009 in php/javascript

1. <!–[if !IE]><!–> 除IE外都可识别 <!–<![endif]–>
2. <!–[if IE]> 所有的IE可识别 < ![endif]–>
3. <!–[if IE 5.0]> 只有IE5.0可以识别 < ![endif]–>
4. <!–[if IE 5]> 仅IE5.0与IE5.5可以识别 < ![endif]–>
5. <!–[if gt IE 5.0]> IE5.0以及IE5.0以上版本都可以识别 < ![endif]–>
6. <!–[if IE 6]> 仅IE6可识别 < ![endif]–>
7. <!–[if lt IE 6]> IE6以及IE6以下版本可识别 < ![endif]–>
8. <!–[if gte IE 6]> IE6以及IE6以上版本可识别 < ![endif]–>
9. <!–[if IE 7]> 仅IE7可识别 < ![endif]–>
10. <!–[if lt IE 7]> IE7以及IE7以下版本可识别 < ![endif]–>
11. <!–[if gte IE 7]> IE7以及IE7以上版本可识别 < ![endif]–>
12. <!–[if lte IE 6]>……< ![endif]–>

机器人 2009-04-22 11:27 于 北京

html q标签的问题

Posted by 机器人 on 9th 四月 2009 in php/javascript

对字符加引号,默认情况下,IE没有,FF有!!
q {quotes:none}
或者
q:before,q:after {content:”;}
去年引号。
但前者在google chrome中不管用。
只能使用后者

机器人 2009-04-09 15:26 于 北京

收藏:Viewport Dimensions in Javascript

Posted by 机器人 on 20th 三月 2009 in php/javascript
var Client = {
  viewportWidth: function() {
    return self.innerWidth || (document.documentElement.clientWidth || document.body.clientWidth);
  },
 
  viewportHeight: function() {
    return self.innerHeight || (document.documentElement.clientHeight || document.body.clientHeight);
  },
 
  viewportSize: function() {
    return { width: this.viewportWidth(), height: this.viewportHeight() };
  }
};

引用:http://andrewdupont.net/2006/09/09/viewport-dimensions-in-javascript/
机器人 2009-03-20 13:20 于 北京

apache之mod_expires

Posted by 机器人 on 19th 三月 2009 in php/javascript

前面提前过yahoo前端工程师提出的14条网站性能优化的建议,第四条是通过mod-deflate模块来对网站内容进行压缩,从而减少页面大小。
其中第三条也提到了这里的mod_expires,就是通过延长页面组件的有效期来加速网页的加载。

因为浏览器在第一天打开了一个网站后,会对里面的图片、脚本等组件进行缓存,所以每次在第一次打开一个网站的时候,明显感觉到速度很慢,但第二次再浏览时,打开速度就会快很多,这就是因为第一次用户访问网站时,由于缓存过期,所以过期的组件需要从服务器上重新下载,那么第二次再打开相同的页面时,由于第一次已经下载过了这些组件,所以这次就直接从缓存里读取,而不需要从浏览器重新下载。
但默认的浏览器缓存时间是很短的,在浏览器关闭时,缓存就是失效,就是意味着,如果刚浏览的网页,在浏览器关闭后,再次浏览,又会重新下载所有的资源。但我们知道,这期间这些资源似乎都没有任何变化。所以在一段时间里,我们是没有必要再去下载这些资源的。
所以我们可能通过延长组件的过期时间来实现这样的要求。

纵观几天闻名网站,都对网站的过期时间进行了延长。

可以使用apache的mod_expires模块来实现这些模块。
编译模块时加上

--enable-expires

然后在配置文件中开启缓存功能。

 ExpiresActive On

延长图片、样式、脚本的过期时间

<filesmatch "\.(gif|jpg|js|css)$">
ExpiresDefault "access plus 10 years"
</filesmatch>

时间可以以年、月、周、小时、分钟、秒为单位来设置。

如果对于一个脚本的有效期延长10年,如果这期间用户不清除缓存,就意味着我们对脚本的所有修改都不会体现到用户。用户浏览页面时,还是使用先前缓存里的脚本。如果要让用户使用最新的脚本,就需要更改文件的链接地址。

所以为了每一次文件更新时,让用户重新下载最新的资源,我们可以将这些资源以版本号的形式来命名。如q_3.2.1.js.每次对其进行更新时,并更新相应的版本号。这样就可能解决用户既然下载最新资源的问题。如果资源不更改,用户还是从缓存读取资源。
嵌入版本号不仅能改变文件命,还能在高度时更容易的找到准确的源代码文件。

机器人 2009-03-19 0:06 于 北京

收藏:js绝对尺寸

Posted by 机器人 on 18th 三月 2009 in php/javascript
function getAbsHeight(ob){return ob.offsetHeight;}
function getAbsWidth(ob){return ob.offsetWidth;}
function getAbsLeft(ob){
	var s_el=0;el=ob;
	while(el){
		s_el=s_el+el.offsetLeft;
		el=el.offsetParent;
	};
	return s_el;
}
function getAbsTop(ob){
	var s_el=0;
	el=ob;
	while(el){
		s_el=s_el+el.offsetTop;
		el=el.offsetParent;
	};
	return s_el;
}