From 13a4dd1891347f05101af486e1a5bf8f85bf040c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E8=8F=B2?= Date: Wed, 16 Nov 2016 10:32:52 +0800 Subject: [PATCH 1/4] support php ext read data after message begin --- .../thrift_protocol/php_thrift_protocol.cpp | 57 +++++++++++++++++++ .../thrift_protocol/php_thrift_protocol7.cpp | 28 +++++++++ 2 files changed, 85 insertions(+) diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp index 4c9062e805b..dc21a066f4c 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp @@ -1123,4 +1123,61 @@ PHP_FUNCTION(thrift_protocol_read_binary) { } } + +// 4 params: $transport $response_Typename $strict_read $buffer_size +PHP_FUNCTION(thrift_protocol_read_binary) { + int argc = ZEND_NUM_ARGS(); + + if (argc < 3) { + WRONG_PARAM_COUNT; + } + + zval ***args = (zval***) emalloc(argc * sizeof(zval**)); + zend_get_parameters_array_ex(argc, args); + + if (Z_TYPE_PP(args[0]) != IS_OBJECT) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "1st parameter is not an object (transport)"); + efree(args); + RETURN_NULL(); + } + + if (Z_TYPE_PP(args[1]) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "2nd parameter is not a string (typename of expected response struct)"); + efree(args); + RETURN_NULL(); + } + + if (argc == 4 && Z_TYPE_PP(args[3]) != IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "4nd parameter is not an integer (typename of expected buffer size)"); + efree(args); + RETURN_NULL(); + } + + try { + size_t buffer_size = 8192; + if (argc == 4) { + buffer_size = Z_LVAL_PP(args[3]); + } + + PHPInputTransport transport(*args[0], buffer_size); + char* obj_typename = Z_STRVAL_PP(args[1]); + convert_to_boolean(*args[2]); + bool strict_read = Z_BVAL_PP(args[2]); + efree(args); + args = NULL; + + createObject(obj_typename, return_value); + zval* spec = zend_read_static_property(zend_get_class_entry(return_value TSRMLS_CC), "_TSPEC", 6, false TSRMLS_CC); + binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); + } catch (const PHPExceptionWrapper& ex) { + zend_throw_exception_object(ex TSRMLS_CC); + RETURN_NULL(); + } catch (const std::exception& ex) { + throw_zend_exception_from_std_exception(ex TSRMLS_CC); + RETURN_NULL(); + } +} + + + #endif /* PHP_VERSION_ID < 70000 && PHP_VERSION_ID > 50000 */ diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp index 3c6c3db8e41..0592906731f 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp @@ -1068,4 +1068,32 @@ PHP_FUNCTION(thrift_protocol_read_binary) { } } +// 4 params: $transport $response_Typename $strict_read $buffer_size +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { + zval *protocol; + zend_string *obj_typename; + zend_bool strict_read; + size_t buffer_size = 8192; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "oSb|l", &protocol, &obj_typename, &strict_read, &buffer_size) == FAILURE) { + return; + } + + try { + PHPInputTransport transport(protocol, buffer_size); + int8_t messageType = 0; + int32_t sz = transport.readI32(); + + createObject(ZSTR_VAL(obj_typename), return_value); + zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); + binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); + } catch (const PHPExceptionWrapper& ex) { + zend_throw_exception_object(ex); + RETURN_NULL(); + } catch (const std::exception& ex) { + throw_zend_exception_from_std_exception(ex); + RETURN_NULL(); + } +} + #endif /* PHP_VERSION_ID >= 70000 */ From 843d87f0c7e69165d1489c7f2dd089b68790720d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E8=8F=B2?= Date: Wed, 16 Nov 2016 10:50:22 +0800 Subject: [PATCH 2/4] fix --- lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp | 3 ++- lib/php/src/ext/thrift_protocol/php_thrift_protocol.h | 1 + lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp index dc21a066f4c..5374286f420 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp @@ -98,6 +98,7 @@ const int BAD_VERSION = 4; static zend_function_entry thrift_protocol_functions[] = { PHP_FE(thrift_protocol_write_binary, NULL) PHP_FE(thrift_protocol_read_binary, NULL) + PHP_FE(thrift_protocol_read_binary_after_message_begin, NULL) {NULL, NULL, NULL} } ; @@ -1125,7 +1126,7 @@ PHP_FUNCTION(thrift_protocol_read_binary) { // 4 params: $transport $response_Typename $strict_read $buffer_size -PHP_FUNCTION(thrift_protocol_read_binary) { +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { int argc = ZEND_NUM_ARGS(); if (argc < 3) { diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h index 44d03ccdeba..04209973cfa 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h @@ -21,6 +21,7 @@ PHP_FUNCTION(thrift_protocol_write_binary); PHP_FUNCTION(thrift_protocol_read_binary); +PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin); extern zend_module_entry thrift_protocol_module_entry; #define phpext_thrift_protocol_ptr &thrift_protocol_module_entry diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp index 0592906731f..0ca0c52459f 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp @@ -88,6 +88,7 @@ const int BAD_VERSION = 4; static zend_function_entry thrift_protocol_functions[] = { PHP_FE(thrift_protocol_write_binary, nullptr) PHP_FE(thrift_protocol_read_binary, nullptr) + PHP_FE(thrift_protocol_read_binary_after_message_begin, nullptr) {nullptr, nullptr, nullptr} }; From 61da80b5ccbe7c63f5187e3296f0453d1abee41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E8=8F=B2?= Date: Wed, 16 Nov 2016 11:53:19 +0800 Subject: [PATCH 3/4] fix --- lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp index 0ca0c52459f..4aad911741a 100644 --- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp +++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol7.cpp @@ -1082,8 +1082,6 @@ PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin) { try { PHPInputTransport transport(protocol, buffer_size); - int8_t messageType = 0; - int32_t sz = transport.readI32(); createObject(ZSTR_VAL(obj_typename), return_value); zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); From 3c956e3446438f8d1a1fadaee198a32b71652e58 Mon Sep 17 00:00:00 2001 From: Robert Lu Date: Wed, 4 Oct 2017 03:18:38 +0800 Subject: [PATCH 4/4] compiler use thrift_protocol_read_binary_after_message_begin --- compiler/cpp/src/thrift/generate/t_php_generator.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc index 9b5062c6166..fe9b6a0b792 100644 --- a/compiler/cpp/src/thrift/generate/t_php_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc @@ -1332,11 +1332,24 @@ void t_php_generator::generate_process_function(std::ofstream& out, t_service* t string resultname = php_namespace(tservice->get_program()) + service_name_ + "_" + tfunction->get_name() + "_result"; + out << indent() << "$bin_accel = ($input instanceof " + << "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_read_binary_after_message_begin');" + << endl; + out << indent() << "if ($bin_accel)" << endl; + scope_up(out); + + out << indent() << "$args = thrift_protocol_read_binary_after_message_begin($input, '" << argsname + << "', $input->isStrictRead());" << endl; + + scope_down(out); + out << indent() << "else" << endl; + scope_up(out); out << indent() << "$args = new " << argsname << "();" << endl << indent() << "$args->read($input);" << endl; if (!binary_inline_) { out << indent() << "$input->readMessageEnd();" << endl; } + scope_down(out); t_struct* xs = tfunction->get_xceptions(); const std::vector& xceptions = xs->get_members();