📄 var.c
字号:
if (return_output) { php_ob_get_buffer (return_value TSRMLS_CC); php_end_ob_buffer (0, 0 TSRMLS_CC); }}/* }}} *//* {{{ php_var_serialize */static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC);static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old){ ulong var_no; char id[32], *p; register int len; /* relies on "(long)" being a perfect hash function for data pointers */ p = smart_str_print_long(id + sizeof(id) - 1, (long) var); len = id + sizeof(id) - 1 - p; if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) { if (!var->is_ref) { /* we still need to bump up the counter, since non-refs will be counted separately by unserializer */ var_no = -1; zend_hash_next_index_insert(var_hash, &var_no, sizeof(var_no), NULL); } return FAILURE; } /* +1 because otherwise hash will think we are trying to store NULL pointer */ var_no = zend_hash_num_elements(var_hash) + 1; zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL); return SUCCESS;}static inline void php_var_serialize_long(smart_str *buf, long val){ smart_str_appendl(buf, "i:", 2); smart_str_append_long(buf, val); smart_str_appendc(buf, ';');}static inline void php_var_serialize_string(smart_str *buf, char *str, int len){ smart_str_appendl(buf, "s:", 2); smart_str_append_long(buf, len); smart_str_appendl(buf, ":\"", 2); smart_str_appendl(buf, str, len); smart_str_appendl(buf, "\";", 2);}static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval **struc TSRMLS_DC){ PHP_CLASS_ATTRIBUTES; PHP_SET_CLASS_ATTRIBUTES(*struc); smart_str_appendl(buf, "O:", 2); smart_str_append_long(buf, name_len); smart_str_appendl(buf, ":\"", 2); smart_str_appendl(buf, class_name, name_len); smart_str_appendl(buf, "\":", 2); PHP_CLEANUP_CLASS_ATTRIBUTES(); return incomplete_class;}static void php_var_serialize_class(smart_str *buf, zval **struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC){ int count; zend_bool incomplete_class; incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC); /* count after serializing name, since php_var_serialize_class_name changes the count if the variable is incomplete class */ count = zend_hash_num_elements(HASH_OF(retval_ptr)); if (incomplete_class) { --count; } smart_str_append_long(buf, count); smart_str_appendl(buf, ":{", 2); if (count > 0) { char *key; zval **d, **name; ulong index; HashPosition pos; int i; zval nval, *nvalp; ZVAL_NULL(&nval); nvalp = &nval; zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos); for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) { i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL, &index, 0, &pos); if (i == HASH_KEY_NON_EXISTANT) break; if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) { continue; } zend_hash_get_current_data_ex(HASH_OF(retval_ptr), (void **) &name, &pos); if (Z_TYPE_PP(name) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only " "containing the names of instance-variables to " "serialize."); /* we should still add element even if it's not OK, since we already wrote the length of the array before */ smart_str_appendl(buf,"N;", 2); continue; } if (zend_hash_find(Z_OBJPROP_PP(struc), Z_STRVAL_PP(name), Z_STRLEN_PP(name) + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); php_var_serialize_intern(buf, d, var_hash TSRMLS_CC); } else { php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); php_var_serialize_intern(buf, &nvalp, var_hash TSRMLS_CC); } } } smart_str_appendc(buf, '}');}static void php_var_serialize_intern(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC){ int i; ulong *var_already; HashTable *myht; if (var_hash && php_add_var_hash(var_hash, *struc, (void *) &var_already) == FAILURE) { if((*struc)->is_ref) { smart_str_appendl(buf, "R:", 2); smart_str_append_long(buf, *var_already); smart_str_appendc(buf, ';'); return; } else if(Z_TYPE_PP(struc) == IS_OBJECT) { smart_str_appendl(buf, "r:", 2); smart_str_append_long(buf, *var_already); smart_str_appendc(buf, ';'); return; } } switch (Z_TYPE_PP(struc)) { case IS_BOOL: smart_str_appendl(buf, "b:", 2); smart_str_append_long(buf, Z_LVAL_PP(struc)); smart_str_appendc(buf, ';'); return; case IS_NULL: smart_str_appendl(buf, "N;", 2); return; case IS_LONG: php_var_serialize_long(buf, Z_LVAL_PP(struc)); return; case IS_DOUBLE: { char *s; ulong slen; slen = spprintf(&s, 0, "d:%.*G;", (int) PG(serialize_precision), Z_DVAL_PP(struc)); smart_str_appendl(buf, s, slen); efree(s); return; } case IS_STRING: php_var_serialize_string(buf, Z_STRVAL_PP(struc), Z_STRLEN_PP(struc)); return; case IS_OBJECT: { zval *retval_ptr = NULL; zval fname; int res; if(Z_OBJCE_PP(struc) != PHP_IC_ENTRY) { INIT_PZVAL(&fname); ZVAL_STRINGL(&fname, "__sleep", sizeof("__sleep") - 1, 0); res = call_user_function_ex(CG(function_table), struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC); if (res == SUCCESS) { if (retval_ptr) { if (HASH_OF(retval_ptr)) { php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC); } else { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only " "containing the names of instance-variables to " "serialize."); /* we should still add element even if it's not OK, since we already wrote the length of the array before */ smart_str_appendl(buf,"N;", 2); } zval_ptr_dtor(&retval_ptr); } return; } } if (retval_ptr) zval_ptr_dtor(&retval_ptr); /* fall-through */ } case IS_ARRAY: { zend_bool incomplete_class = 0; if (Z_TYPE_PP(struc) == IS_ARRAY) { smart_str_appendl(buf, "a:", 2); myht = HASH_OF(*struc); } else { incomplete_class = php_var_serialize_class_name(buf, struc TSRMLS_CC); myht = Z_OBJPROP_PP(struc); } /* count after serializing name, since php_var_serialize_class_name changes the count if the variable is incomplete class */ i = myht ? zend_hash_num_elements(myht) : 0; if (i > 0 && incomplete_class) { --i; } smart_str_append_long(buf, i); smart_str_appendl(buf, ":{", 2); if (i > 0) { char *key; zval **data; ulong index; uint key_len; HashPosition pos; zend_hash_internal_pointer_reset_ex(myht, &pos); for (;; zend_hash_move_forward_ex(myht, &pos)) { i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos); if (i == HASH_KEY_NON_EXISTANT) break; if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) { continue; } switch (i) { case HASH_KEY_IS_LONG: php_var_serialize_long(buf, index); break; case HASH_KEY_IS_STRING: php_var_serialize_string(buf, key, key_len - 1); break; } /* we should still add element even if it's not OK, since we already wrote the length of the array before */ if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) != SUCCESS || !data || data == struc) { smart_str_appendl(buf, "N;", 2); } else { php_var_serialize_intern(buf, data, var_hash TSRMLS_CC); } } } smart_str_appendc(buf, '}'); return; } default: smart_str_appendl(buf, "i:0;", 4); return; } }PHPAPI void php_var_serialize(smart_str *buf, zval **struc, HashTable *var_hash TSRMLS_DC){ php_var_serialize_intern(buf, struc, var_hash TSRMLS_CC); smart_str_0(buf);} /* }}} *//* {{{ proto string serialize(mixed variable) Returns a string representation of variable (which can later be unserialized) */PHP_FUNCTION(serialize){ zval **struc; php_serialize_data_t var_hash; smart_str buf = {0}; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &struc) == FAILURE) { WRONG_PARAM_COUNT; } Z_TYPE_P(return_value) = IS_STRING; Z_STRVAL_P(return_value) = NULL; Z_STRLEN_P(return_value) = 0; PHP_VAR_SERIALIZE_INIT(var_hash); php_var_serialize(&buf, struc, &var_hash TSRMLS_CC); PHP_VAR_SERIALIZE_DESTROY(var_hash); if (buf.c) { RETURN_STRINGL(buf.c, buf.len, 0); } else { RETURN_NULL(); }}/* }}} *//* {{{ proto mixed unserialize(string variable_representation) Takes a string representation of variable and recreates it */PHP_FUNCTION(unserialize){ zval **buf; php_unserialize_data_t var_hash; if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &buf) == FAILURE) { WRONG_PARAM_COUNT; } if (Z_TYPE_PP(buf) == IS_STRING) { const unsigned char *p = (unsigned char*)Z_STRVAL_PP(buf); if (Z_STRLEN_PP(buf) == 0) { RETURN_FALSE; } PHP_VAR_UNSERIALIZE_INIT(var_hash); if (!php_var_unserialize(&return_value, &p, p + Z_STRLEN_PP(buf), &var_hash TSRMLS_CC)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zval_dtor(return_value); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - Z_STRVAL_PP(buf)), Z_STRLEN_PP(buf)); RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } else { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Argument is not a string"); RETURN_FALSE; }}/* }}} */#if MEMORY_LIMIT/* {{{ proto int memory_get_usage() Returns the allocated by PHP memory */PHP_FUNCTION(memory_get_usage) { RETURN_LONG(AG(allocated_memory));}/* }}} */#endif/* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -