在页面退出或者切换刷新提示用户

<script language="JavaScript" type="text/javascript">

<!--

window.onbeforeunload = onbeforeunload_handler;

function onbeforeunload_handler()

{

  var warning="确认退出?";

  return warning;

}

// -->

</script>
 

相关延伸:

可以定义一个变量开控制是否提示,比如用户自己确实手动关闭或者刷新,可以不提示。否则提示。

有人也写了刷新不提示的代码(未测试):
 window.onbeforeunload    =    function(){

        var    n    =    window.event.screenX    -    window.screenLeft;

        var    b    =    n    >    document.documentElement.scrollWidth-20;

       if(b    &&    window.event.clientY    <   0    ||    window.event.altKey)

        {

            alert("是关闭而非刷新");

            window.event.returnValue    =   "是否关闭?";

        }else{

               alert("是刷新而非关闭");

       }

 }

客观评价360VS腾讯事件

其实 这件事发生了,双方都有责任,腾讯并不能完全责怪360,的确QQ扫描客户端是不对,360说出来了,其实是在体现自己出了个 隐私保护器的作用的同时一方面也是给了用户用户的知情权,而腾讯扫描客户端事先没有通知用户,这一点我认为360是对的,但360出了个扣扣,有几个地方不对,一般的功能,包括阻止QQ扫描客户端这些我 都认为是对的,你可以设置,也可以不设置,而QQ软件上正好缺少这个功能(我相信腾讯会在产品中增加这一项,可以通过设置来取消某些用户自己用不到的功能),用户看需要,比如我就选择了屏蔽广告,和禁止扫描客户端,但是360某个设置,设置了之后就会劫持QQ管家,就是在QQ上点击管家那个图标会出现360软件,这个过 分了,在这一点上,我推荐MSN的做法,MSN在接受文件后,有一个扫描功能,比如QQ上设置一个安全扫描,可以让用户自行选择扫描软件,这是一个比较人性化的做法,而QQ在客户端上让用户二选一,确实很过分,这感觉是在逼用户,而每个用户都很讨厌这样的做法,故大部分都会觉得QQ做法很不对,其中我对QQ这样的做法很不高兴。

个人认为QQ产品有必要作调整,QQ毕竟是一个IM客户端,不要在上面强加很多功能,就算加,也要让用户有一个选择的机会,或者安装的时候提示,或者安装后在设置里有设置,我认为这是用户体验的一种,也是一个有责任企业对用户的一种负责,可以使用类似Firefox那样的插件式,或者类似Apple的IOS系统的安装模式,其实很类似,易于安装,易于取消,符合用户使用习惯。

360的产品更需要调整,现行的360软件,多窗口,很让用户反感。做好自己的产品,不要采取不和谐非健康的方式干预其他软件,360没有必要去说别人产品多么不好,而是要做好自己的产品,自己的好不是靠说别人的不好体现出来的,到底谁的产品好,用户能看得出来,总是去说别人不好的,那自己肯定好不到哪儿去。

需要反思,在这件事情发生的同时,我们发现,腾讯的官方网站上没有客观报道这个件事,腾讯的新闻几乎是倒向腾讯,就是说说自己100%有理由,没有任何问题,我觉得,腾讯的QQ产品有问题,并不要影响腾讯网的的运营,不要报道一边倒,要客观,不是说一个网友发了一篇批判360的就置顶什么的,比如还有QQ围脖中也是,有刻意引导用户来讨论事件话题,然后有把自己的官方博客强制加到首页,几乎腾讯的所有产品都影响到了,就当腾讯在逼用户二选一的时候,360打包了一个webQQ,腾讯也关掉了WebQQ,我觉得这种做法,没有经过思考,而是小孩子气。如果腾讯在这件事上不采取如此强烈的措施,反而更为主动,不可能像现在这样处于被动状态。

我觉得网上举例子说的很好,“现在主席在用360和QQ,你叫主席怎么办?”,用户就是上帝,千万不要得罪用户,更不要逼用户做选择,谁逼用户往往是用户就不选谁。

ie8的Slice

<div class=”defaultSection  hslice” id=”divRecomment”>
  
<h2 class=”entry-title”>今日推荐</h2>
  
<ul class=”entry-content”>
    
<li><href=http://www.baidu.com>baidu</a></li>
    
<li><href=http://www.google.com>google</a></li>
    
<li><href=http://qq.com>qq</a></li>  </ul>
</div>

大家可以看到在div上面有一个hslice的css class,这个class表示这个div内的内容是一个网页快讯,同时要求这个div必须指定id;还有两个固定的css分别是entry-title和entry-content分别表示网页快讯的标题和内容元素。这个神奇的功能需要我们做的事情就是指定一个id和三个css的class。

ie8的这个功能真炫。感谢微软。

今日推荐

不要无视用户,不能强奸用户。

