终于从google来了一个访客。。。纪念下。。。

开博客到现在,终于从se来了一个访客。。。鼓掌。。。。

一个关于多语言都解决方法

http://www.oschina.net/code/snippet_266272_10204

大多数通用的方案是使用模板+语言标签+[中文、英文、etc]语言包实现

导致在进行开发的过程中需要同时维护模板中的标签和至少一套语言包

本组件减少了维护开发工程中这一套语言包的工作,直接使用中文作为源标签,生成不同locale的语言缓存模板供调用。

ps:实验用途,不建议用于实际生产

文件以及文件夹:



核心文件:

 

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?php
/*
	+----------------------------------------------------------------+	
	|Hellovigoss Language v1.0                                       |
	+----------------------------------------------------------------+
	|Hvgs_Lang 一个方便使用的多语言模板组件For Chinese phper         |
	+----------------------------------------------------------------+
	|Copyright(c) hellovigoss<hellovigoss@gmail.com>                 |
	+----------------------------------------------------------------+
	|在php多语言项目中需要做很多翻译工作                             |
	|一般的locale组件使用中间标示变量+模板实现多语言                 |
	|本组件旨在简单的解决多语言方案,开发过程只需整理一套中文语言模板|
	|后期独立整理各个版本的语言词组即可                              |
	|不需要整理中间变量,详见README                                  |
	+----------------------------------------------------------------+
	|Aurthor: hellovigoss <hellovigoss@gmail.com>                    |
	|blog: http://www.php-ex.com                                     |
	+----------------------------------------------------------------+
*/
class Hvgs_Lang{
	private $_source = 'zh-cn';
	private $_to = 'en';
	private $_cache_life = 3600;
	private $_cache_path = './cache/';
	private $_local_path = './locale/';
	private $_template_path = './template/';
 
	public function setTargetLocale($to){
		$this->_to = $to;
	}
	public function translate($template){
		if($this->_source == $this->_to){
			return $this->_template_path . $template;
		}
		if($cache_file = $this->expired($template)){
			if(!file_exists($this->_local_path . $this->_to)){
				die('locale file : ' . $this->_local_path . $this->_to . ' not exist!');
			}
			$_source_array = file_get_contents($this->_local_path . $this->_source);
			$_source_array = explode("\n", $_source_array);
			$_to_array = file_get_contents($this->_local_path . $this->_to);
			$_to_array = explode("\n", $_to_array);
			foreach($_source_array as $key => $value){
				if(empty($value)){
					continue;
				}
				$temp_array[$value] = $_to_array[$key]; 
			}
			$sort = create_function('$a,$b', 'return(strLen($a) < strLen($b));');
			uksort($temp_array, $sort);
 
			$content = file_get_contents($this->_template_path . $template);
			foreach($temp_array as $key => $value){
				$content = str_ireplace($key, $value, $content);
			}
			$cache_file = $this->writeCache($template, $content);
		}
		return $cache_file;
	}
 
	private function expired($template){
		$cache_file_name = $this->_cache_path . $this->_to . '-' . $template;
		if(!file_exists($cache_file_name) || (time() - filemtime($cache_file_name)) > $this->_cache_life){
			return true;
		}
		else{
			return $cache_file_name;
		}
	}
 
	private function writeCache($template, $content){
		$cache_file_name = $this->_cache_path . $this->_to . '-' . $template;
		file_put_contents($cache_file_name, $content);
		return $cache_file_name;
	}
}

装修对话

与大姐(^轻轻^)的聊天记录 – Q+ Web

聊天对象:大姐(^轻轻^) 保存时间:2012-04-24 11:40:30
hellovigoss2012-04-24 09:20:40
大姐
【提示:此用户正在使用Q+ Web:http://web2.qq.com/
hellovigoss2012-04-24 09:20:42
阔在?~
hellovigoss2012-04-24 09:20:47
我的报价预算出来了
hellovigoss2012-04-24 09:20:50
你帮我瞅瞅
大姐2012-04-24 09:21:20
现在的行情我不知道了也
大姐2012-04-24 09:21:28
发给我看看
hellovigoss2012-04-24 09:21:31
他带了一份材料表
hellovigoss2012-04-24 09:21:37
你看看用料如何
hellovigoss2012-04-24 09:21:44
兔宝宝的板子啊什么的- -#
hellovigoss2012-04-24 09:21:53
我webqq发到你邮箱里面啊
大[......]

走过撸过-_# ENTER

关于“轮子”–php框架感想

做php开发,可能大家都会有一个想法,写一套自己的框架,framework- -#

恩。毕竟各个阶段都有各个阶段的目标。但是 – -#,就php来说。现在框架多的数不胜数。。良莠不齐。。

在我看来,系统就好比是一辆汽车,框架就是让这辆车上路的轮子,至于需要这么多轮子么。

目前接触了一套框架,大致看了一些内部实现代码。设计思想确实不敢苟同,且先举出两个例子吧:

