手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表分类:PHP

PHP语言中global和$GLOBALS[]的分析

原来以为global和$GLOBALS除了写法不一样以为,其他都一样,可是在实际应用中发现,2者的区别还是很大的!
先看下面的例子:

PHP代码
  1. <?php  
  2. // 例子1  
  3. function test_global() {  
  4.   global $var1$var2;  
  5.   $var2 =& $var1;  
  6. }  
  7. function test_globals() {  
  8.   $GLOBALS['var3'] =& $GLOBALS['var1'];  
  9. }  
  10. $var1 = 5;  
  11. $var2 = $var3 = 0;  
  12. test_global();  
  13. print $var2 ."\n";  
  14. test_globals();  
  15. print $var3 ."\n";  
  16. ?>   

执行结果为:
0
5

怎么会这样呢?不应该是2个5吗?怎么会出现1个0和1个5呢?

恩,我们保留以上问题,深入分析$GLOBALS和global的原理!

我们都知道变量其实是相应物理内存在代码中的"代号",假设我们上面声明的3个变量分配的内存如下图表示:

引用php手册的$GLOBALS的解释:

Global 变量:$GLOBALS
注意: $GLOBALS 在 PHP 3.0.0 及以后版本中适用。

由所有已定义全局变量组成的数组。变量名就是该数组的索引。

这是一个“superglobal”,或者可以描述为自动全局变量。
也就是说上面代码中的$var1和$GLOBALS['var1']是指的同一变量,而不是2个不同的变量!

下面来分析global到底做了什么?

我们都知道php中的函数所产生的变量都是函数的私有变量,那么global关键字产生的变量也肯定逃不出这个规则,为什么这么说呢,看下面的代码:

PHP代码
  1. <?php  
  2. // 例子2  
  3. function test() {  
  4.   global $a;  
  5.   unset($a);  
  6. }  
  7.   
  8. $a = 1;  
  9. test();  
  10. print $a;  
  11. ?>   

复制代码
执行结果为:
1
为什么会输出1呢?不是已经把$a给unset了吗?unset失灵了?php的bug?

都不是,其实unset起作用了,是把test函数中的$a给unset掉了,可以在函数后面加入
print $a;
复制代码
来测试!也就是说global产生了test函数外部$a的别名变量“$a”,为了和外面的$a区别,我把它成为--test->$a,那么例子1也这么命名的话,可得出下面的图:
[没有图,谢谢,忽悠你的]



接着回到上面的例子1,看test_global中的这一代码“$var2 =& $var1;”,上面是一个引用赋值运算,也就是$var2将指向var1所指向的物理内存地址,所以例子1执行过test_global函数以后,变量的变化由下图可以看出:
[没有图,谢谢,忽悠你的]
而test_globals执行过以后,看变量的变化:

此时,看图,就能理解为什么例子1执行完以后,$var2是0,而$var3是5了!

所以我们得出一个结论,在函数中global和$GLOBALS[]的区别在于:

global在函数产生一个指向函数外部变量的别名变量,而不是真正的函数外部变量,一但改变了别名变量的指向地址,就会发生一些意料不到情况,例如例子1.

$GLOBALS[]确确实实调用是外部的变量,函数内外会始终保持一致!

文章来自:向东的博客,http://www.xiangdong.org/blog/post/1749/

Tags: global

Open Fetion -- Implement Fetion Protocol with PHP

最近一段时间,飞信可以说是被人研究的很彻底呀。估计中国移动是笑的咧不开嘴了。
虽然用飞信软件的人不是特别多,但根据飞信协议做二次、三次开发的并不少,好象很多应用都与原来飞信想法不太一样,但这有什么关系呢?用户数才是王道。

Open Fetion -- Implement Fetion Protocol with PHP,是一个SF上的项目,用PHP来实现飞信功能,具体使用方法如下:

Usage: fetion [options] user_mobile password
fetion [options] user_mobile password sendto_sid content

* if no sendto_sid specified, all available sid will be displayed
* you can not send sms to yourself
* use sid as 'sendto_sid' instead of mobile number or fetion number
-p