此文章只代表个人意见和观点,我只是从一个用户来看这个问题。
先说360吧,先说他们的产品,我为什么选择360后又放弃360?360这个软件我也用过一段时间,刚开始出来的时候用起来还是挺好的,界面简单,免费是最大的优势。后来一直发展到现在,出了很多衍生产品比如360浏览器,360杀毒,360网盾,360保险箱等等出了一系列的,而且每个是单独的一个界面,什么意思,就是比如我装了360安全卫士,点了里面的某个功能模块,卡,弹出一个新的窗口,点其他的又弹出来很多,加上如果又漏洞补丁什么的,右下角还有提示,看上去有很多个界面在桌面上,给人的第一感觉是运行了很多软件,而不是一个软件,只是这几个软件界面差不多罢了,给第一用户的感觉是全部关掉只保留当前操作的一个,至少给我是这个感觉,后来我就不用360了,直接裸奔,只要不上什么乱七八糟的网站,我相信是不会中毒的,我一直使用firefox浏览器,后来出来google出了chorme,我一般就用这两种,还是挺安全的。
360这次曝光qq扫描用户硬盘文件事件,我认为是对用户的一种负责行为,为什么这么说,首先他不告诉我们,我们用户是不知道的,腾讯也没有告诉我们说是要扫描我们的电脑文件,更没有说为什么要扫描我们的电脑了,其实曝光这个问题也说明了360开始重视用户体验和保护用户隐私。
再说说腾讯,腾讯自从有了qq这个产品之后,就一直在模仿,抄袭这个是大家有目共睹的,至少给我的感觉是这样的,qq是抄袭原来国外的icq,之前名字叫oicq,后来还被告了,然后名字改成“QQ”,腾讯的产品刚出来的时候,还是很好用的,软件没有这么大,也没有其他周边产品,后来越做越大,浏览器也做了,对战平台也做了,问吧也做了,商城也做了,支付也做了,搜索也做了,游戏也做了,为什么他要做这么多东西,很显然其实是在垄断,其实垄断不是不好,但是关键是要做好每个产品,有人说苹果一直被抄袭,但一直没有被超越,腾讯一直在抄袭,一直没有超越。我认为腾讯的产品太多,说的不好听有些产品根本就不需要,是在忽悠用户,我们不需要这样的产品,就来其中一款产品来说吧,腾讯的滔滔,这个产品其实是模仿twitter的,国内好像是饭否第一个‘引进’过来的,腾讯也搞了个滔滔,而现在微博也搞了一个,其实功能基本上差不多,说白了是一种浪费,微博是什么,其实就是twitter功能差不多,有必要让用户这么折腾吗?为什么说是折腾用户,因为我们发现好多用qq的人,有一部分人是有这样的心里的,这也是腾讯猥琐的一面,你点到某人头像上面,上面不是显示开通了某些产品吗,很大一部分用户是这样想的,我要去开通红钻,我要去开通黄钻,那腾讯搞50个产品,有些人就要去开50个服务,当然不要钱是不可能的,当然很大一部分是要钱的,其实有这样想法的人真的很多,也很正常,他们就想完美一点,一方面是满足自己的虚荣心,另一方面是好看一点,因为没有没有点亮图标是灰色的,点亮了就是彩色的。总之,腾讯的产品是多而不精,像这次腾讯和360这么一闹,再怎么说也要推出个qq杀毒软件什么的啊,要不面子都没有了啊,人都这样,我腾讯这么大一个公司,我有几亿的用户,我要被你360指指点点的成怎么回事,呵呵。
腾讯被360捅了这么一刀,这下完了,我不是有几亿用户吗,客户端上是我的天下,你360跟我斗,你有资格吗,开始报复啦,这个大家都看到了,腾讯就说了,我扫描客户端文件是为了保护帐号安全,这里我要问的就是,既然让你扫了,你什么都干了,那要是万一我银行卡里钱少了,你腾讯有没有责任?人家360说了,你扫描我客户端文件还有进程,连我的银行软件也要检查,我不知道你干了些什么,不排除你盗取我电脑资料和银行密码啊,你说是把,我这么想也是正常的。
腾讯这么一弄,360很生气啊,怎么当着那么多用户的面说我360怎么怎么的呢,我也是为了用户啊,360很生气,这样来出个软件,限制qq的一些功能,的确,360那个软件还挺好的,可以屏蔽聊天窗口的广告,还有禁止qq扫描客户端文件,我是觉得挺好。
之前360不是也和金山有冲突吗,前段事件也闹了一阵子,金山说360装上了就不能装我们的软件,360说装了金山网镖就要卸载360安全卫士什么的,后来不知道怎么搞的,牵出了可牛,还有遨游也都说360怎么怎么的,后来我知道那个可牛老总原来是360的,后来自己出去搞了个可牛,挺牛,那段时间在腾讯微博上骂的啊,火啊 ,那段时间我也在关注,纯当娱乐,反正貌似有一天那个可牛的老总在上面说了什么 我之前在360干过,我出来之后做的所有的事情不是针对弟兄们,说之前360的有些做法很有意见,反正讲的大家懂得,就是360的某些别人看不到的黑暗的一面,我相信也是有的,我写这个文章不是为了袒护某一方。后来第二天还是第三天貌似被删了,不知道发生了什么事情。至于怎么牵出遨游和可牛,现在我才明白,现在不是可牛被金山合并了嘛,应该就是那段时间就开始接触了,所以出来帮金山说话,金山跟遨游也有合作,遨游应该也是帮金山说话的。 话说到现在我当时也还在用360,后来我也就下了个金山网镖,装啊,哎,的却装不上啊,我就去360说这个问题了,当时有条新闻,我就在下面评论了,嘿,审核制的,想说我360坏话,不行,不能发,这里只能发诋毁金山的,当然我也去金山测试了,但是我发现金山问题还是有很多的,我当时后来又试用了他们一个产品,那个产品就出了个低级错误,我点了他们自己网站的软件,直接弹出来,说可能又病毒什么的,其实呢,那个连接就是他们自己的连接。我无语啊,后来打电话过去,他们客服说了我可能下载的测试版或者什么的,还给我发了邮件,我按照他的做法重装了,问题依旧,第二天还给我打电话,服务挺好,但是解决不了问题。
360吧产品还行,指责你指责他的,自己做好自己的产品,不要把什么东西都推到客户端,动不动搞个扣扣保镖,跟腾讯沟通下不就好了嘛,但是也为难你了关系都搞这么僵了,只能这么干了。腾讯也不好,做好自己的产品,现在没有这种技术嘛,如果不扫描硬盘,就不能有效保护qq安全,我还不信,我也没有听过装个银行什么软件,他会对全盘扫描啊,自己软件安全机制做好,也没有必要瞎搞嘛,该知道的知道,不知道的也不要去知道,用户的隐私还是要保证的,你说你是保证安全才扫描,我相信你,别人也不信啊,是不,谁知道不顺便干点别的事呢,这个社会相信别人不如相信自己。
总之,请你们不要无视用户,不能强奸用户,动不动出几个软件,把我们用户当成是试验品了,还有那个可牛,也跟在360后出个361,太让人讨厌了,根本就是无视用户。没有最好,只有更好,希望你们把你们产品真正做好。腾讯,你说你牛,有本事你全免费,广告也不做,或者让用户自己选择,或者插件式安装,你可以把扣扣的功能集成到qq软件里,那不是对大家都好嘛,说到广告,你那个新闻里到处是广告,站内的也就算了,有些是站外的广告,误导用户,以为上了你腾讯的网站,确实外面的广告连接,界面跟腾讯的差不多,这样做太不把用户当回事了。说到广告,我认为淘宝做的就比较好,他所又广告都是站内的,站外的都屏蔽掉了,比较重视用户的,而且taobao用户体验方面做的也很不多,然家每次改版,都会调查一下用户意见,你们呢,自己搞,搞完再说,强奸用户,qq界面呢三天两头就去抄袭msn的什么的,我就搞不懂,你们不差钱,老去抄人家的有意思嘛,你们就不能自己研发,汗,整天就想着赚钱,什么火,什么新奇就搞什么,qq号都能卖钱,看人家msn只怎么做的,人家能直接email登陆,难道人家不能用号码,一点做大事的风范都没有,就是钱,用小沈阳的话说你不差钱,还有有前几年,出的那个等级,不知道浪费了多少电啊,怎么想出来的,我看msn没有出等级,也没有发现其他im出过类似的,你们是在浪费资源,算了好像说了腾讯不少坏话啊,做的好的地方也不少了,有些用户体验还是不错的,邮箱做的不错,呵呵。我这么说也是为了用户着想,你们都应该自己反省一下,产品到底怎么做?特别怎么做好,别老去揭别人的短处,做好自己的,别人的短处告诉他,让他改,别动不动就直接吵起来,抄给我们看啊,我们用户被你们这么一搞,真不放心,不知道能信任哪一个,这么一看,哪个都好,仔细想想,哪个都不是好东西。现在用了你们的产品,那是因为没有替代品,等有一天替代品出来了,那估计就晚了。好好做好自己的产品吧。
最后,比较遗憾的是,我们国家还没有一个权威部门,来对你们的产品进行检测,来保障用户的利益,最好的人才都在你们那,你们看着办吧,哪些做产品的人也要想一下,什么东西能做,什么东西该做,不是什么都去做,要有点职业修养。

