in compiler/cpp/src/thrift/generate/t_php_generator.cc [1844:2104]
void t_php_generator::generate_service_client(t_service* tservice) {
ofstream_with_content_based_conditional_update& f_service_client = f_service_;
if (!classmap_) {
string f_service_client_name = package_dir_ + service_name_ + "Client.php";
f_service_client.open(f_service_client_name.c_str());
generate_service_header(tservice, f_service_client);
}
string extends = "";
string extends_client = "";
if (tservice->get_extends() != nullptr) {
extends = tservice->get_extends()->get_name();
extends_client = " extends " + php_namespace(tservice->get_extends()->get_program()) + extends
+ "Client";
}
f_service_client << "class " << php_namespace_declaration(tservice) << "Client" << extends_client
<< " implements " << php_namespace(tservice->get_program()) << service_name_ << "If" << '\n'
<<"{"<< '\n';
indent_up();
// Private members
if (extends.empty()) {
f_service_client << indent() << "protected $input_ = null;" << '\n' << indent()
<< "protected $output_ = null;" << '\n' << '\n';
f_service_client << indent() << "protected $seqid_ = 0;" << '\n' << '\n';
}
// Constructor function
f_service_client << indent() << "public function __construct($input, $output = null)" << '\n'
<< indent() << "{" << '\n';
indent_up();
if (!extends.empty()) {
f_service_client << indent() << "parent::__construct($input, $output);" << '\n';
} else {
f_service_client << indent() << "$this->input_ = $input;" << '\n'
<< indent() << "$this->output_ = $output ? $output : $input;" << '\n';
}
indent_down();
f_service_client << indent() << "}" << '\n' << '\n';
// Generate client method implementations
vector<t_function*> functions = tservice->get_functions();
vector<t_function*>::const_iterator f_iter;
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
t_struct* arg_struct = (*f_iter)->get_arglist();
const vector<t_field*>& fields = arg_struct->get_members();
vector<t_field*>::const_iterator fld_iter;
string funname = (*f_iter)->get_name();
f_service_client << '\n';
// Open function
indent(f_service_client) << "public function " << function_signature(*f_iter) << '\n';
scope_up(f_service_client);
indent(f_service_client) << "$this->send_" << funname << "(";
bool first = true;
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
if (first) {
first = false;
} else {
f_service_client << ", ";
}
f_service_client << "$" << (*fld_iter)->get_name();
}
f_service_client << ");" << '\n';
if (!(*f_iter)->is_oneway()) {
f_service_client << indent();
if (!(*f_iter)->get_returntype()->is_void()) {
f_service_client << "return ";
}
f_service_client << "$this->recv_" << funname << "();" << '\n';
}
scope_down(f_service_client);
f_service_client << '\n';
indent(f_service_client) << "public function send_" << function_signature(*f_iter) << '\n';
scope_up(f_service_client);
std::string argsname = php_namespace(tservice->get_program()) + service_name_ + "_"
+ (*f_iter)->get_name() + "_args";
f_service_client << indent() << "$args = new " << argsname << "();" << '\n';
for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
f_service_client << indent() << "$args->" << (*fld_iter)->get_name() << " = $"
<< (*fld_iter)->get_name() << ";" << '\n';
}
f_service_client << indent() << "$bin_accel = ($this->output_ instanceof "
<< "TBinaryProtocolAccelerated) && function_exists('thrift_protocol_write_binary');"
<< '\n';
f_service_client << indent() << "if ($bin_accel) {" << '\n';
indent_up();
string messageType = (*f_iter)->is_oneway() ? "TMessageType::ONEWAY" : "TMessageType::CALL";
f_service_client << indent() << "thrift_protocol_write_binary(" << '\n';
indent_up();
f_service_client << indent() << "$this->output_," << '\n'
<< indent() << "'" << (*f_iter)->get_name() << "'," << '\n'
<< indent() << messageType << "," << '\n'
<< indent() << "$args," << '\n'
<< indent() << "$this->seqid_," << '\n'
<< indent() << "$this->output_->isStrictWrite()" << '\n';
indent_down();
f_service_client << indent() << ");" << '\n';
indent_down();
f_service_client << indent() << "} else {" << '\n';
indent_up();
// Serialize the request header
if (binary_inline_) {
f_service_client << indent() << "$buff = pack('N', (0x80010000 | " << messageType << "));" << '\n'
<< indent() << "$buff .= pack('N', strlen('" << funname << "'));" << '\n'
<< indent() << "$buff .= '" << funname << "';" << '\n' << indent()
<< "$buff .= pack('N', $this->seqid_);" << '\n';
} else {
f_service_client << indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name()
<< "', " << messageType << ", $this->seqid_);" << '\n';
}
// Write to the stream
if (binary_inline_) {
f_service_client << indent() << "$args->write($buff);" << '\n' << indent()
<< "$this->output_->write($buff);" << '\n' << indent()
<< "$this->output_->flush();" << '\n';
} else {
f_service_client << indent() << "$args->write($this->output_);" << '\n' << indent()
<< "$this->output_->writeMessageEnd();" << '\n' << indent()
<< "$this->output_->getTransport()->flush();" << '\n';
}
scope_down(f_service_client);
scope_down(f_service_client);
if (!(*f_iter)->is_oneway()) {
std::string resultname = php_namespace(tservice->get_program()) + service_name_ + "_"
+ (*f_iter)->get_name() + "_result";
t_struct noargs(program_);
t_function recv_function((*f_iter)->get_returntype(),
string("recv_") + (*f_iter)->get_name(),
&noargs);
// Open function
f_service_client << '\n' << indent() << "public function " << function_signature(&recv_function)
<< '\n';
scope_up(f_service_client);
f_service_client << indent() << "$bin_accel = ($this->input_ instanceof "
<< "TBinaryProtocolAccelerated)"
<< " && function_exists('thrift_protocol_read_binary');" << '\n';
f_service_client << indent() << "if ($bin_accel) {" << '\n';
indent_up();
f_service_client << indent() << "$result = thrift_protocol_read_binary(" << '\n';
indent_up();
f_service_client << indent() << "$this->input_," << '\n'
<< indent() << "'" << resultname << "'," << '\n'
<< indent() << "$this->input_->isStrictRead()" << '\n';
indent_down();
f_service_client << indent() << ");" << '\n';
indent_down();
f_service_client << indent() << "} else {" << '\n';
indent_up();
f_service_client << indent() << "$rseqid = 0;" << '\n'
<< indent() << "$fname = null;" << '\n'
<< indent() << "$mtype = 0;" << '\n' << '\n';
if (binary_inline_) {
t_field ffname(g_type_string, "fname");
t_field fseqid(g_type_i32, "rseqid");
f_service_client << indent() << "$ver = unpack('N', $this->input_->readAll(4));" << '\n'
<< indent() << "$ver = $ver[1];" << '\n' << indent() << "$mtype = $ver & 0xff;"
<< '\n' << indent() << "$ver = $ver & 0xffff0000;" << '\n' << indent()
<< "if ($ver != 0x80010000) throw new "
<< "TProtocolException('Bad version identifier: '.$ver, "
<< "TProtocolException::BAD_VERSION);" << '\n';
generate_deserialize_field(f_service_client, &ffname, "", true);
generate_deserialize_field(f_service_client, &fseqid, "", true);
} else {
f_service_client << indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << '\n'
<< indent() << "if ($mtype == TMessageType::EXCEPTION) {" << '\n';
indent_up();
f_service_client << indent() << "$x = new TApplicationException();" << '\n'
<< indent() << "$x->read($this->input_);" << '\n'
<< indent() << "$this->input_->readMessageEnd();" << '\n'
<< indent() << "throw $x;" << '\n';
indent_down();
f_service_client << indent() << "}" << '\n';
}
f_service_client << indent() << "$result = new " << resultname << "();" << '\n'
<< indent() << "$result->read($this->input_);" << '\n';
if (!binary_inline_) {
f_service_client << indent() << "$this->input_->readMessageEnd();" << '\n';
}
scope_down(f_service_client);
// Careful, only return result if not a void function
if (!(*f_iter)->get_returntype()->is_void()) {
f_service_client << indent() << "if ($result->success !== null) {" << '\n';
indent_up();
f_service_client << indent() << "return $result->success;" << '\n';
indent_down();
f_service_client << indent() << "}" << '\n';
}
t_struct* xs = (*f_iter)->get_xceptions();
const std::vector<t_field*>& xceptions = xs->get_members();
vector<t_field*>::const_iterator x_iter;
for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
f_service_client << indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << '\n';
indent_up();
f_service_client << indent() << "throw $result->" << (*x_iter)->get_name() << ";" << '\n';
indent_down();
f_service_client << indent() << "}" << '\n';
}
// Careful, only return _result if not a void function
if ((*f_iter)->get_returntype()->is_void()) {
indent(f_service_client) << "return;" << '\n';
} else {
f_service_client << indent() << "throw new \\Exception(\"" << (*f_iter)->get_name()
<< " failed: unknown result\");" << '\n';
}
// Close function
scope_down(f_service_client);
}
}
indent_down();
f_service_client << "}" << '\n';
// Close service client file
if (!classmap_) {
f_service_client.close();
}
}