Code For Colorful Life
SSO 实现方案探讨
本博文主要针对多个相互信任的网站实现单点login后其它站点也login,单点logout后其它站点也logout的解决方案。
本方案学习自:Simple Single Sign-On for PHP (Ajax compatible),但实现方式与之有些不同:
- Broker可以存储用户信息,这样,当用户在登陆Broker之后所进行的操作都不需要请求SSO以检查用户是否退出了;
- 当用户从某个Broker退出时,该Broker先自己执行用户退出工作,之后发送退出请求到SSO,SSO通知其它已经登陆了的Broker执行退出工作。
Read more...
urlencode和rawurlencode区别
urlencode()
:用于编码URL中的参数部分。
rawurlencode()
:用于编码URL路径部分。
Read more...
PHP foreach 是如何遍历数组的?
参考资料:How foreach actually works和PHP的哈希表实现
Array类型的实现
在PHP的zvalue_value结构体中,我们知道array类型是通过HashTable实现的,结构如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct _hashtable {
uint nTableSize; // hash Bucket的大小,最小为8,以2x增长。
uint nTableMask; // nTableSize-1 , 索引取值的优化
uint nNumOfElements; // hash Bucket中当前存在的元素个数,count()函数会直接返回此值
ulong nNextFreeElement; // 下一个数字索引的位置
Bucket *pInternalPointer; // 当前遍历的指针(foreach比for快的原因之一)
Bucket *pListHead; // 存储数组头元素指针
Bucket *pListTail; // 存储数组尾元素指针
Bucket **arBuckets; // 存储hash数组
dtor_func_t pDestructor; // 在删除元素时执行的回调函数,用于资源的释放
zend_bool persistent; //指出了Bucket内存分配的方式。如果persisient为TRUE,则使用操作系统本身的内存分配函数为Bucket分配内存,否则使用PHP的内存分配函数。
unsigned char nApplyCount; // 标记当前hash Bucket被递归访问的次数(防止多次递归)
zend_bool bApplyProtection;// 标记当前hash桶允许不允许多次访问,不允许时,最多只能递归3次
#if ZEND_DEBUG
int inconsistent;
#endif
} HashTable;
Bucket *pInternalPointer;
就是foreach
用于遍历Bucket
的指针,数组的每一个元素都存储在Bucket
,它比for
快,因为for
需要对key
进行哈希后,才能找到相应节点。
Read more...
PHP变量引用计数,写时复制总结
在PHP的变量存储结构ZVAL中,有两个成员:refcount__gc
和is_ref_gc
用于实现引用计数和写时复制,这样既能节省内存,又能减少计算量。
当执行如下代码时:
1
2
3
4
5
<?php
$a = "this is";
$b = "variable";
$c = 42;
?>
三个变量各自拥有一个ZVAL,如下图所示:
Read more...
GRASP (object-oriented design)
翻译自维基百科GRASP (object-oriented design)
General Responsibility Assignment Software Patterns(通用职责分配软件模式),简写为GRASP,由面向对象设计中对类和对象的职责分配原则组成。
GRASP使用的模式和原则有:控制器、创建者、间接性、信息专家、高内聚、低耦合、多态、防止变异和纯虚构。所有这些模式都回答了一些软件设计问题,并且这些问题几乎在每一个软件开发项目中都会遇到。这些技术还没有被用来发明新的工作方式,而是为了改善文档和规范旧的开发方式,是在面向对象设计中不断尝试和测试的编程原则。
Larman说:“软件开发中最关键的设计工具是一个在设计原则上受过良好教育的头脑,而不是UML或者其它技术。”因此,GRASP是一个真正的思维工具,一个学习援助,在面向对象软件的设计中有所帮助。
Read more...
Pear编码标准 10、13
翻译自Coding Standards的10、13小节
文件头注释
在PEAR库的所有源代码文件都要包含一个“页面级”的注释在文件开头和每一个类的都要有“类级别”的注释。下面有一个例子:
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
/**
* 关于本文件短的描述
*
* 详细的描述(如果需要的话……)
*
* PHP version 5版本
*
* 许可声明
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version SVN: $Id$
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since File available since Release 1.2.0
* @deprecated File deprecated in Release 2.0.0
*/
/*
* 将includes,constant defines和$_GLOBAL设置写在这里。
* 确保他们有合适的文档注释,以免phpDocumentor将它们当作“页面级”注释处理。
*/
/**
* 关于类的简短描述
*
* 详细的描述(如果需要的话……)
*
* @category CategoryName
* @package PackageName
* @author Original Author <author@example.com>
* @author Another Author <another@example.com>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version Release: @package_version@
* @link http://pear.php.net/package/PackageName
* @see NetOther, Net_Sample::Net_Sample()
* @since Class available since Release 1.2.0
* @deprecated Class deprecated in Release 2.0.0
*/
class Foo_Bar
{
}
?>
Read more...
Pear编码标准 1-9
翻译自Coding Standards的1-9小节
缩进和行的长度
使用4个空格的缩进,且不含制表符。这有助于避免差别、补丁、SVN历史和注释带来的问题。为了增强代码的可读性,特别推荐每一行大约占75-85个字符长。 Paul M. Jones有关于这个限制的一些想法。
Read more...