PHP获取当前url路径的函数及服务器变量

1,$_SERVER["QUERY_STRING"]
说明:查询(query)的字符串

2,$_SERVER["REQUEST_URI"]
说明:访问此页面所需的URI

3,$_SERVER["SCRIPT_NAME"]
说明:包含当前脚本的路径

4,$_SERVER["PHP_SELF"]
说明:当前正在执行脚本的文件名

实例:
1,http://www.biuuu.com/ (直接打开主页)
结果:
$_SERVER["QUERY_STRING"] = “”
$_SERVER["REQUEST_URI"] = “/”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”

2,http://www.biuuu.com/?p=222 (附带查询)
结果:
$_SERVER["QUERY_STRING"] = “p=222″
$_SERVER["REQUEST_URI"] = “/?p=222″
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”

3,http://www.biuuu.com/index.php?p=222&q=biuuu
结果:
$_SERVER["QUERY_STRING"] = “p=222&q=biuuu”
$_SERVER["REQUEST_URI"] = “/index.php?p=222&q=biuuu”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”

$_SERVER["QUERY_STRING"]获取查询语句,实例中可知,获取的是?后面的值
$_SERVER["REQUEST_URI"] 获取http://www.biuuu.com后面的值,包括/
$_SERVER["SCRIPT_NAME"] 获取当前脚本的路径,如:index.php
$_SERVER["PHP_SELF"] 当前正在执行脚本的文件名

当前url:”http://”.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']

总结一下,对于QUERY_STRING,REQUEST_URI,SCRIPT_NAME和PHP_SELF,深入了解将有利于我们在$_SERVER函数中正确调用这四个值。通过实例详解$_SERVER函数中 QUERY_STRING,REQUEST_URI,SCRIPT_NAME和PHP_SELF掌握四个变量之间的区别。

$_SERVER["REQUEST_URI"] :获取当前请求的完整的(除域名的)url。。。

uchome系统中处理技巧:

代码
//处理REQUEST_URI
if(!isset($_SERVER['REQUEST_URI'])) {
$_SERVER['REQUEST_URI'] = $_SERVER['PHP_SELF'];
if(isset($_SERVER['QUERY_STRING'])) $_SERVER['REQUEST_URI'] .= ‘?’.$_SERVER['QUERY_STRING'];
}
if($_SERVER['REQUEST_URI']) {
$temp = urldecode($_SERVER['REQUEST_URI']);
if(strexists($temp, ‘<') || strexists($temp, '"')) {
$_GET = shtmlspecialchars($_GET);//XSS
}
}

代码如下:

代码
echo $_SERVER['DOCUMENT_ROOT']."
“; //获得服务器文档根变量
echo $_SERVER['PHP_SELF'].”
“; //获得执行该代码的文件服务器绝对路径的变量
echo __FILE__.”
“; //获得文件的文件系统绝对路径的变量
echo dirname(__FILE__); //获得文件所在的文件夹路径的函数
?>

//server函数
$_SERVER["HTTP_REFERER"]=http://localhost/lianxi/
$_SERVER["HTTP_ACCEPT_LANGUAGE"]=zh-cn
$_SERVER["HTTP_ACCEPT_ENCODING"]=gzip, deflate
$_SERVER["HTTP_USER_AGENT"]=Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727)
$_SERVER["HTTP_HOST"]=localhost
$_SERVER["HTTP_CONNECTION"]=Keep-Alive
$_SERVER["PATH"]=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Common Files\Adobe\AGL;C:\Program Files\MySQL\MySQL Server 5.0\bin;C:\php;C:\php\ext
$_SERVER["SystemRoot"]=C:\WINDOWS
$_SERVER["COMSPEC"]=C:\WINDOWS\system32\cmd.exe
$_SERVER["PATHEXT"]=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
$_SERVER["WINDIR"]=C:\WINDOWS
$_SERVER["SERVER_SIGNATURE"]=
Apache/2.0.55 (Win32) PHP/5.1.1 Server at localhost Port 80 \\使用的何服务器
$_SERVER["SERVER_SOFTWARE"]=Apache/2.0.55 (Win32) PHP/5.1.1
$_SERVER["SERVER_NAME"]=localhost \\服务器名称
$_SERVER["SERVER_ADDR"]=127.0.0.1
$_SERVER["SERVER_PORT"]=80 \\服务器端口
$_SERVER["REMOTE_ADDR"]=127.0.0.1
$_SERVER["DOCUMENT_ROOT"]=D:/lianxi \\网站的主目录
$_SERVER["SERVER_ADMIN"]=sss@163.com \\安装APACHE时设置的邮箱
$_SERVER["SCRIPT_FILENAME"]=D:/lianxi/lianxi/servervalues.php \\当前的网页的绝对路径,
$_SERVER["REMOTE_PORT"]=1076 \\远程端口
$_SERVER["GATEWAY_INTERFACE"]=CGI/1.1
$_SERVER["SERVER_PROTOCOL"]=HTTP/1.1
$_SERVER["REQUEST_METHOD"]=GET
$_SERVER["QUERY_STRING"]=\\获取?号后面的内容
$_SERVER["REQUEST_URI"]=例子:/lianxi/servervalues.php?a=1&b=2
$_SERVER["SCRIPT_NAME"]=例子:/lianxi/servervalues.php
$_SERVER["PHP_SELF"]=/lianxi/servervalues.php \\返回当前网页的相对路径.
$_SERVER["REQUEST_TIME"]=1179190013 \\运行时间 单位为十万分之一毫秒
$_SERVER["argv"]=Array
$_SERVER["argc"]=0
1,$_SERVER["QUERY_STRING"]
说明:查询(query)的字符串
2,$_SERVER["REQUEST_URI"]
说明:访问此页面所需的URI
3,$_SERVER["SCRIPT_NAME"]
说明:包含当前脚本的路径
4,$_SERVER["PHP_SELF"]
说明:当前正在执行脚本的文件名
实例:
1,http://www.biuuu.com/ (直接打开主页)
结果:
$_SERVER["QUERY_STRING"] = “”
$_SERVER["REQUEST_URI"] = “/”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
2,http://www.biuuu.com/?p=222 (附带查询)
结果:
$_SERVER["QUERY_STRING"] = “p=222″
$_SERVER["REQUEST_URI"] = “/?p=222″
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
3,http://www.biuuu.com/index.php?p=222&q=biuuu
结果:
$_SERVER["QUERY_STRING"] = “p=222&q=biuuu”
$_SERVER["REQUEST_URI"] = “/index.php?p=222&q=biuuu”
$_SERVER["SCRIPT_NAME"] = “/index.php”
$_SERVER["PHP_SELF"] = “/index.php”
$_SERVER["QUERY_STRING"]获取查询语句,实例中可知,获取的是?后面的值
$_SERVER["REQUEST_URI"] 获取http://www.biuuu.com后面的值,包括/
$_SERVER["SCRIPT_NAME"] 获取当前脚本的路径,如:index.php
$_SERVER["PHP_SELF"] 当前正在执行脚本的文件名

代码
/**
__FILE__ ,
getcwd(),
$_SERVER["REQUEST_URI"],
$_SERVER["SCRIPT_NAME"],
$_SERVER["PHP_SELF"],
$_SERVER["SCRIPT_FILENAME"],

来观察一下这些变量或函数的异同.
假设有一个请求地址为: http://localhost:8080/test.php/age=20
而test.php 的完整路径是: D:/server/www/example/test.php
1) getcwd()
将得到浏览器请求的页面文件所在的目录. 即test.php 文件所在的目录: D:/server/www/example/ ,
如果在test.php 执行了 require 或 include 语句, 比如 inculde(”test_dir/test2.php”),
那么在 test2.php 里 getcwd()函数 返回的也将是 test.php 所在的目录.
2) __FILE__
一个魔术变量, 用它将得到 __FILE__ 变量所在文件的完整路径,
比如: test.php 里 __FILE__ 将得到 D:/server/www/example/test.php ,
test_dir/test2.php 里的 __FILE__ 将得到 D:/server/www/example/test_dir/test2.php

3) $_SERVER["SCRIPT_FILENAME"]
将得到浏览器请求的页面文件的完整路径.
test.php 和 test_dir/test2.php 里用 $_SERVER["SCRIPT_NAME"] 都将得到 D:/server/www/example/test.php.

4) $_SERVER["SCRIPT_NAME"]
将得到浏览器请求的页面文件的文件名,注意: 与 $_SERVER["SCRIPT_NAME"] 不同, 此变量只得到文件名而不包含路径,
在test.php 与 test_dir/test2.php 用$_SERVER["SCRIPT_NAME"] 得到的都将是 test.php.
当然, 在test.php 与 test_dir/test2.php 执行 basename($_SERVER["SCRIPT_FILENAME"]) 与 $_SERVER["SCRIPT_NAME"] 相同.
执行 在test.php 与 test_dir/test2.php 执行 realpath(”test.php”) 得到的结果与 $_SERVER["SCRIPT_FILENAME"] 相同.

5) $_SERVER["PHP_SELF"]
将得到浏览器请求页面的文件名, 并剥掉问号 ? 后的内容, 注意:不包含路径,
比如在客户端里请求 http://localhost:8080/test.php?age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php”。“age=20&name=Tom”被剥掉。
而如果客户端里请求 http://localhost:8080/test.php/age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["PHP_SELF"] 都将得到 “test.php/age=20&name=Tom”。

6) $_SERVER["REQUEST_URI"]
将得到浏览器请求页面的文件名, 以及文件名之后的所有内容(注意: 井号 # 之后的内容将被略去),
比如在客户端里请求 http://localhost:8080/test.php?age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["REUEST_URI"] 都将得到 “test.php”。“age=20&name=Tom”被剥掉。
而如果客户端里请求 http://localhost:8080/test.php/age=20&name=Tom,
那么test.php 和 test_dir/test2.php 的 $_SERVER["REQUEST_URI"] 都将得到 “test.php/age=20&name=Tom”。
*/

// test.php:
echo “test1.php variables
”;
echo “getcwd: “, getcwd(), “
”;
echo “__FILE__: “, __FILE__, “
”;
echo “REQUEST_URI: “, $_SERVER["REQUEST_URI"], “
”;
echo “SCRIPT_NAME: “, $_SERVER["SCRIPT_NAME"], “
”;
echo “PHP_SELF: “, $_SERVER["PHP_SELF"], “
”;
echo “SCRIPT_FILENAME “, $_SERVER["SCRIPT_FILENAME"] , “
”;

// 把 test2.php 包含进来, 在 test2.php 里输出上面的变量,看有什么不同:
include_once(”test2/test2.php”);

?>

来自: http://hi.baidu.com/abcfxr/blog/item/8cb5c5ff4e22ba3f5c600833.html

php联合查询详解

转自:http://hi.baidu.com/shiryu963/blog/item/aca86513887bca0a5baf5313.html

资料:

http://keke-wanwei.javaeye.com/blog/99162

http://hi.baidu.com/daweeforever/blog/item/a8831425e684296735a80f5e.html

http://sizhefang.javaeye.com/blog/212652

这几天碰到2个有点绕的查询:
1.
select * from 表A,表A子表

where 表A.FileCode = 表A子表.FileCode and 表A.ID

in (select 表A子表.ID from 表A子表 where

Vc_Code = ’1190′ AND Vc_Num =’111300′ AND Er_Num =’0101′);

这个查询的条件在子表,而结果在父表,没用关联查询,直接查询2个表

2.
SELECT * FROM

A表 AS A LEFT JOIN C表 AS C ON A.UID = C.EID ,

B表 AS B

WHERE A.U_ID = B.U_ID AND //A表和B表通过U_ID关联

B.D_ID IN (SELECT MAX(D_ID) FROM B表 GROUP BY U_ID) //要D_ID值最大的D_ID

AND B.CASEID = ’87′ //B表的一个字段值已知

AND A.STATUS = ’1′; //A表的一个字段值已知

关联查询总结:

1.UNION

格式:
查询语句

UNION [ALL] 查询语句

[UNION [ALL] 查询语句][…n]

说明:
ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一行。

在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:

查询1 UNION (查询2 UNION 查询3)

例子:
person表和user表没有约束
person表:

user表:

执行:select id,name from user UNION select id,name from person;

结果:

注意:sql句子栏目数必须是相同的,字段可以随意

2.JOIN

JOIN用于按照ON条件联接两个表,主要有四种:

(一)内连接

INNER JOIN:内部联接两个表中的记录,仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行。(表示交集)

(二)外连接

LEFT JOIN / LEFT OUTER JOIN:外部联接两个表中的记录,并包含左表中的全部记录。如果左表的某记录在右表中没有匹配记录,则在相关联的结果集中右表的所有选择列表列均为空值。理解为即使不符合ON条件,左表中的记录也全部显示出来,且结果集中该类记录的右表字段为空值。(差集)

RIGHT JOIN / RIGHT OUTER JOIN:外部联接两个表中的记录,并包含右表中的全部记录。简单说就是和LEFT JOIN反过来。(差集)

FULL JOIN / FULL OUTER JOIN: 完整外部联接返回左表和右表中的所有行。就是LEFT JOIN和RIGHT JOIN和合并,左右两表的数据都全部显示。(并集)

(三)交叉连接

交叉连接(cross join)不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

JOIN的基本语法(注意结果对比):

1.执行 select * from user as A join person as B on A.id=B.id;或
select * from user as A inner join person as B on A.id=B.id;

结果如下:

2.执行 select A.* from user as A join person as B on A.id=B.id;

3.执行select * from user as A left join person as B on A.id=B.id;

4.select * from person as A right join user as B on A.id=B.id;

5.full join
mysql 5不支持full join 所以用左关联和右关联进行联合
SELECT * FROM user
LEFT JOIN money ON user.id=money.id
UNION
SELECT * FROM user
RIGHT JOIN money ON user.id=money.id

6.执行 select * from user CROSS JOIN person;

正则表达式

目录
本文目标
如何使用本教程
什么是正则表达式?
入门
测试正则表达式
元字符
字符转义
重复
字符类
反义
替换
分组
后向引用
位置指定
负向位置指定
注释
贪婪与懒惰
平衡组
还有些什么东西没提到
一些我认为你可能已经知道的术语的参考
网上的资源及本文参考文献
第二版更新说明
本文目标
30分钟内让你明白正则表达式是什么,并对它有一些基本的了解,让你可以在自己的程序或网页里使用它。

如何使用本教程
别被下面那些复杂的表达式吓倒,只要跟着我一步一步来,你会发现正则表达式其实并不像你想像中的那么困难。当然,如果你看完了这篇教程之后发现自己明白了 很多,却又几乎什么都记不得,那也是很正常的——其实我认为没接触过正则表达式的人在看完这篇教程后能把提到过的语法记住80%以上的可能性为零。这里只 是让你明白基本道理,以后你还需要多练习,多查资料,才能熟练掌握正则表达式。

除了作为入门教程之外,本文还试图成为可以在日常工作中使用的正则表达式语法参考手册(就作者本人的经历来说,这个目标还是完成得不错的)。

文本格式约定:专业术语 元字符/语法格式 正则表达式 正则表达式中的一部分(用于分析) 用于在其中搜索的字符串 对正则表达式或其中一部分的说明

什么是正则表达式?
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

很可能你使用过Windows/Dos下用于文件查找的通配符(wildcard),也就是*和?。如果你想查找某个目录下的所有的word文档的话,你会搜索*.doc。在这里,*会被解释成任意的字符串。和通配符类似,正则表达式也是用来进行文本匹配的工具,只不过比起通配符它能更精确地描述你的需求——当然,代价就是更复杂。比如你可以编写一个正则表达式来查找所有以0开头,后面跟着2-3个数字,然后是一个连字号“-”,最后是7或8位数字的字符串(像010-12345678或0376-7654321)。

正则表达式是用于进行文本匹配的工具,所以本文里多次提到了在字符串里搜索/查找,这种说法的意思是在给定的字符串中,寻找与给定的正则表达式相匹配的部分。有可能字符串里有不止一个部分满足给定的正则表达式,这时每一个这样的部分被称为一个匹配。匹配在本文里可能会有三种意思:一种是形容词性的,比如说一个字符串匹配一个表达式;一种是动词性的,比如说在字符串里匹配正则表达式;还有一种是名词性的,就是刚刚说到的“字符串中满足给定的正则表达式的一部分”。

入门
学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改,实验。下面给出了不少简单的例子,并对它们作了详细的说明。

假设你在一篇英文小说里查找hi,你可以使用正则正则表达式hi。

这是最简单的正则表达式了,它可以精确匹配这样的字符串:由两个字符组成,前一个字符是h,后一个是i。通常,处理正则表达式的工具会提供一个忽略大小写的选项,如果选中了这个选项,它可以匹配hi,HI,Hi,hI这四种情况中的任意一种。

不幸的是,很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。

\b是正则表达式规定的一个特殊代码(好吧,某些人叫它元字符,metacharacter),代表着单词的开头或结尾,也就是单词的分界处。虽然通常英文的单词是由空格或标点符号或换行来分隔的,但是\b并不匹配这些单词分隔符中的任何一个,它只匹配一个位置。(如果需要更精确的说法, \b匹配这样的位置:它的前一个字符和后一个字符不全是\w)

假如你要找的是hi后面不远处跟着一个Lucy,你应该用\bhi\b.*\bLucy\b。

这里,.是另一个元字符,匹配除了换行符以外的任意字符。*同样是元字符,不过它代表的不是字符,也不是位置,而是数量–它指定*前边的内容可以重复任意次以使整个表达式得到匹配。因此,.*连在一起就意味着任意数量的不包含换行的字符。现在\bhi\b.*\bLucy\b的意思就很明显了:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词。

如果同时使用其它的一些元字符,我们就能构造出功能更强大的正则表达式。比如下面这个例子:

0\d\d-\d\d\d\d\d\d\d\d匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字(也就是中国的电话号码。当然,这个例子只能匹配区号为3位的情形)。

这里的\d是一个新的元字符,匹配任意的数字(0,或1,或2,或……)。-不是元字符,只匹配它本身——连字号。

为了避免那么多烦人的重复,我们也可以这样写这个表达式:0\d{2}-\d{8}

这里\d后面的{2}({8})的意思是前面\d必须连续重复匹配2次(8次)。

测试正则表达式
如果你不觉得正则表达式很难读写的话,要么你是一个天才,要么,你不是地球人。正则表达式的语法很令人头疼,即使对经常使用它的人来说也是如此。由于难于读写,容易出错,所以很有必要创建一种工具来测试正则表达式。

由于在不同的环境下正则表达式的一些细节是不相同的,本教程介绍的是Microsoft .Net 2.0下正则表达式的行为,所以,我向你介绍一个.Net下的工具Regex Tester。首先你确保已经安装了.Net Framework 2.0,然后下载Regex Tester,下载完后打开压缩包,运行setup.exe安装。

下面是Regex Tester运行时的截图

元字符
现在你已经知道几个很有用的元字符了,如\b,.,*,还有\d.当然还有更多的元字符,比如\s匹配任意的空白符,包括空格,制表符(Tab),换行符,中文全角空格等。\w匹配字母或数字或下划线或汉字。

下面来试试更多的例子:

\ba\w*\b匹配以字母a开头的单词——先是某个单词开始处(\b),然后是字母a,然后是任意数量的字母或数字(\w*),最后是单词结束处(\b)(好吧,现在我们说说这里的单词是什么意思吧:就是几个连续的\w。不错,这与学习英文时要背的成千上万个同名的东西的确关系不大)。

\d+匹配1个或更多连续的数字。这里的+是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。

\b\w{6}\b 匹配刚好6个字母/数字的单词。

表1.常用的元字符 代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束

元字符^(和6在同一个键位上的符号)以及$和\b有点类似,都匹配一个位置。^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$。

这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}匹配只能不多不少重复2次,{5,12}则是必须重复最少5次,最多12次,否则都不匹配。

因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。

和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配行的开始处和结束处。

字符转义
如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没法指定它们,因为它们会被解释成其它的意思。这时你就必须使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.

例如:www\.unibetter\.com匹配www.unibetter.com,c:\\windows匹配c:\windows,2\^8匹配2^8(通常这是2的8次方的书写方式)。

重复
你已经看过了前面的*,+,{2},{5,12}这几个匹配重复的方式了。下面是正则表达式中所有指定重复的方式:

表2.常用的限定符 代码/语法 说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

下面是一些使用重复的例子:

Windows\d+匹配Windows后面跟1个或更多数字

13\d{9}匹配以13后面跟9个数字(中国的手机号)

^\w+匹配一行的第一个单词(或整个字符串的第一个单词,具体匹配哪个意思得看选项设置)

字符类
要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集的元字符,但是如果你想匹配没有预定义元字符的字符集比如元音字母(a,e,i,o,u),怎么办?

很简单,你只需要在中括号里列出它们就行了,像[aeiou]就匹配任何一个元音字母,[.?!]匹配标点符号(.或?或!)(英文语句通常只以这三个标点结束)。注意,我们不需要写成[\.\?!]。

我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字,同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。

下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}。

这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字({2}),然后是)或-或空格中的一个,它出现1 次或不出现(?),最后是8个数字(\d{8})。不幸的是,它也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,请在本教程的下面查找答案。

反义
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:

表3.常用的反义代码 代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

例子:\S+匹配不包含空白符的字符串。

]+>匹配用尖括号括起来的以a开头的字符串。

替换
好了,现在终于到了解决3位或4位区号问题的时间了。正则表达式里的替换指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看例子:

0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。

\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}这个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。你可以试试用替换|把这个表达式扩展成也支持4位区号的。

\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用替换时,顺序是很重要的。如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配替换时,将会从左到右地测试每个分枝条件,如果满足了某个分枝的话,就不会去管其它的替换条件了。

Windows98|Windows2000|WindosXP这个例子是为了告诉你替换不仅仅能用于两种规则,也能用于更多种规则。

分组
我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复一个字符串又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。