1,大家都知道oop的基本思想是封装、继承、多态。

在我所接触的这个fw(framework)中,大量使用了global全局变量,将所有配置也就是config独立于框架之外的global变量$_config_存在,然后在框架中使用一个通用函数对本global变量进行操作,包括存取。这个其实就是破坏了框架的数据封装。且不较劲争辩global是否应该用于fw。

我先提出一个较优的解决方案(大部分主流框架的实现方式):使用config类独立加载对应配置文件、提供对外public借口访问/修改config配置项。

乍一看,一样的阿。那么为什么说这个更为优化?举个例子你在一个函数体内global了这[......]

走过撸过-_# ENTER

trello.com,项目管理协同合作的另一种选择

觉得项目管理cs软件过于庞大,
可能你可以试试这个。
trello.com
基于card的项目管理软件,支持gmail账户登录
挺好

php的array_rand函数

array_rand函数,功能是从参数数组中取出一个或者多个随机单元
有人发现了这个函数有个问题就是出来得结果前面得索引必然小于后面得索引

 

1
2
3
4
5
6
7
8
9
10
11
12
<?php 
for($i = 0; ; $i ++) {   
srand((float) microtime() * 10000000);   
$input = array("Neo", "Morpheus", "Trinity", "Cypher", "Tank");   
$rand_keys = array_rand($input, 2);   
if ((int)$rand_keys[0] --> (int)$rand_keys[1])
  {
    echo "1%" . ($i + 1) . "";
    break;
  }
}
?>

对应的实现代码如下:

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
PHP_FUNCTION(array_rand)
{
        zval *input;
        long randval, num_req = 1;
        int num_avail, key_type;
        char *string_key;
        uint string_key_len;
        ulong num_key;
        HashPosition pos;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &amp;input, &amp;num_req) == FAILURE) {
                return;
        }
 
        num_avail = zend_hash_num_elements(Z_ARRVAL_P(input));//获取数组元素个数
 
        if (ZEND_NUM_ARGS() &gt; 1) {//如果参数个数大于1
                if (num_req &lt;= 0 || num_req &gt; num_avail) {//获取数组key小于0或者越界
                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Second argument has to be between 1 and the number of elements in the array");
                        return;
                }
        }
 
        /* Make the return value an array only if we need to pass back more than one result. */
        if (num_req &gt; 1) {//如果参数个数大于1,以参数个数大小得数组返回
                array_init_size(return_value, num_req);
        }
 
        /* We can't use zend_hash_index_find() because the array may have string keys or gaps. */
        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &amp;pos);//重置hash表指针
        while (num_req &amp;&amp; (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &amp;string_key, &amp;string_key_len, &amp;num_key, 0, &amp;pos)) != HASH_KEY_NON_EXISTANT) {//判断条件,少于需求得个数且hash没遍历完成
 
                randval = php_rand(TSRMLS_C);
 
                if ((double) (randval / (PHP_RAND_MAX + 1.0)) &lt; (double) num_req / (double) num_avail) {
                        /* If we are returning a single result, just do it. */
                        if (Z_TYPE_P(return_value) != IS_ARRAY) {//仅仅返回一个结果
                                if (key_type == HASH_KEY_IS_STRING) {
                                        RETURN_STRINGL(string_key, string_key_len - 1, 1);
                                } else {
                                        RETURN_LONG(num_key);
                                }
                        } else {
                                /* Append the result to the return value. */
                                if (key_type == HASH_KEY_IS_STRING) {//返回多个结果
                                        add_next_index_stringl(return_value, string_key, string_key_len - 1, 1);//将key加入返回数组
                                } else {
                                        add_next_index_long(return_value, num_key);//增加索引进入数组
                                }
                        }
                        num_req--;//还需要得key个数-1
                }
                num_avail--;//数组标志个数-1
                zend_hash_move_forward_ex(Z_ARRVAL_P(input), &amp;pos);//后移指针
        }
}

其中涉及到随机数处理的代码我已经加上了注释,
很显然可以看出,只有一个数组遍历循环。从头到尾得while,那么前面key的索引比后面一个key得索引小那就是必然的了。
而随机关键点在于其中得那个if语句和num_req 、 num_avail这俩变量,if如下
if ((double) (randval / (PHP_RAND_MAX + 1.0)) < (double) num_req / (double) num_avail)
其中 (randval / (PHP_RAND_MAX + 1.0)) 肯定是比1小得,
而num_avail是一个初始值为数组count,每层while循环都会减小1得变量,而num_req则是用户输入[......]

走过撸过-_# ENTER

GDB使用

Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C++ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是 gdb 所提供的一些功能:
它使你能监视你程序中变量的值.
它使你能设置断点以使程序在指定的代码行上停止执行.
它使你能一行行的执行你的代码.

在命令行上键入 gdb 并按回车键就可以运行 gdb 了, 如果一切正常的话, gdb 将被启动并且你将在屏幕上看到类似的内容:
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type “show copying” to see the conditions.
There is absolutely no warranty for GDB; type “show warranty” for details.
GDB 4.14 (i486-slakware-linux), Copyright 1995[......]

