📄 msession.c
字号:
/* +----------------------------------------------------------------------+ | msession 1.0 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | 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 world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Mark Woodward <markw@mohawksoft.com> | | Portions copyright the PHP group. | +----------------------------------------------------------------------+ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#include "php_ini.h"#include "php_msession.h"#include "reqclient.h"#include "ext/standard/info.h"#include "ext/session/php_session.h"/* Macros and such */#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#ifndef SID_LEN#define SID_LEN 32#endif/* Uncomment to get debugging messages *//* #define ERR_DEBUG *//* Uncomment for conections which are persistent for a process * This will be faster but allocates a thread in the msession * daemon. * Pros: No reconnect overhead. * cons: Msession maintains a thread per connection. *//* #define PERSISTENT_CONN */#ifdef ERR_DEBUG#define ELOG( str ) php_log_err( str )#else#define ELOG( str )#endif/* Test if system is OK fror use. *//* Macros may be ugly, but I can globaly add debuging when needed. */#define IFCONNECT_BEGIN if(s_reqb && s_conn) {#define IFCONNECT_ENDVAL(V) } else { php_error(E_WARNING, s_szNoInit, get_active_function_name(TSRMLS_C)); return V; }#define IFCONNECT_END } else { php_error(E_WARNING, s_szNoInit, get_active_function_name(TSRMLS_C)); RETURN_FALSE; }#ifndef HAVE_PHP_SESSION#error HAVE_PHP_SESSION not defined#endif/* Test if session module contains custom sesson ID patch */#ifdef PHP_SESSION_API#if (PHP_SESSION_API >= 20020330)#define HAVE_PHP_SESSION_CREATESID#endif#endif /* This sets the PHP API version used in the file. *//* If this module does not compile on the version of PHP you are using, look for *//* this value in Zend/zend_modules.h, and set appropriately */#if (ZEND_MODULE_API_NO <= 20001222)#define PHP_4_0#define TSRMLS_CC#define TSRMLS_DC#define TSRMLS_FETCH()/* Comment out this line if you wish to have msession without php sessions */#define HAVE_PHP_SESSION#warning Backward compatible msession extension requires PHP sessions. If PHP compiles and links, you can ignore this warning.#elif (ZEND_MODULE_API_NO >= 20010901)#define PHP_4_1#endif/* * Please do not remove backward compatibility from this module. * this same source must also work with the 4.0.6 version of PHP. * * Module Variable naming hints: * All global scope variables begin with "g_" for global. * All static file scoped variables begin with "s_" for static. * Zero terminated strings generally start with "sz" for "string followed by zero." * integers that hold string or data lengths generally start with "cb" for "count of bytes." * Also, please to not reformat braces ;-) * -MLW */#if HAVE_MSESSION#ifdef HAVE_PHP_SESSION#ifdef HAVE_PHP_SESSION_CREATESID/* If the PHP Session module is compiled or available, include support */PS_FUNCS_SID(msession);ps_module ps_mod_msession = { PS_MOD_SID(msession)};#elsePS_FUNCS(msession);ps_module ps_mod_msession = { PS_MOD(msession)};#endif#endif/* Static strings */static char s_szNoInit[]="%s(): Msession not initialized";static char s_szErrFmt[]="%s(): %s";/* Per-process variables need by msession */static char s_szdefhost[]="localhost";static char * s_szhost=s_szdefhost;static int s_port=8086;static void * s_conn=NULL;static REQB * s_reqb=NULL;function_entry msession_functions[] = { PHP_FE(msession_connect,NULL) PHP_FE(msession_disconnect,NULL) PHP_FE(msession_lock,NULL) PHP_FE(msession_unlock,NULL) PHP_FE(msession_count,NULL) PHP_FE(msession_create,NULL) PHP_FE(msession_destroy,NULL) PHP_FE(msession_set,NULL) PHP_FE(msession_get,NULL) PHP_FE(msession_find,NULL) PHP_FE(msession_get_array,NULL) PHP_FE(msession_set_array,NULL) PHP_FE(msession_timeout,NULL) PHP_FE(msession_inc,NULL) PHP_FE(msession_set_data,NULL) PHP_FE(msession_get_data,NULL) PHP_FE(msession_listvar,NULL) PHP_FE(msession_list,NULL) PHP_FE(msession_uniq,NULL) PHP_FE(msession_randstr,NULL) PHP_FE(msession_plugin,NULL) PHP_FE(msession_call,NULL) PHP_FE(msession_ctl,NULL) {NULL, NULL, NULL}};zend_module_entry msession_module_entry = {#ifdef PHP_4_1 STANDARD_MODULE_HEADER,#endif "msession", msession_functions, PHP_MINIT(msession), PHP_MSHUTDOWN(msession), PHP_RINIT(msession), PHP_RSHUTDOWN(msession), PHP_MINFO(msession),#ifdef PHP_4_1 NO_VERSION_YET,#endif STANDARD_MODULE_PROPERTIES};#ifdef COMPILE_DL_MSESSIONZEND_GET_MODULE(msession)#endifPHP_MINIT_FUNCTION(msession){ s_conn = NULL; s_szhost = s_szdefhost; #ifdef HAVE_PHP_SESSION php_session_register_module(&ps_mod_msession);#endif return SUCCESS;}PHP_MSHUTDOWN_FUNCTION(msession){ return SUCCESS;}PHP_RINIT_FUNCTION(msession){ return SUCCESS;}PHP_RSHUTDOWN_FUNCTION(msession){#ifndef PERSISTENT_CONN if(s_conn) { CloseReqConn(s_conn); s_conn = NULL; } if(s_reqb) { FreeRequestBuffer(s_reqb); s_reqb=NULL; }#endif return SUCCESS;}PHP_MINFO_FUNCTION(msession){ php_info_print_table_start(); php_info_print_table_header(2, "msession support", "enabled"); php_info_print_table_end();}/* The PHP Version of DoRequest *//* Manages connections that have been disconnected */int PHPDoRequest(void **pconn, REQB **ppreq){ void *conn = *pconn; int stat = (*ppreq)->req.stat; int param = (*ppreq)->req.param; int result = DoRequest(conn, ppreq); /* Server closed the connection! */ if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND)) { /* In the case of a bad socket, this should be */ /* all that changs! */ (*ppreq)->req.stat = stat; (*ppreq)->req.param = param; ELOG("Connection was closed by server"); if(ReopenReqConn(conn)) result = DoRequest(*pconn, ppreq); }#ifdef ERR_DEBUG if((*ppreq)->req.stat == REQ_ERR && (result == REQE_BADCONN || result == REQE_NOSEND)) ELOG("Socket reports closed");#endif return result;}int PHPMsessionConnect(const char *szhost, int nport){ int fNewHost=FALSE; TSRMLS_FETCH(); if(!s_reqb) s_reqb = AllocateRequestBuffer(2048); if(!s_reqb) /* no buffer, it won't work! */ return 0; if(strcmp(s_szhost, szhost)) { if(s_szhost != s_szdefhost) free(s_szhost); s_szhost = strdup(szhost); fNewHost = TRUE; } if(nport && nport != s_port) { fNewHost = TRUE; s_port = nport; }#ifndef PERSISTENT_CONN ELOG("PHPMsessionConnect:old"); if(s_conn) { CloseReqConn(s_conn); php_log_err("Call to connect with non-null s_conn" TSRMLS_CC); } s_conn = OpenReqConn(s_szhost, s_port);#else ELOG("PHPMsessionConnect:new"); if(s_conn && fNewHost) { ELOG("Closing old connection, opening new"); CloseReqConn(s_conn); s_conn = NULL; } if(!s_conn) s_conn = OpenReqConn(s_szhost, s_port);#ifdef ERR_DEBUG else { ELOG("Reusing old connection"); }#endif#endif#ifdef ERR_DEBUG{ char buffer[256]; sprintf(buffer,"Connect: %s [%d] = %d (%X)\n", s_szhost, s_port, (s_conn != NULL), (unsigned)s_conn); php_log_err(buffer);}#endif return (s_conn) ? 1 : 0;}void PHPMsessionDisconnect(){#ifndef PERSISTENT_CONN if(s_conn) { CloseReqConn(s_conn); s_conn = NULL; } if(s_reqb) { FreeRequestBuffer(s_reqb); s_reqb = NULL; }#endif}char *PHPMsessionGetData(const char *session TSRMLS_DC){ char *ret = NULL; IFCONNECT_BEGIN FormatRequest(&s_reqb, REQ_DATAGET, session,"","",0); PHPDoRequest(&s_conn, &s_reqb); if(s_reqb->req.stat==REQ_OK) ret = safe_estrdup(s_reqb->req.datum); IFCONNECT_ENDVAL(0) return ret;}int PHPMsessionSetData(const char *session, const char *data TSRMLS_DC){ IFCONNECT_BEGIN int ret=0; FormatRequest(&s_reqb, REQ_DATASET, session,"",data,0); PHPDoRequest(&s_conn,&s_reqb); ret = (s_reqb->req.stat==REQ_OK); if(s_reqb->req.stat!=REQ_OK) php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); return ret; IFCONNECT_ENDVAL(0)}int PHPMsessionDestroy(const char *session TSRMLS_DC){ IFCONNECT_BEGIN int ret=0; FormatRequest(&s_reqb, REQ_DROP, session, "","",0); PHPDoRequest(&s_conn,&s_reqb); ret = (s_reqb->req.stat==REQ_OK); if(s_reqb->req.stat!=REQ_OK) php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); return ret; IFCONNECT_ENDVAL(0)}/* {{{ proto bool msession_connect(string host, string port) Connect to msession sever */PHP_FUNCTION(msession_connect){ char *szhost; int nport; zval **zhost; zval **zport; if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zhost, &zport) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(zhost); convert_to_string_ex(zport); szhost = Z_STRVAL_PP(zhost); nport = atoi(Z_STRVAL_PP(zport)); if(PHPMsessionConnect(szhost,nport)) { RETURN_TRUE; } else { php_error(E_WARNING, "%s(): MSession connect failed", get_active_function_name(TSRMLS_C)); RETURN_FALSE; }}/* }}} *//* {{{ proto void msession_disconnect(void) Disconnect from msession server */PHP_FUNCTION(msession_disconnect){ PHPMsessionDisconnect(); RETURN_NULL();}/* }}} *//* {{{ proto int msession_count(void) Get session count */PHP_FUNCTION(msession_count){ IFCONNECT_BEGIN int count; FormatRequest(&s_reqb, REQ_COUNT, "", "","",0); PHPDoRequest(&s_conn,&s_reqb); count = (s_reqb->req.stat == REQ_OK) ? s_reqb->req.param : 0; RETURN_LONG(count); IFCONNECT_END}/* }}} *//* {{{ proto bool msession_create(string session) Create a session */PHP_FUNCTION(msession_create){ IFCONNECT_BEGIN/* int stat; */ char *szsession; zval **session; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &session) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); FormatRequest(&s_reqb, REQ_CREATE, szsession, "","",0); PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { RETURN_TRUE; } else { php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); RETURN_FALSE; } IFCONNECT_END}/* }}} *//* {{{ proto bool msession_destroy(string name) Destroy a session */PHP_FUNCTION(msession_destroy){ char *szsession; zval **session; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &session) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); PHPMsessionDestroy(szsession TSRMLS_CC); RETURN_TRUE;}/* }}} *//* {{{ proto int msession_lock(string name) Lock a session */PHP_FUNCTION(msession_lock){ IFCONNECT_BEGIN char *szsession; zval **session; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &session) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); FormatRequest(&s_reqb, REQ_SLOCK, szsession, "","",0); PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { RETURN_LONG(s_reqb->req.param); } else { php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); RETURN_FALSE; } IFCONNECT_END}/* }}} *//* {{{ proto int msession_stat(string name) Lock a session */PHP_FUNCTION(msession_ctl){ static char *parray[] = { "EXIST", "TTL", "AGE", "TLA", "CTIME", "TOUCH", "NOW", NULL }; IFCONNECT_BEGIN char *szsession; zval **session; zval **which; int fn = REQ_STAT_EXIST; int n = ZEND_NUM_ARGS(); if(n != 1 && n != 2) { WRONG_PARAM_COUNT; } if(zend_get_parameters_ex(n,&session,&which) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); if(n > 1) { char *szwhich; int i; convert_to_string_ex(which); szwhich = Z_STRVAL_PP(which); for(i=0; parray[i]; i++) { if(strcasecmp(parray[i], szwhich) == 0) { fn = i; break; } } } FormatRequest(&s_reqb, REQ_CTL, szsession, "","",fn); PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) {#ifdef ERR_DEBUG char buffer[128]; sprintf(buffer, "ret:%d", s_reqb->req.param); ELOG(buffer);#endif RETURN_LONG(s_reqb->req.param); } else { ELOG("msession_ctl failed"); RETURN_FALSE; } IFCONNECT_END}/* {{{ proto int msession_unlock(string session, int key) Unlock a session */PHP_FUNCTION(msession_unlock){ IFCONNECT_BEGIN char *szsession; long lkey; zval **session; zval **key; if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &session, &key) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); szsession = Z_STRVAL_PP(session); convert_to_long_ex(key); lkey = Z_LVAL_PP(key); FormatRequest(&s_reqb, REQ_SUNLOCK, szsession, "","",lkey); PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { RETURN_LONG(s_reqb->req.param); } else { php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); RETURN_FALSE; } IFCONNECT_END}/* }}} *//* {{{ proto bool msession_set(string session, string name, string value) Set value in session */PHP_FUNCTION(msession_set){ IFCONNECT_BEGIN char *szsession; char *szname; char *szvalue; zval **session; zval **name; zval **value; if(ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3,&session,&name,&value) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); convert_to_string_ex(name); convert_to_string_ex(value); szsession = Z_STRVAL_PP(session); szname = Z_STRVAL_PP(name); szvalue = Z_STRVAL_PP(value); FormatRequest(&s_reqb, REQ_SETVAL, szsession, szname, szvalue, 0); PHPDoRequest(&s_conn,&s_reqb); if(s_reqb->req.stat==REQ_OK) { RETURN_TRUE; } else { php_error(E_WARNING, s_szErrFmt, get_active_function_name(TSRMLS_C), ReqbErr(s_reqb)); RETURN_FALSE; } IFCONNECT_END}/* }}} *//* {{{ proto string msession_get(string session, string name, string default_value) Get value from session */PHP_FUNCTION(msession_get){ IFCONNECT_BEGIN char *szsession; char *szname; char *szvalue; zval **session; zval **name; zval **value; if(ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3,&session,&name,&value) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_string_ex(session); convert_to_string_ex(name); convert_to_string_ex(value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -