Skip to content

Commit d301aa3

Browse files
author
马犇
committed
first commit
1 parent 564065e commit d301aa3

File tree

8 files changed

+530
-0
lines changed

8 files changed

+530
-0
lines changed

CREDITS

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
agj

EXPERIMENTAL

Whitespace-only changes.

cfc.c

+340
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 7 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2016 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Author: |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
/* $Id$ */
20+
21+
#ifdef HAVE_CONFIG_H
22+
#include "config.h"
23+
#endif
24+
25+
#include "php.h"
26+
#include "php_ini.h"
27+
#include "ext/standard/info.h"
28+
#include "php_cfc.h"
29+
#include "zend_smart_str.h"
30+
#include <hiredis/hiredis.h>
31+
32+
#define HASH_TABLE_NAME "cfc_hash"
33+
34+
/* If you declare any globals in php_cfc.h uncomment this:
35+
ZEND_DECLARE_MODULE_GLOBALS(cfc)
36+
*/
37+
static redisContext *g_redis = NULL;
38+
39+
static void (*old_zend_execute_ex)(zend_execute_data *execute_data);
40+
41+
/* True global resources - no need for thread safety here */
42+
static int le_cfc;
43+
44+
/* {{{ PHP_INI
45+
*/
46+
/* Remove comments and fill if you need to have entries in php.ini
47+
PHP_INI_BEGIN()
48+
STD_PHP_INI_ENTRY("cfc.enable", "1", PHP_INI_ALL, OnUpdateBool, global_value, zend_cfc_globals, cfc_globals)
49+
STD_PHP_INI_ENTRY("cfc.redis_host", "127.0.0.1", PHP_INI_ALL, OnUpdateString, redis_host, zend_cfc_globals, cfc_globals)
50+
STD_PHP_INI_ENTRY("cfc.redis_port", "6379", PHP_INI_ALL, OnUpdateLong, redis_port, zend_cfc_globals, cfc_globals)
51+
PHP_INI_END()
52+
*/
53+
PHP_INI_BEGIN()
54+
PHP_INI_ENTRY("cfc.enable", "On", PHP_INI_ALL, NULL)
55+
PHP_INI_ENTRY("cfc.redis_host", "127.0.0.1", PHP_INI_ALL, NULL)
56+
PHP_INI_ENTRY("cfc.redis_port", "6379", PHP_INI_ALL, NULL)
57+
PHP_INI_ENTRY("cfc.prefix", NULL, PHP_INI_ALL, NULL)
58+
PHP_INI_END()
59+
/* }}} */
60+
61+
/* Remove the following function when you have successfully modified config.m4
62+
so that your module can be compiled into PHP, it exists only for testing
63+
purposes. */
64+
65+
/* Every user-visible function in PHP should document itself in the source */
66+
/* {{{ proto string confirm_cfc_compiled(string arg)
67+
Return a string to confirm that the module is compiled in */
68+
69+
void redis_init()
70+
{
71+
char *host = INI_STR("cfc.redis_host");
72+
int port = INI_INT("cfc.redis_port");
73+
char *msg;
74+
75+
if (!host) {
76+
msg = "redis host have not set, using `-r' option";
77+
goto error;
78+
}
79+
80+
g_redis = redisConnect(host, port);
81+
if (g_redis == NULL || g_redis->err) {
82+
msg = "Can not connect to redis server";
83+
goto error;
84+
}
85+
return;
86+
87+
error:
88+
fprintf(stderr, "%s\n", msg);
89+
exit(1);
90+
}
91+
92+
void redis_free()
93+
{
94+
redisFree(g_redis);
95+
}
96+
97+
int redis_incr(char *func)
98+
{
99+
int r = -1;
100+
101+
redisReply *reply = NULL;
102+
smart_str command = { 0 };
103+
smart_str_appends(&command, "HINCRBY ");
104+
smart_str_appendl(&command, HASH_TABLE_NAME, strlen(HASH_TABLE_NAME));
105+
smart_str_appendl(&command, " ", strlen(" "));
106+
smart_str_appendl(&command, func, strlen(func));
107+
smart_str_appendl(&command, " 1", strlen(" 1"));
108+
smart_str_0(&command);
109+
reply = redisCommand(g_redis, command.s->val);
110+
if (g_redis->err != 0) {
111+
php_printf("redis hash set failure, error:%d, command:%s\n", g_redis->err, command.s);
112+
} else {
113+
r = (int)reply->integer;
114+
}
115+
smart_str_free(&command);
116+
freeReplyObject(reply);
117+
}
118+
119+
PHP_FUNCTION(confirm_cfc_compiled)
120+
{
121+
char *arg = NULL;
122+
size_t arg_len, len;
123+
zend_string *strg;
124+
125+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) {
126+
return;
127+
}
128+
129+
strg = strpprintf(0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "cfc", arg);
130+
131+
RETURN_STR(strg);
132+
}
133+
/* }}} */
134+
/* The previous line is meant for vim and emacs, so it can correctly fold and
135+
unfold functions in source code. See the corresponding marks just before
136+
function definition, where the functions purpose is also documented. Please
137+
follow this convention for the convenience of others editing your code.
138+
*/
139+
140+
141+
/* {{{ php_cfc_init_globals
142+
*/
143+
/* Uncomment this function if you have INI entries
144+
static void php_cfc_init_globals(zend_cfc_globals *cfc_globals)
145+
{
146+
cfc_globals->global_value = 0;
147+
cfc_globals->global_string = NULL;
148+
}
149+
*/
150+
/* }}} */
151+
152+
static char *get_function_name(zend_execute_data * execute_data)
153+
{
154+
zend_execute_data *data;
155+
char *ret = NULL;
156+
int len;
157+
const char * cls;
158+
const char * func;
159+
zend_function *curr_func;
160+
uint32_t curr_op;
161+
const zend_op *opline;
162+
163+
data = EG(current_execute_data);
164+
165+
if (data)
166+
{
167+
curr_func = data->func;
168+
/* extract function name from the meta info */
169+
if (curr_func->common.function_name)
170+
{
171+
/* previously, the order of the tests in the "if" below was
172+
* flipped, leading to incorrect function names in profiler
173+
* reports. When a method in a super-type is invoked the
174+
* profiler should qualify the function name with the super-type
175+
* class name (not the class name based on the run-time type
176+
* of the object.
177+
*/
178+
func = curr_func->common.function_name->val;
179+
len = curr_func->common.function_name->len + 1;
180+
cls = curr_func->common.scope ?
181+
curr_func->common.scope->name->val :
182+
(data->called_scope ?
183+
data->called_scope->name->val : NULL);
184+
if (cls)
185+
{
186+
len = strlen(cls) + strlen(func) + 10;
187+
ret = (char*) emalloc(len);
188+
snprintf(ret, len, "%s::%s", cls, func);
189+
}
190+
else
191+
{
192+
ret = (char*) emalloc(len);
193+
snprintf(ret, len, "%s", func);
194+
}
195+
}
196+
else
197+
{
198+
if (data->prev_execute_data)
199+
{
200+
opline = data->prev_execute_data->opline;
201+
}
202+
else
203+
{
204+
opline = data->opline;
205+
}
206+
switch (opline->extended_value)
207+
{
208+
case ZEND_EVAL:
209+
func = "eval";
210+
break;
211+
default:
212+
func = NULL;
213+
break;
214+
}
215+
216+
if (func)
217+
{
218+
ret = estrdup(func);
219+
}
220+
}
221+
}
222+
return ret;
223+
}
224+
225+
static void my_zend_execute_ex(zend_execute_data *execute_data)
226+
{
227+
228+
char *func = NULL;
229+
func = get_function_name(execute_data TSRMLS_CC);
230+
if (!func) {
231+
old_zend_execute_ex(execute_data TSRMLS_CC);
232+
return;
233+
}
234+
char *prefix = INI_STR("cfc.prefix");
235+
if (strncmp(prefix, func, strlen(prefix)) == 0) {
236+
redis_incr(func);
237+
}
238+
old_zend_execute_ex(execute_data TSRMLS_CC);
239+
efree(func);
240+
}
241+
/* {{{ PHP_MINIT_FUNCTION
242+
*/
243+
PHP_MINIT_FUNCTION(cfc)
244+
{
245+
REGISTER_INI_ENTRIES();
246+
redis_init();
247+
old_zend_execute_ex = zend_execute_ex;
248+
zend_execute_ex = my_zend_execute_ex;
249+
return SUCCESS;
250+
}
251+
/* }}} */
252+
253+
/* {{{ PHP_MSHUTDOWN_FUNCTION
254+
*/
255+
PHP_MSHUTDOWN_FUNCTION(cfc)
256+
{
257+
UNREGISTER_INI_ENTRIES();
258+
redis_free();
259+
zend_execute_ex = old_zend_execute_ex;
260+
return SUCCESS;
261+
}
262+
263+
/* }}} */
264+
265+
/* Remove if there's nothing to do at request start */
266+
/* {{{ PHP_RINIT_FUNCTION
267+
*/
268+
PHP_RINIT_FUNCTION(cfc)
269+
{
270+
#if defined(COMPILE_DL_CFC) && defined(ZTS)
271+
ZEND_TSRMLS_CACHE_UPDATE();
272+
#endif
273+
return SUCCESS;
274+
}
275+
/* }}} */
276+
277+
/* Remove if there's nothing to do at request end */
278+
/* {{{ PHP_RSHUTDOWN_FUNCTION
279+
*/
280+
PHP_RSHUTDOWN_FUNCTION(cfc)
281+
{
282+
return SUCCESS;
283+
}
284+
/* }}} */
285+
286+
/* {{{ PHP_MINFO_FUNCTION
287+
*/
288+
PHP_MINFO_FUNCTION(cfc)
289+
{
290+
php_info_print_table_start();
291+
php_info_print_table_header(2, "cfc support", "enabled");
292+
php_info_print_table_end();
293+
294+
/* Remove comments if you have entries in php.ini
295+
DISPLAY_INI_ENTRIES();
296+
*/
297+
}
298+
/* }}} */
299+
300+
/* {{{ cfc_functions[]
301+
*
302+
* Every user visible function must have an entry in cfc_functions[].
303+
*/
304+
const zend_function_entry cfc_functions[] = {
305+
PHP_FE(confirm_cfc_compiled, NULL) /* For testing, remove later. */
306+
PHP_FE_END /* Must be the last line in cfc_functions[] */
307+
};
308+
/* }}} */
309+
310+
/* {{{ cfc_module_entry
311+
*/
312+
zend_module_entry cfc_module_entry = {
313+
STANDARD_MODULE_HEADER,
314+
"cfc",
315+
cfc_functions,
316+
PHP_MINIT(cfc),
317+
PHP_MSHUTDOWN(cfc),
318+
PHP_RINIT(cfc), /* Replace with NULL if there's nothing to do at request start */
319+
PHP_RSHUTDOWN(cfc), /* Replace with NULL if there's nothing to do at request end */
320+
PHP_MINFO(cfc),
321+
PHP_CFC_VERSION,
322+
STANDARD_MODULE_PROPERTIES
323+
};
324+
/* }}} */
325+
326+
#ifdef COMPILE_DL_CFC
327+
#ifdef ZTS
328+
ZEND_TSRMLS_CACHE_DEFINE();
329+
#endif
330+
ZEND_GET_MODULE(cfc)
331+
#endif
332+
333+
/*
334+
* Local variables:
335+
* tab-width: 4
336+
* c-basic-offset: 4
337+
* End:
338+
* vim600: noet sw=4 ts=4 fdm=marker
339+
* vim<600: noet sw=4 ts=4
340+
*/

cfc.php

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
$br = (php_sapi_name() == "cli")? "":"<br>";
3+
4+
if(!extension_loaded('cfc')) {
5+
dl('cfc.' . PHP_SHLIB_SUFFIX);
6+
}
7+
$module = 'cfc';
8+
$functions = get_extension_funcs($module);
9+
echo "Functions available in the test extension:$br\n";
10+
foreach($functions as $func) {
11+
echo $func."$br\n";
12+
}
13+
echo "$br\n";
14+
$function = 'confirm_' . $module . '_compiled';
15+
if (extension_loaded($module)) {
16+
$str = $function($module);
17+
} else {
18+
$str = "Module $module is not compiled into PHP";
19+
}
20+
echo "$str\n";
21+
?>

0 commit comments

Comments
 (0)