走过撸过-_# ENTER

发出一个php源码加密扩展

specail thanks to MoXie <system128@gmail.com>

对php源码进行加密保护

稍后放出源码

源码地址:http://code.google.com/p/guard-php/

加密前源代码:

index.php

include.php

加密过程:

加密后文件:

index.php

include.php

运行:

写一个php的c扩展 part1写扩展。。(4)

接前面的http://www.php-ex.com/?p=139

之前说明了如何接受从php script层传过来的参数,处理完成了之后。现在需要将它返回给php脚本

如何返回值

 

这里有简单的返回宏供大家调用

  • RETURN_NULL();     无参数,返回null
  • RETURN_BOOL(b);    参数若为0则返回false,否则返回true
  • RETURN_TRUE();    相当于RETURN_BOOL(1);
  • RETURN_FALSE();    相当于RETURN_BOOL(0);
  • RETURN_LONG(l);    返回整形数据
  • RETURN_DOUBLE(d);    返回浮点型数据

前面这些返回宏都是比较简单的,没有或者只有一个参数,接下来返回字符串稍微复杂一点

  • RETURN_STRING(str, dup)    返回一个字符串,第一个参数是字符串的指针,第二个参数是一个标识,是否在返回之前复制一份(1),还是直接返回(0)
  • RETURN_STRINGL(str, le[......]

走过撸过-_# ENTER

HashTable API

一、创建HashTable

1
2
3
4
5
6
7
8
9
int zend_hash_init(
	HashTable *ht,//指向一个HashTable
	uint nSize,//nSize是指这个HashTable可以拥有的元素的最大数量。在我们添加新的元素时,这个值会根据情况决定是否自动增长,这个值永远都是2的次方,如果你给它的值不是一个2的次方
			//的形式,那它将自动调整成大于它的最小的2的次方值。它的计算方法就像这样:nSize = pow(2, ceil(log(nSize, 2)))。(HashTable能够包含任意数量的元素,这个值只是为了提前申请好内存,提高性
			//能,省的不停的进行rehash操作)
	hash_func_t pHashFunction,//pHashFunction是早期的参数,为向前兼容所以没有去掉。直接赋值NULL即可。
	dtor_func_t pDestructor,//一个回调函数,当我们删除或者修改HashTable中其中一个元素时候便会调用,它的函数原型必须是这样的:void method_name(void *pElement),一般使用宏ZVAL_PTR_DTOR即可。
	zend_bool persistent//值为0或1,如果是1那么这个HashTable将永远存在于内存中,而不会在RSHUTDOWN阶段自动被注销掉。此时第一个参数ht所指向的地址必须是通过pemalloc()函数申请的。
);

注:
#define ZVAL_PTR_DTOR (void (*)(void *)) zval_ptr_dtor_wrapper
删除元素,回调析构该元素。
二、添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int zend_hash_add(
	HashTable *ht,		//待操作的ht
	char *arKey,			//索引,如"my_key"
	uint nKeyLen,		//字符串索引的长度,如6
	void **pData,		//要插入的数据,注意它是void **类型的。
	uint nDataSize,		//例如,存放zval类型变量,那么nDataSize=sizeof(zval*)
	void *pDest			//如果操作成功,则pDest=*pData;
);
 
int zend_hash_next_index_insert(
	HashTable *ht,	//待操作的ht
	void *pData,	//要插入的数据
	uint nDataSize,
	void **pDest
);

三、更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int zend_hash_update(
	HashTable *ht,
	char *arKey,	//索引字符串
	uint nKeyLen,	//索引字符串长度
	void *pData,
	uint nDataSize,
	void **pDest
);
 
int zend_hash_index_update(
	HashTable *ht,
	ulong h,
	void *pData,
	uint nDataSize,
	void **pDest
);

四、查找

1
2
3
4
5
6
7
8
9
10
11
12
int zend_hash_find(
	HashTable *ht,
	char *arKey, 	//索引字符串
	uint nKeyLength,	//索引字符串长度
	void **pData	//找到元素,则将元素指向pData
);
 
int zend_hash_index_find(
	HashTable *ht,
	ulong h, 		//数字索引
	void **pData	//找到元素,则将元素指向pData
);

五、检测

1
2
3
4
5
6
7
8
9
10
int zend_hash_exists(
	HashTable *ht, 
	char *arKey, 
	uint nKeyLen
);
 
int zend_hash_index_exists(
	HashTable *ht, 
	ulong h
);

这两个函数返回SUCCESS或者FAILURE,分别代表着是否存在

六、加速
ulong zend_get_hash_value(char *arKey, uint nKeyLen);//返回索引的hash值
通过使用zend_get_hash_value函数得到索引hash值,之后对hashTable进行添加、修改等操作使用quick系列函数可以避免重[......]

走过撸过-_# ENTER