(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1 到3位的数字,(\d{1,3}\.}{3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,最后再加上一个一到三位的数字 (\d{1,3})。

不幸的是,它也将匹配256.300.888.999这种不可能存在的IP地址(IP地址中每个数字都不能大于255)。如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组,选择,字符类来描述一个正确的IP地址: ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。

理解这个表达式的关键是理解2[0-4]\d|25[0-5]|[01]?\d\d?,这里我就不细说了,你自己应该能分析得出来它的意义。

后向引用
使用小括号指定一个子表达式后,匹配这个子表达式的文本可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。难以理解?请看示例:

\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, kitty kitty。首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),然后是1个或几个空白符(\s+,最后是前面匹配的那个单词(\1)。

你也可以自己指定子表达式的组号或组名。要指定一个子表达式的组名,请使用这样的语法:(?\w+),这样就把 \w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k,所以上一个例子也可以写成这样: \b(?\w+)\b\s*\k\b。

使用小括号的时候,还有很多特定用途的语法。下面列出了最常用的一些:

表4.分组语法 捕获
(exp) 匹配exp,并捕获文本到自动命名的组里
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本
位置指定
(?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(? 注释
(?#comment) 这种类型的组不对正则表达式的处理产生任何影响,只是为了提供让人阅读注释

我们已经讨论了前两种语法。第三个(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面。

位置指定
接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们用于指定一个位置,就像\b,^,$那样,因此它们也被称为零宽断言。最好还是拿例子来说明吧:

(?=exp)也叫零宽先行断言,它匹配文本中的某些位置,这些位置的后面能匹配给定的后缀exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如果在查找I'm singing while you're dancing.时,它会匹配sing和danc。

(?<=exp)也叫零宽后行断言,它匹配文本中的某些位置,这些位置的前面能给定的前缀匹配exp。比如(?<=\bre) \w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\d)\d{3})*\b。请仔细分析这个表达式,它可能不像你第一眼看出来的那么简单。

下面这个例子同时使用了前缀和后缀:(?<=\s)\d+(?=\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)。

负向位置指定
前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:

\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。但是如果多做测试(或者你思维足够敏锐,直接就观察出来了),你会发现,如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。这是因为[^u]总是匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w+\b将会匹配下一个单词,于是\b\w*q[^u] \w*\b就能匹配整个Iraq fighting。负向位置指定能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u) \w*\b。

零宽负向先行断言(?!exp),只会匹配后缀exp不存在的位置。\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字。

同理,我们可以用(?

一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。()指定了这样的前缀:被尖括号括起来的单词(比如可能是),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的 (\w+)匹配的内容,这样如果前缀实际上是的话,后缀就是了。整个表达式匹配的是和< /b>之间的内容(再次提醒,不包括前缀和后缀本身)。
转自:http://www.blue1000.com/bkhtml/2007-10/54467.htm

php入门教程

在 PHP 中创建和使用表单 第 1 页(共12 页)

开发人员创建 PHP 是为了开发一种 Web 编程语言。事实上,虽然可以从命令行中运行 PHP,但很少有人在 Web 应用程序领域之外使用这种语言。结果,PHP 程序员最常见的任务就是使用 Web 表单。

使用 HTML 创建 Web 表单,当用户提交表单时,浏览器向服务器发送一个信息数组。

这一节将讨论数组和使用表单数据的方式,以及控制 PHP 脚本流的方法,如循环和 if-then 语句。

用 HTML 创建表单 第 2 页(共12 页)

首先来创建应用程序的注册页面。最终,用户将在这里输入他们的信息,而您则需要在将这些信息保存到数据库之前验证 它们或者检查它们的完整性。但现在,我们只需要创建一个基本的表单。创建一个命名为 registration.php 的新文件,在该文件中添加以下内容:



Register for an Account:

Username:
Email:
Password:


这是一个简单的表单(在 form 元素中),其中有两个文本输入字段、一个口令字段和一个提交按钮。如果将该文件保存到文档根目录(registration_action.php)中,那么输入各字段后的结果将如图 3 所示。

图 3. 帐户注册表单
帐户注册表单

注意,口令输入框中没有显示实际输入的内容。那么单击 GO 按钮后会出现什么样的情况呢?

提交表单 第 3 页(共12 页)

创建表单时,创建了一个真正的 form 元素,如下所示:

该元素有两部分信息。首先,action 告诉浏览器将信息发送到何处,在这里是发送到前面创建的 registration_action.php 页面。其次,method 告诉浏览器如何发送数据。

让我们看看这些操作是如何实现的。填充一些数据并单击 GO 按钮,结果将如图 4 所示。

图 4. 输出数据
输出数据

这里,您并没有提交它所说的信息,但这是因为您还没有修改并查看提交数据的页面。看看 URL 就知道了。

http://localhost/registration_action.php?name=roadnick&email=

ibmquestions%40nicholaschase.com&pword=supersecretpassword

注意,每个表单元素都有一个名称,URL 中包含用地址符号(&)分隔的名值对。URL 采用这种格式是因为使用了 GET 方法。在 使用 POST 一节中,还将介绍这些内容,不过,让我们首先来看看如何从 PHP 页面中检索数据。

访问表单数据 第 4 页(共12 页)

现在已经提交了表单,还要将数据放到真正的响应页面 registration_action.php 中,对该文件做如下更改:


You entered:

$username = $_GET['name'];
$password = $_GET['pword'];

echo "

Username = ” . $username . “

“;
echo “

Password = ” . $password . “

“;
?>


要做的就是从 $_GET 数组中取得命名的值。后面还将进一步讨论数组,目前要注意的是,刷新浏览器后,真正的应答页面将如图 5 所示。

图 5. 浏览器中的正确信息
浏览器中的正确信息

可以按照名称取得所有提交的信息,因为这是一个数组,所以还可通过其他的方式。

数组 第 5 页(共12 页)

PHP 允许创建数组或者值列表,从而方便地同时移动一组数据。比如,可以创建一个数组并将其值输出到页面中,如下所示:

$formnames = array(“name”, “email”, “pword”);
echo “0=”.$formnames[0].”
“;
echo “1=”.$formnames[1].”
“;
echo “2=”.$formnames[2].”
“;

array() 函数返回一个值,这个例子中返回的值恰好是一个数组。(函数在后面讨论,现在只要知道调用函数,并为函数的返回值赋给一个变量即可。)

上述脚本的输出如下:

0=name
1=email
2=pword

注意,第一个值的索引号是 0 而不是 1。 此外,通过在数组变量名后的方括号中使用索引可以指定需要的任意值。这项操作与访问表单数据的方式类似,这并不是偶然的。$_GET 变量是一种特殊类型的数组,称为关联(associative)数组,也就是说,每个值不使用数字索引,而使用 key。

提交表单的时候,实际上创建了以下这样一个数组:

$_GET = array(“name” => “roadnick”,
“email” => “ibmquestions@nicholaschase.com”,
“pword” => “supersecretpassword”);

这就是能够提取每个值(如 $_GET["name"])的原因。不过不需要分别提取。

访问数组信息 第 6 页(共12 页)

在处理数据时,使用关联数组非常方便,但经常会遇到不知道数组结构是什么样的情形。比如,您可能创建了一个通用数据库例程,从查询中接受一个关联数组。

幸运的是,PHP 提供的两个函数简化了此操作:

You entered:

$form_names = array_keys($_GET);
$form_values = array_values($_GET);

echo "

” . $form_names[0] . ” = ” . $form_values[0] . “

“;
echo “

” . $form_names[1] . ” = ” . $form_values[1] . “

“;
echo “

” . $form_names[2] . ” = ” . $form_values[2] . “

“;
?>


array_keys() 和 array_values() 函数都返回普通的数字索引数组,因此可以使用数字索引从这两个数组中获取信息,如图 6 所示。

图 6. 使用数字索引提取数据
使用数字索引提取数据

还应该有更方便的办法。比方说,如果不知道有多少个值,该怎么办?PHP 提供了处理关联数组的多种方式,而使用哪一种最方便则由已经掌握的信息决定。我们来看看完成同样任务的其他方法。

使用 for-next 循环 第 7 页(共12 页)

PHP 中最常见的一项任务是遍历一组值。使用 for-next 可以很轻松地完成这项操作。for-next 循环按照定义遍历一组值。比如下面的循环:

for ($i = 0; $i < 10; $i++) {
echo $i . " ";
}

生成的结果为:

0 1 2 3 4 5 6 7 8 9

PHP 首先把 0 赋给 $i,这是在循环一开始定义的,只要 $i 小于 10,循环就会继续下去,每执行一次循环,PHP 就会把 $i 的值加一。

也就是说,如果知道 $_GET 数组中有多少个值(可以做到),那么很容易使用下面的形式遍历其中的每个值:

You entered:

$form_names = array_keys($_GET);
$form_values = array_values($_GET);

for ($i = 0; $i < sizeof($_GET); $i++) {
echo "

“.$form_names[$i].” = ” . $form_values[$i] . “

“;
}
?>


sizeof() 告诉您 $_GET 数组中包含多少个值。可以使用这个数据确定什么时候结束循环,如图 7 所示。

图 7. 使用 sizeof 函数结束循环
使用 sizeof 函数结束循环

因为 $_GET 是关联数组,实际上还有另一种选择:foreach 循环。

使用 foreach 循环 第 8 页(共12 页)

关联数组在 PHP 中很常见,该语言提供了一种很简单的方法来获得其中的数据,不需要经过提取键和值的过程。使用 foreach 循环可以直接操纵这类数组。比如下面的代码:


foreach ($_GET as $value) {
echo "

” . $value . “

“;
}
?>

PHP 第一次执行该循环时,会从 $_GET 数组中取得第一个值,然后将该值赋给 $value 并输出它。然后,返回到循环的顶部,把下一个值赋给 $value,依次处理 $_GET 中的每个值(也包括名称)。最终的结果如下:

roadnick

ibmquestions@nicholaschase.com

supersecretpassword

更方便的是,它还能提取值和键:


foreach ($_GET as $key=>$value) {
echo “

“.$key.” = ” . $value . “

“;
}
?<
...

于是又得到了最初的结果:

图 8. 最初的结果
最初的结果

多表单值 第 9 页(共12 页)

对于表单值,还需要处理偶尔出现的情况:一个名称具有多个表单值。比如,由于用户看不到输入的口令,您可能希望他们输入两次进行确认,以避免发生错误:

...
Username:
Email:
Password:
Password (again):

注意,pword字段名稍做了修改。因为将检索多个值,所以需要将 password 本身看成一个数组。也就是说,一个数组值本身也是另一个数组。提交该表单时,得到的 URL 将是:

http://localhost/registration_action.php?name=roadnick&email=ibmquestions%40nicholas

chase.com&pword[]=supersecretpassword&pword[]=supersecretpassword

提交表单相当于创建下面的数组:

$passwords = array(“supersecretpassword”, “supersecretpassword”);
$_POST = array(“name”=>”roadnick”,
“email”=>”ibmquestions@nicholaschase.com”,
“pword”=>$passwords);

这意味着如果查看口令值,则必须将该值作为数字数组来访问,例如:


foreach ($_GET as $key=>$value) {
echo “

“.$key.” = ” . $value . “

“;
}

$passwords = $_GET["pword"];
echo “First password = “.$passwords[0];
echo “
“;
echo “Second password = “.$passwords[1];

提交改变单(或者刷新页面)就会看到其中的差别,如图 9 所示。

图 9. 提交表单
提交表单

注意,password 字段是作为 Array 输出的,但是您可以直接访问它的值。

GET 和 POST 第 10 页(共12 页)

到目前为止,提交数据使用的一直是 GET 方法,这种方法将数据放在 URL 中。这样做有时候很合适,但有时候不合适。比如,可以通过这种技术使用链接来模仿表单的提交,但是如果有大量的数据,比方说数据来自 textarea(用户可以输入注释),那么这种技术就不是达到目标的最佳方法。因为,Web 服务器通常限制能够在 GET 请求中接收的字符个数。

另外,好的技术和标准需求告诉我们,永远不要使用 GET 执行有“副作用”的操作或者真正做 什么事情的操作。比如说,现在我们只是查看数据,这不会带来什么副作用。但是,如果要将数据添加到数据库中,按照定义,这就是有副作用的操作。

很多 Web 程序员不知道这种特殊的限制,因此可能造成问题。使用 GET,特别是将它作为 URL 使用,可能导致系统多次执行一项操作,因为用户将其添加到了收藏夹中,或者搜索引擎正在建立该 URL 的索引, 并不知道实际上是在更新数据库或者执行其他某项操作。

因此,在这种情况下必须使用 POST。

使用 POST 第 11 页(共12 页)

使用 POST 方法代替 GET 方法实际上非常简单。首先需要修改 registration.php 页面:

Register for an Account:

Username:

现在,当提交该表单时,URL 会变得非常干净:

http://localhost/registration_action.php

要检索数据,需要使用 registration_action.php 中的 $_POST 数组,而不是 $_GET 数组:


You entered:

foreach ($_POST as $key=>$value) {
echo “

“.$key.” = ” . $value . “

“;
}

$passwords = $_POST["pword"];
echo “First password = “.$passwords[0];
echo “
“;
echo “Second password = “.$passwords[1];
?>


使用 $_POST 数组的方式与使用 $_GET 数组的方式相同。

错误检查:if-then 语句 第 12 页(共12 页)

转入下一节之前,如果无法确保两者匹配,那么要求用户两次输入口令就没有任何意义。因此需要使用 if-then 语句:


$passwords = $_POST["pword"];
echo “First password = “.$passwords[0];
echo “
“;
echo “Second password = “.$passwords[1];

if ($passwords[0] == $passwords[1]) {
echo “

Passwords match. Thank you.

“;
} else {
echo “

Passwords don’t match. Please try again.

“;
}

在 if-then 语句中,如果括号中的表达式(该例中为 $passwords[0] == $passwords[1])成立,那么 PHP 将执行第一对括号中的语句,否则不执行。这里还需要包括该语句不成立时需要执行的操作。

要注意的是,这里不是单个等号的 $passwords[0] = $passwords[1],而是双等号的 $passwords[0] == $passwords[1]。双等号是比较运算符,实际上检查两者是否相等。单等号是赋值运算符。如果使用单等号,执行该语句时,PHP 将把 $passwords[1] 的值赋给 $passwords[0],这显然违背了您的意愿。

该例中,如果口令不匹配,那么页面上会发出警告,如图 10 所示。

图 10. 口令不匹配发出的警告
口令不匹配

还有两个方便的运算符,与运算符(&&)和或运算符(||)。比如,可以说:

if (($today == “Monday”) && ($status == “Not a holiday”)) {
echo “GO TO WORK!!!”;
}

在上面的例子中,只有当今天是星期一并且不是节假日时,表达式才成立。但对于或运算符,只要有一个条件成立,就会返回 true。

转自:http://home.phpchina.com/space.php?uid=14637&do=blog&id=3467

发表在 php

Air执行本地exe

这里是一个adobe论坛上air执行cmd的例子。
原连接:http://forums.adobe.com/thread/727337?tstart=1

protected var npsi:NativeProcessStartupInfo;
protected var nativeProcess:NativeProcess;
protected var file:File = new File("c:\\windows\\system32\\cmd.exe");
protected var args:Vector.<String> = new Vector.<String>;

protected function init():void
{

args.push(‘ping’)
args.push(‘www.adobe.com’)

npsi = new NativeProcessStartupInfo();
npsi.arguments = args;
npsi.executable = file;

nativeProcess = new NativeProcess();
nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA,onStandardOutputData);
nativeProcess.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onError);
nativeProcess.start(npsi);
nativeProcess.standardInput.writeUTFBytes(args + “\n”);
}

private function onError(event:ProgressEvent):void {

var process:NativeProcess = event.target as NativeProcess;
var data:String = process.standardError.readUTFBytes(process.standardError.bytesAvailable);
lbl.text += data;

}

private function onStandardOutputData(event:ProgressEvent):void
{
var process:NativeProcess = event.target as NativeProcess;
var data:String = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable);
lbl.text += data
}

这里也有个blog上写的方法 原理一样。

http://technodesk.wordpress.com/2010/04/15/air-2-0-native-process-batch-file/


public function launchBatchFile():void{
var file:File = File.applicationDirectory;
file = file.resolvePath("C:\\Windows\\System32\\cmd.exe");
var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
NativeProcessStartupInfo.executable = file;
nativeProcessStartupInfo.workingDirectory = File.applicationDirectory.resolvePath();
var args:Vector = new Vector();
args.push();
args.push(); // Repeat this to pass all the arguments
nativeProcessStartupInfo.arguments = args;
var process:NativeProcess = new NativeProcess();
process.start(nativeProcessStartupInfo);
process.addEventListener(NativeProcessExitEvent.EXIT, exitHandler);
}

protected function exitHandler(event:NativeProcessExitEvent):void{
Alert.show("Execution Complete");
}

相关讨论的主题有:

http://hi.baidu.com/sl19880127sl/blog/item/1405ca13b12a04ddf6039e61.html

http://www.riameeting.com/node/487

http://efreedom.com/Question/1-2763139/Flex3-Air-NativeProcess-Accepts-Standard-Input-Data-Error-2044-3218

http://hi.baidu.com/sl19880127sl/blog/item/d6894c3375fe8ef51b4cffd6.html

air保存文件

public function saveFile(byteArray:ByteArray):void
{
var file:File = new File(File.applicationDirectory.nativePath);
file = file.resolvePath(“123.abc”);//123表示文件名,abc表示文件格式
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.writeBytes(byteArray);
stream.close();
}