Tags: fetion, protocol

避免在 HTML 头部使用注解

这个问题我从来没有遇到过,所以感觉很新鲜。
希望遇到这个问题的朋友看到后能够有恍然大悟的感觉。当然事实上很多情况是,不会有人在头部加注释。。

原文:http://blog.linym.net/archives/474(全部翻译成简体了。。原文是繁体)
前几天学弟问我一个问题,说他CSS排版的网页在大部分浏览器都正常,唯独IE怪怪的,网页中的DIV元素怎么样都无法居中,困扰了他许久,他的原始代码内容大致如下:

<!-- Head area -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test Page</title>
<style type="text/css">
<!--
#content {
margin: 0 auto;
width: 500px;
}
-->
</style>
</head>

<body>
<!-- Content Begin -->
<div id="content">Content</div>
<!-- Content End -->
</body>
</html>
嗯。看起来不应该会有什么问题,那是什么原因让IE无法将DIV居中呢?突然注意到他网页头问那一行注释,因为自己写网页到现在从未在头部使用过注释

果然,拿掉以后就一切正常了。IE,还真是搞不懂你啊!
(注:全系列 IE 都有此现象)

Tags: html

增强网站易用性的10个设计技巧

这是一篇来自博客园的文章,感觉里面的一些知识点不错。最后那张图是我一直想要找没有找到的。好像记得每年都会有这种用户行为征测的报告出来,但,因为不知道术语是什么,也就没有找到过。做商业网站的时候,了解这种行为非常重要,只有这样才能知道把重点放在什么位置。

原文:http://www.cnblogs.com/cocowool/archive/2009/05/01/1447466.html

作者:小狼的世界

易用性是什么?

易用性就是是你的网站对用户来说使用更简单,能够让用户在他需要的地方很快找到需要的信息。类比于Google所提倡的”让用户呆在Google的时间不短缩短“,对于网站来说,我们不是减少用户在网站的停留时间,而是缩短用户寻找关键信息和向导的时间。

很多人认为要实现网站的易用性需要耗费大量的人力、财力和物力,确实有很多的大网站他们投入了很多的钱和设备去做网站的易用性的研究和测试,但是对于我们日常的小网站来说,我们仍有方法在没有专家和专业设备的基础上改进网站的易用性。

一、包含宣传词(Tagline)。

宣传词是一个用来表明公司理念、目标或者网站愿景的地方。这一部分应该是网站最引人瞩目的部分,应该用简短的语言概括站点。统计结果表明,一个页面只有8秒钟的时间来吸引一个用户继续他的浏览,所以如果不能用醒目的焦点吸引用户,那这个页面就是失败的。

国外的站点很多使用Tagline或者醒目的Flash,国内的站点也可以 这么用,有的时候内容多的时候,还可以是Banner+焦点图,这个要区分不同的网站类型来对待。例如对于产品型的网站,完全可以只使用一个焦点图或者醒 目的有特色的Flash来吸引注意,如果是资讯类的或者专题类的页面,则可能既要有Banner,来突出这个页面的主题,也要有焦点图,来显示最近的一些 动态。这个需要在制作的过程中不断地体会积累。
大小: 29.91 K
尺寸: 500 x 204
浏览: 1720 次
点击打开新窗口浏览全图
大小: 36.74 K
尺寸: 500 x 204
浏览: 1818 次
点击打开新窗口浏览全图

大小: 342.25 K
尺寸: 500 x 172
浏览: 1931 次
点击打开新窗口浏览全图

二、提供站内搜索。

站内搜索对于用户来说也是非常重要的,特别是当站点的内容量开始逐渐增多以至于用户不能很轻易的找到他想要的东西时,用户往往会想到搜索。 你能想象到,要在博客园里通过连接一个一个查找你之前看到过的某一篇文章的痛苦吧。

搜索框的长度和位置也需要加一点注意,不能太小,位置最好放在右上区域,因为根据用户的浏览习惯呈现出”F“的趋势(F Pattern),提交按钮的文字最好能够明确的告诉用户,接下来将要发生的动作是搜索。
大小: 20.78 K
尺寸: 500 x 135
浏览: 1808 次
点击打开新窗口浏览全图

三、不能滥用图片。

 从易用性的角度来看,Less Is Always More。

四、使用站点地图。

站点地图是一项能够改进站内导航和搜索引擎优化(SEO)的特性。典型的站点地图提供了站点的结构和各个页面的导航。站点地图可以是任何形式的,可以是一个网页、一些页面的列表,只要他们是按照层级关系组织起来的就行。

最近,Google、Yahoo、MSN开始提供Sitemap Protocol的服务,同站点地图非常相近,但是数据是以XML的形式组织的。

 

五、不要破坏工作流。

工作流是指用户在网站上所进行的操作,比如填写表单、注册用户、浏览目录、档案等,要允许用户撤销操作,如果没有提供后退或者返回的选项,用户就被逼着做他们不想做的动作,或者他们会干脆关掉浏览器来图个清净。

有些站点上的操作顺序并不是那么的明显,这个时候就需要有提示来指导用户。比如Yahoo Music当第一次进入的时候,会有一个向导来指导你一步一步的熟悉页面上各个功能区。玩游戏的时候也会有游戏教学这个环节,如果网站上也提供了,会带来很好的用户体验。

还有一个误区是改变超链接的样式。传统的门户往往让超链接停留在他原始的样子,这样能够给用户明确的指示,这是一个超链接,通过点击,我可以进入一 个新的页面。当然,我并不赞成超链接的样式一定不能改变,但是如果发生了改变,我们一定需要通过图示或者文字来表明,用户可以通过点击这个链接到达另外一 个页面。

六、让网站更容易被”扫描“。

内容的可读性能够提高用户的忠诚度,让用户停留在站点上获得他们需要的内容。但是研究表明,很多用户并不是在读页面,而是在”扫描“,通过扫描标题、着重文字、强调的列表来获得信息。

Jacbo Nilsen通过视觉追踪发现用户的浏览很像一个F型,他们从左到用从上到下的”扫描“页面。

大小: 46.47 K
尺寸: 500 x 222
浏览: 1884 次
点击打开新窗口浏览全图

他的实验同时也得出了一下结论:

用户不是一个字一个字的去阅读,而是从段落、着重文字中提取信息。

 文章的前两段非常的重要,这两段必须包括这篇文章的大部分内容。

副标题和列表能够重新引起用户的注意,注意用这些元素来强调重要的内容。

从传统的纸质媒体上得来的经验也告诉我们,将内容组织成一个倒金字塔型。关键问题是,我们如何才能知道什么信息对用户来说是重要的,那些信息对用户来说又是不重要的,作者推荐了一个工具:News Values。

七、不要设计容易误导的界面元素。

千万不要设计那种看上去像是一个按钮实际上不是的内容,我们也经常被那些带下划线的文字误导,当我们点击时,发现他们根本不是链接!

Yahoo是一个很好的正面的例子。

八、给出用户有意义的提示。

这一点大家应该都有共识了,不要将出错信息直接输出到页面上,要给出用户经过处理的、用户能够理解的信息。

九、不要过度使用Javascript。

过度的使用Javascript和Ajax技术,我们需要小心的避免出现浏览器兼容性问题,我们要很好的衡量这个代价。

十、避免验证符。

验证符的使用在必须的地方添加,如果不是那么必要,还是要符合人类懒惰的本性,去掉那些验证符吧。

 

总结:提升网站的易用性并不一定需要墨守成规,但是在没有足够的功力之前,这些规则能够为我们提供一个很好的方向指向。对于这些规则的争论也很多, 比如避免验证符的使用,在很多情况下,我们必须使用验证符来避免垃圾信息的产生,就像坐飞机时的安检,虽然是一件让人不舒服的事情,可是他有他的目的。

 网站的易用性也不是网站的全部,我们必须在易用性、页面设计、站点的可维护性和安全性之间权衡,对不同类型的项目采取不同的处理策略。

参考资料:

[1]、http://www.webdesignerdepot.com/2008/12/10-usability-tips-for-web-designers/

[2]、http://www.useit.com/

[3]、News Values。http://mtsu32.mtsu.edu:11178/171/newsvals.htm#top

Tags: 网站设计, 易用性

[向东]简单的PHP的任务队列

来自向东:http://www.xiangdong.org/blog/post/1743/

文章太长,不作过多介绍,反正,文章的头部就说明了大概的意思。。。
原文如下:
写了一个简单的队列任务处理。多进程任务,异步任务可能会用到这个(主要是命令行应用)
比如,任务的某个一个环节速度十分不稳定,可能执行几秒,也可能执行几分钟,
我就可以把那个环节包括前面的部分扔进队列,多跑几个进程,同时往队列里面写。
然后后面比较快的环节只跑一个处理任务就OK了。让整体速度达到更好的效果。

write.php: 将任务写入队列

PHP代码
  1. <?php  
  2. /* 
  3. 产生队列 
  4. */  
  5. //用微秒生成队列文件名。因为会有多个队列,所以加了一个identifier来区分各个队列  
  6. function mt($identifier='default')  
  7. {  
  8.         return sprintf("%.6f.%s",strtok(microtime(),' ')+strtok(''),$identifier);  
  9. }  
  10.   
  11. while(1) //实际中尽量不要while(1) 非要while(1)记得任务完成要break  
  12. {  
  13.         if(count(glob('./queue/*.identifier'))>=10) //队列最大长度,不限制的话硬盘可能会受不了哦。  
  14.         {  
  15.                 sleep(1);//记住这里要sleep,否则队列满了cpu占用很高  
  16.                 continue;  
  17.         }  
  18.         $url = 'www.'.time().'.com'//随便举个例子,我用时间戳生成了一个网址  
  19.         echo "$url\r\n";  
  20.         $fp = fopen('./queue/'.mt('identifier'),'w');  
  21.         fwrite($fp,$url);  
  22.         fclose($fp);  
  23.         sleep(1);//这里不需要sleep,我sleep是因为我的任务太简单。  
  24. }  
  25. ?>  

read.php:

PHP代码
  1. <?php  
  2. /* 
  3. 处理队列 
  4. */  
  5.   
  6. while(1) //实际程序最好不要while(1)如果while(1),记得处理完任务要break  
  7. {  
  8.         if($queue = glob('./queue/*.identifier'))  
  9.         {  
  10.                 $q = array_shift($queue);  
  11.                 $url = file_get_contents($q);  
  12.                 echo $url."\r\n";  
  13.                 unlink($q);  
  14.         }  
  15.         sleep(1);//这里要不要sleep或sleep多久自己凭感觉来。  
  16. }  
  17. ?>  

相关的资料:双向队列

baidu和google上没有查到PHP双向队列的资料,搜索到java的双向队列定义如下:双向队列(双端队列)就像是一个队列,但是你可以在任何一端添加或移除元素。
而双端队列是一种数据结构,定义如下:
A deque is a data structure consisting of a list of items, on which the following operations are possible.
* push(D,X) -- insert item X on the rear end of deque D.
* pop(D) -- remove the front item from the deque D and return it.
* inject(D,X) -- insert item X on the front end of deque D.
* eject(D) -- remove the rear item from the deque D and return it.
Write routines to support the deque that take O(1) time per operation.

翻译:双端队列(deque)是由一些项的表组成的数据结构,对该数据结构可以进行下列操作:
push(D,X) 将项X 插入到双端队列D的前端
pop(D) 从双端队列D中删除前端项并将其返回
inject(D,X) 将项X插入到双端队列D的尾端
eject(D) 从双端队列D中删除尾端项并将其返回
编写支持双端队伍的例程,每种操作均花费O(1)时间

