📄 mysqlnd_ps_codec.c
字号:
}#endif}/* }}} *//* {{{ ps_fetch_string */staticvoid ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ /* For now just copy, before we make it possible to write \0 to the row buffer */ unsigned long length= php_mysqlnd_net_field_length(row);#if PHP_MAJOR_VERSION < 6 ZVAL_STRINGL(zv, (char *)*row, length, 1); #else if (field->charsetnr == MYSQLND_BINARY_CHARSET_NR) { ZVAL_STRINGL(zv, (char *)*row, length, 1); } else { ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE); }#endif (*row) += length;}/* }}} *//* {{{ ps_fetch_bit */staticvoid ps_fetch_bit(zval *zv, const MYSQLND_FIELD * const field, uint pack_len, zend_uchar **row, zend_bool as_unicode TSRMLS_DC){ unsigned long length= php_mysqlnd_net_field_length(row); /* Handle BIT here */ ZVAL_STRINGL(zv, (char *)*row, length, 1); (*row) += length;}/* }}} *//* {{{ _mysqlnd_init_ps_subsystem */void _mysqlnd_init_ps_subsystem(){ memset(mysqlnd_ps_fetch_functions, 0, sizeof(mysqlnd_ps_fetch_functions)); mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].func = ps_fetch_null; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].pack_len = 0; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].php_type = IS_NULL; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NULL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].func = ps_fetch_int8; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].pack_len = 1; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].func = ps_fetch_int16; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].pack_len = 2; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SHORT].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].func = ps_fetch_int16; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].pack_len = 2; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_YEAR].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].func = ps_fetch_int32; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].pack_len = 4; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_INT24].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].func = ps_fetch_int32; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].pack_len = 4; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].func = ps_fetch_int64; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].pack_len= 8; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].php_type = IS_LONG; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONGLONG].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].func = ps_fetch_float; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].pack_len = 4; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].php_type = IS_DOUBLE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_FLOAT].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].func = ps_fetch_double; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].pack_len = 8; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].php_type = IS_DOUBLE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DOUBLE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].func = ps_fetch_time; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIME].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].func = ps_fetch_date; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].func = ps_fetch_date; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].pack_len = MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDATE].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].func = ps_fetch_datetime; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].php_type= IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DATETIME].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].func = ps_fetch_datetime; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_TINY_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].php_type= IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_MEDIUM_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_LONG_BLOB].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].func = ps_fetch_bit; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_BIT].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VAR_STRING].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_VARCHAR].is_possibly_blob = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_STRING].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_DECIMAL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_NEWDECIMAL].can_ret_as_str_in_uni = TRUE; mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_ENUM].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].pack_len = MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_SET].php_type = IS_STRING; mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].func = ps_fetch_string; mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].pack_len= MYSQLND_PS_SKIP_RESULT_STR; mysqlnd_ps_fetch_functions[MYSQL_TYPE_GEOMETRY].php_type= IS_STRING;}/* }}} *//* {{{ mysqlnd_stmt_execute_store_params */voidmysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uchar **p, size_t *buf_len, unsigned int null_byte_offset){ unsigned int i = 0; unsigned left = (*buf_len - (*p - *buf)); unsigned int data_size = 0;/* 1. Store type information */ if (stmt->send_types_to_server) { /* 2 bytes per type, and leave 20 bytes for future use */ if (left < ((stmt->param_count * 2) + 20)) { unsigned int offset = *p - *buf; zend_uchar *tmp_buf; *buf_len = offset + stmt->param_count * 2 + 20; tmp_buf = emalloc(*buf_len); memcpy(tmp_buf, *buf, offset); *buf = tmp_buf; /* Update our pos pointer */ *p = *buf + offset; } for (i = 0; i < stmt->param_count; i++) { /* our types are not unsigned */#if SIZEOF_LONG==8 if (stmt->param_bind[i].type == MYSQL_TYPE_LONG) { stmt->param_bind[i].type = MYSQL_TYPE_LONGLONG; }#endif int2store(*p, stmt->param_bind[i].type); *p+= 2; } }/* 2. Store data */ /* 2.1 Calculate how much space we need */ for (i = 0; i < stmt->param_count; i++) { if (stmt->param_bind[i].zv && Z_TYPE_P(stmt->param_bind[i].zv) == IS_NULL) { continue; } switch (stmt->param_bind[i].type) { case MYSQL_TYPE_DOUBLE: data_size += 8; break;#if SIZEOF_LONG==8 case MYSQL_TYPE_LONGLONG: data_size += 8; break;#elif SIZEOF_LONG==4 case MYSQL_TYPE_LONG: data_size += 4; break;#else#error "Should not happen"#endif case MYSQL_TYPE_LONG_BLOB: if (!(stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED)) { /* User hasn't sent anything, we will send empty string. Empty string has length of 0, encoded in 1 byte. No real data will follow after it. */ data_size++; } break; case MYSQL_TYPE_VAR_STRING: data_size += 8; /* max 8 bytes for size */ convert_to_string_ex(&stmt->param_bind[i].zv); data_size += Z_STRLEN_P(stmt->param_bind[i].zv); break; } } /* 2.2 Enlarge the buffer, if needed */ left = (*buf_len - (*p - *buf)); if (left < data_size) { unsigned int offset = *p - *buf; zend_uchar *tmp_buf; *buf_len = offset + data_size + 10; /* Allocate + 10 for safety */ tmp_buf = emalloc(*buf_len); memcpy(tmp_buf, *buf, offset); *buf = tmp_buf; /* Update our pos pointer */ *p = *buf + offset; } /* 2.3 Store the actual data */ for (i = 0; i < stmt->param_count; i++) { zval *data = stmt->param_bind[i].zv; /* Handle long data */ if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) { (*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7)); } else { switch (stmt->param_bind[i].type) { case MYSQL_TYPE_DOUBLE: convert_to_double_ex(&data); float8store(*p, Z_DVAL_P(data)); (*p) += 8; break;#if SIZEOF_LONG==8 case MYSQL_TYPE_LONGLONG: convert_to_long_ex(&data); int8store(*p, Z_LVAL_P(data)); (*p) += 8; break;#elif SIZEOF_LONG==4 case MYSQL_TYPE_LONG: convert_to_long_ex(&data); int4store(*p, Z_LVAL_P(data)); (*p) += 4; break;#else#error "Should not happen"#endif case MYSQL_TYPE_LONG_BLOB: if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) { stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED; } else { /* send_long_data() not called, send empty string */ *p = php_mysqlnd_net_store_length(*p, 0); } break; case MYSQL_TYPE_VAR_STRING: /* We have already converted it to string */ { unsigned int len = Z_STRLEN_P(data); /* to is after p. The latter hasn't been moved */ *p = php_mysqlnd_net_store_length(*p, len); memcpy(*p, Z_STRVAL_P(data), len); (*p) += len; } break; default: /* Won't happen, but set to NULL */ (*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7)); break; } } }}/* }}} *//* {{{ mysqlnd_stmt_execute_generate_request */zend_uchar* mysqlnd_stmt_execute_generate_request(MYSQLND_STMT *stmt, size_t *request_len, zend_bool *free_buffer){ zend_uchar *p = stmt->cmd_buffer.buffer, *cmd_buffer = stmt->cmd_buffer.buffer; size_t cmd_buffer_length = stmt->cmd_buffer.length; unsigned int null_byte_offset, null_count= (stmt->param_count + 7) / 8; int4store(p, stmt->stmt_id); p += 4; int1store(p, stmt->flags); p++; /* Make it all zero */ int4store(p, 0); int1store(p, 1); /* and send 1 for iteration count */ p+= 4; null_byte_offset = p - cmd_buffer; memset(p, 0, null_count); p += null_count; int1store(p, stmt->send_types_to_server); p++; mysqlnd_stmt_execute_store_params(stmt, &cmd_buffer, &p, &cmd_buffer_length, null_byte_offset); *free_buffer = (cmd_buffer != stmt->cmd_buffer.buffer); *request_len = (p - cmd_buffer); return cmd_buffer;}/* }}} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -