[svn:PHP-Sandwich] rev 1077 - PHP-Sandwich/trunk
[email protected] 8 Jun 2005 14:14:04 -0000
| Newsgroups | perl.php.sandwich.dev |
|---|---|
| Message-ID | <[email protected]> |
Author: gschlossnagle
Date: Wed Jun 8 07:14:03 2005
New Revision: 1077
Modified:
PHP-Sandwich/trunk/PHP.xs
Log:
add ability to pass optional autoglobals data as a hashref to PHP::Interpreter
constructor.
Modified: PHP-Sandwich/trunk/PHP.xs
==============================================================================
--- PHP-Sandwich/trunk/PHP.xs (original)
+++ PHP-Sandwich/trunk/PHP.xs Wed Jun 8 07:14:03 2005
@@ -328,12 +328,91 @@ static int get_class_name(zval *z, char
return 0;
}
+static void my_autoglobal_merge(HashTable *dest, HashTable *src TSRMLS_DC)
+{
+ zval **src_entry, **dest_entry;
+ char *string_key;
+ uint string_key_len;
+ ulong num_key;
+ HashPosition pos;
+ int key_type;
+ int globals_check = (PG(register_globals) && (dest == (&EG(symbol_table))));
+
+ zend_hash_internal_pointer_reset_ex(src, &pos);
+ while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) {
+ key_type = zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key,
+ 0, &pos);
+ if (Z_TYPE_PP(src_entry) != IS_ARRAY
+ || (key_type == HASH_KEY_IS_STRING && zend_hash_find(dest, string_key, string_key_len, (void **) &dest_entry) != SUCCESS)
+ || (key_type == HASH_KEY_IS_LONG && zend_hash_index_find(dest, num_key, (void **)&dest_entry) != SUCCESS)
+ || Z_TYPE_PP(dest_entry) != IS_ARRAY
+ ) {
+ (*src_entry)->refcount++;
+ if (key_type == HASH_KEY_IS_STRING) {
+ /* if register_globals is on and working with main symbol table, prevent overwriting of GLOBALS */
+ if (!globals_check || string_key_len != sizeof("GLOBALS") || memcmp(string_key, "GLOBALS", sizeof("GLOBALS") - 1)) {
+ zend_hash_update(dest, string_key, string_key_len, src_entry, sizeof(zval *), NULL);
+ } else {
+ (*src_entry)->refcount--;
+ }
+ } else {
+ zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL);
+ }
+ } else {
+ SEPARATE_ZVAL(dest_entry);
+ my_autoglobal_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry) TSRMLS_CC);
+ }
+ zend_hash_move_forward_ex(src, &pos);
+ }
+}
+
+static my_auto_globals_create_request(void *dummy TSRMLS_DC)
+{
+ zval *form_variables;
+ unsigned char _gpc_flags[3] = {0, 0, 0};
+ char *p;
+
+ ALLOC_ZVAL(form_variables);
+ array_init(form_variables);
+ INIT_PZVAL(form_variables);
+
+ for (p = PG(variables_order); p && *p; p++) {
+ switch (*p) {
+ case 'g':
+ case 'G':
+ if (!_gpc_flags[0]) {
+ my_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC);
+ _gpc_flags[0] = 1;
+ }
+ break;
+ case 'p':
+ case 'P':
+ if (!_gpc_flags[1]) {
+ my_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC);
+ _gpc_flags[1] = 1;
+ }
+ break;
+ case 'c':
+ case 'C':
+ if (!_gpc_flags[2]) {
+ my_autoglobal_merge(Z_ARRVAL_P(form_variables), Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC);
+ _gpc_flags[2] = 1;
+ }
+ break;
+ }
+ }
+
+ zend_hash_update(&EG(symbol_table), "_REQUEST", sizeof("_REQUEST"), &form_variables, sizeof(zval *), NULL);
+ return 0;
+}
+
+
MODULE = PHP PACKAGE = PHP::Interpreter PREFIX=SAND_
REQUIRE: 1.9505
PROTOTYPES: DISABLE
-SV* SAND_new(classname)
+SV* SAND_new(classname, ...)
char *classname;
CODE:
{
@@ -343,7 +422,59 @@ SV* SAND_new(classname)
RETVAL = &PL_sv_undef;
return;
}
+ fprintf(stderr, "items: %d\n", items);
interp = sandwich_per_interp_setup();
+ if(items > 1 && SvROK(ST(1)) && (SvTYPE(SvRV(ST(1))) == SVt_PVHV)) {
+ HV *args = (HV *) SvRV(ST(1));
+ SV *trackvars;
+ char *trackvars_key;
+ I32 trackvars_keylen;
+ void *old_ctx = tsrm_set_interpreter_context(interp->ctx);
+ TSRMLS_FETCH();
+ hv_iterinit(args);
+ while((trackvars = hv_iternextsv(args, &trackvars_key, &trackvars_keylen)) != NULL) {
+ HV *hv;
+ SV *autoglobal;
+ char *key;
+ I32 keylen;
+ zval *track_vars_array = NULL;
+
+ if(!strcmp(trackvars_key, "GET")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_GET];
+ }
+ else if(!strcmp(trackvars_key, "POST")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_POST];
+ }
+ else if(!strcmp(trackvars_key, "COOKIE")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_COOKIE];
+ }
+ else if(!strcmp(trackvars_key, "SERVER")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_SERVER];
+ }
+ else if(!strcmp(trackvars_key, "ENV")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_ENV];
+ }
+ else if(!strcmp(trackvars_key, "FILES")) {
+ track_vars_array = PG(http_globals)[TRACK_VARS_FILES];
+ } else {
+ /* special case - this isn't an autoglobal - register it and continue */
+ int old_register_globals = PG(register_globals);
+ PG(register_globals) = 1;
+ php_register_variable_ex(trackvars_key, SvZval(trackvars TSRMLS_CC), NULL TSRMLS_CC);
+ PG(register_globals) = old_register_globals;
+ continue;
+ }
+ if(!SvROK(trackvars) || !(SvTYPE(SvRV(trackvars)) == SVt_PVHV)) continue;
+ hv = (HV *) SvRV(trackvars);
+ hv_iterinit(hv);
+ while((autoglobal = hv_iternextsv(hv, &key, &keylen)) != NULL) {
+ zval *zag = SvZval(autoglobal TSRMLS_CC);
+ php_register_variable_ex(key, zag, track_vars_array TSRMLS_CC);
+ }
+ }
+ my_auto_globals_create_request(NULL TSRMLS_CC);
+ tsrm_set_interpreter_context(old_ctx);
+ }
RETVAL = newSV(0);
sv_setref_pv(RETVAL, classname, (void *)interp);
}