百度百科:(deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构。双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行。

转贴一个使用Php数组函数实现该功能的代码:

PHP代码
  1. <?php  
  2. //Input limit double-ende queue  
  3. class DoubleEndedQueue1 {  
  4. var $queue = array();  
  5. function add($var){  
  6.     return array_push($this->queue, $var);  
  7. }  
  8. function frontRemove(){  
  9.     return array_shift($this->queue);  
  10. }  
  11. function rearRemove(){  
  12.     return array_pop($this->queue);  
  13. }  
  14. }  
  15.   
  16. //Output limit double-ende queue  
  17. class DoubleEndedQueue2 {  
  18. var $queue = array();  
  19. function remove(){  
  20.     return array_pop($this->queue);  
  21. }  
  22. function frontAdd($var){  
  23.     return array_unshift($this->queue, $var);  
  24. }  
  25. function rearAdd($var){  
  26.     return array_push($this->queue, $var);  
  27. }  
  28. }  
  29.   
  30. //Test code  
  31. $q = new DoubleEndedQueue1;  
  32. $q->add('aaa');  
  33. $q->add('bbb');  
  34. $q->add('ccc');  
  35. $q->add('ddd');  
  36.   
  37. echo $q->frontRemove();  
  38. echo "<br>";  
  39. echo $q->rearRemove();  
  40. echo "<br>";  
  41. print_r($q->queue);  
  42. ?>  
array_push -- 将一个或多个单元压入数组的末尾(入栈)
array_unshift -- 在数组开头插入一个或多个单元
array_pop -- 将数组最后一个单元弹出(出栈)
array_shift -- 将数组开头的单元移出数组

// 来自 PHP5 in Practice  (U.S.)Elliott III & Jonathan D.Eisenhamer
PHP代码
  1. <?php  
  2. // A library to implement queues in PHP via arrays  
  3. // The Initialize function creates a new queue:  
  4. function &queue_initialize() {  
  5.     // In this case, just return a new array  
  6.     $new = array();  
  7.     return $new;  
  8. }  
  9. // The destroy function will get rid of a queue  
  10. function queue_destroy(&$queue) {  
  11.     // Since PHP is nice to us, we can just use unset  
  12.     unset($queue);  
  13. }  
  14. // The enqueue operation adds a new value unto the back of the queue  
  15. function queue_enqueue(&$queue$value) {  
  16.     // We are just adding a value to the end of the array, so can use the  
  17.     //  [] PHP Shortcut for this.  It's faster than using array_push  
  18.     $queue[] = $value;  
  19. }  
  20. // Dequeue removes the front of the queue and returns it to you  
  21. function queue_dequeue(&$queue) {  
  22.     // Just use array unshift  
  23.     return array_shift($queue);  
  24. }  
  25. // Peek returns a copy of the front of the queue, leaving it in place  
  26. function queue_peek(&$queue) {  
  27.     // Return a copy of the value found in front of queue  
  28.     //  (at the beginning of the array)  
  29.     return $queue[0];  
  30. }  
  31. // Size returns the number of elements in the queue  
  32. function queue_size(&$queue) {  
  33.     // Just using count will give the proper number:  
  34.     return count($queue);  
  35. }  
  36. // Rotate takes the item on the front and sends it to the back of the queue.  
  37. function queue_rotate(&$queue) {  
  38.     // Remove the first item and insert it at the rear.  
  39.     $queue[] = array_shift($queue);  
  40. }  
  41. // Let's use these to create a small queue of data and manipulate it.  
  42. // Start by adding a few words to it:  
  43. $myqueue =& queue_initialize();  
  44. queue_enqueue($myqueue'Opal');  
  45. queue_enqueue($myqueue'Dolphin');  
  46. queue_enqueue($myqueue'Pelican');  
  47. // The queue is: Opal Dolphin Pelican  
  48. // Check the size, it should be 3  
  49. echo '<p>Queue size is: ', queue_size($myqueue), '</p>';  
  50. // Peek at the front of the queue, it should be: Opal  
  51. echo '<p>Front of the queue is: ', queue_peek($myqueue), '</p>';  
  52. // Now rotate the queue, giving us: Dolphin Pelican Opal  
  53. queue_rotate($myqueue);  
  54. // Remove the front element, returning: Dolphin  
  55. echo '<p>Removed the element at the front of the queue: ',  
  56.     queue_dequeue($myqueue), '</p>';  
  57. // Now destroy it, we are done.  
  58. queue_destroy($myqueue);  
  59. ?>  

Tags: 任务队列