[ 
https://issues.apache.org/jira/browse/THRIFT-1241?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13068435#comment-13068435
 ] 

Darius Staisiunas commented on THRIFT-1241:
-------------------------------------------

--- compiler/cpp/src/generate/t_php_generator.cc.orig   2011-06-23 
12:28:07.000000000 +0300
+++ compiler/cpp/src/generate/t_php_generator.cc        2011-07-20 
18:09:05.403366001 +0300
@@ -29,6 +29,12 @@
 #include "platform.h"
 using namespace std;
 
+#define NSGLOBAL  (nsglobal_.size() ? nsglobal_ : "")
+#define NSGLOBAL_A ("\\" + NSGLOBAL )
+#define NSGLOBAL_B ( NSGLOBAL + "\\")
+#define NSGLOBAL_AB ("\\" + NSGLOBAL + "\\")
+#define NS_ROOT ( namespace53_ ? "\\" : "")
+
 
 /**
  * PHP code generator.
@@ -60,6 +66,18 @@
     iter = parsed_options.find("oop");
     oop_ = (iter != parsed_options.end());
 
+    iter = parsed_options.find("namespace53");
+    namespace53_ = (iter != parsed_options.end());
+
+    iter = parsed_options.find("nsglobal");
+    if(iter != parsed_options.end()) {
+      if(namespace53_) nsglobal_ = iter->second;
+      else throw "cannot use nsglobal without namespace53.";
+    }
+    else {
+      nsglobal_ = ""; // by default global namespace is empty
+    }
+
     if (oop_ && binary_inline_) {
       throw "oop and inlined are mutually exclusive.";
     }
@@ -183,7 +201,24 @@
 
   std::string php_namespace(t_program* p) {
     std::string ns = p->get_namespace("php");
-    return ns.size() ? (ns + "_") : "";
+    size_t position = ns.find( "." );
+    while (position != string::npos) {
+      ns.replace(position, 1, "\\");
+      position = ns.find(".", position+1);
+    }
+    if(namespace53_) return (nsglobal_.size() ? NSGLOBAL_AB : NSGLOBAL_B) + 
(ns.size() ? (ns + "\\") : "");
+    else return "";
+  }
+
+  std::string php_namespace_suffix(const t_program* p) {
+    std::string ns = p->get_namespace("php");
+    size_t position = ns.find( "." );
+    while (position != string::npos) {
+      ns.replace(position, 1, "\\");
+      position = ns.find(".", position+1);
+    }    
+    if (namespace53_) return (nsglobal_.size() ? NSGLOBAL_B : NSGLOBAL) + ns;
+    else return "";
   }
 
   std::string php_path(t_program* p) {
@@ -199,7 +234,7 @@
       }
     }
 
-    return ns + '/' + p->get_name();
+    return ((namespace53_) ? ns + '/' : "" ) + p->get_name();
   }
 
  private:
@@ -237,7 +272,16 @@
    * Whether to use OOP base class TBase
    */
   bool oop_;
-
+  
+  /**
+   * Generate namespaces in PHP5.3 style
+   */
+  bool namespace53_;
+ 
+  /**
+   * Global namespace for PHP 5.3
+   */
+  std::string nsglobal_;
 };
 
 
@@ -263,9 +307,9 @@
 
   // Print header
   f_types_ <<
-    "<?php" << endl <<
-    autogen_comment() <<
-    php_includes();
+    "<?php" << endl;
+  if(namespace53_) f_types_ << "namespace " << 
php_namespace_suffix(get_program()) << ";" << endl;
+  f_types_ << autogen_comment() << php_includes();
 
   // Include other Thrift includes
   const vector<t_program*>& includes = program_->get_includes();
@@ -282,8 +326,9 @@
     string f_consts_name = package_dir_+program_name_+"_constants.php";
     f_consts_.open(f_consts_name.c_str());
     f_consts_ <<
-      "<?php" << endl <<
-      autogen_comment() <<
+      "<?php" << endl;
+     if(namespace53_) f_consts_ << "namespace " << 
php_namespace_suffix(get_program()) << ";" << endl;
+     f_consts_ << autogen_comment() <<
       "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" + php_path(program_) 
+ "/" + program_name_ + "_types.php';" << endl <<
       endl <<
       "$GLOBALS['" << program_name_ << "_CONSTANTS'] = array();" << endl <<
@@ -348,7 +393,7 @@
   // code but you can't do things like an 'extract' on it, which is a bit of
   // a downer.
   f_types_ <<
-    "final class " << php_namespace(tenum->get_program()) << tenum->get_name() 
<< " {" << endl;
+    "final class " << tenum->get_name() << " {" << endl;
   indent_up();
 
   for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
@@ -420,7 +465,7 @@
   } else if (type->is_enum()) {
     indent(out) << value->get_integer();
   } else if (type->is_struct() || type->is_xception()) {
-    out << "new " << php_namespace(type->get_program()) << type->get_name() << 
"(array(" << endl;
+    out << "new " << NS_ROOT << php_namespace(type->get_program()) << 
type->get_name() << "(array(" << endl;
     indent_up();
     const vector<t_field*>& fields = ((t_struct*)type)->get_members();
     vector<t_field*>::const_iterator f_iter;
@@ -513,7 +558,7 @@
 void t_php_generator::generate_php_type_spec(ofstream& out,
                                              t_type* t) {
   t = get_true_type(t);
-  indent(out) << "'type' => " << type_to_enum(t) << "," << endl;
+  indent(out) << "'type' => " << NS_ROOT << type_to_enum(t) << "," << endl;
 
   if (t->is_base_type() || t->is_enum()) {
     // Noop, type is all we need
@@ -522,8 +567,8 @@
   } else if (t->is_map()) {
     t_type* ktype = get_true_type(((t_map*)t)->get_key_type());
     t_type* vtype = get_true_type(((t_map*)t)->get_val_type());
-    indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << endl;
-    indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << endl;
+    indent(out) << "'ktype' => " << NS_ROOT << type_to_enum(ktype) << "," << 
endl;
+    indent(out) << "'vtype' => " << NS_ROOT << type_to_enum(vtype) << "," << 
endl;
     indent(out) << "'key' => array(" << endl;
     indent_up();
     generate_php_type_spec(out, ktype);
@@ -541,7 +586,7 @@
     } else {
       etype = get_true_type(((t_set*)t)->get_elem_type());
     }
-    indent(out) << "'etype' => " << type_to_enum(etype) <<"," << endl;
+    indent(out) << "'etype' => " << NS_ROOT << type_to_enum(etype) <<"," << 
endl;
     indent(out) << "'elem' => array(" << endl;
     indent_up();
     generate_php_type_spec(out, etype);
@@ -621,11 +666,11 @@
   vector<t_field*>::const_iterator m_iter;
 
   out <<
-    "class " << php_namespace(tstruct->get_program()) << tstruct->get_name();
+    "class " << tstruct->get_name();
   if (is_exception) {
-    out << " extends TException";
+    out << " extends " << NS_ROOT << "TException";
   } else if (oop_) {
-    out << " extends TBase";
+    out << " extends " << NS_ROOT << "TBase";
   }
   out <<
     " {" << endl;
@@ -737,7 +782,7 @@
       t_field ffid(g_type_i16, "fid");
       generate_deserialize_field(out, &fftype);
       out <<
-        indent() << "if ($ftype == TType::STOP) {" << endl <<
+        indent() << "if ($ftype == " << NS_ROOT << "TType::STOP) {" << endl <<
         indent() << "  break;" << endl <<
         indent() << "}" << endl;
       generate_deserialize_field(out, &ffid);
@@ -746,7 +791,7 @@
         "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << endl;
       // Check for field STOP marker and break
       indent(out) <<
-        "if ($ftype == TType::STOP) {" << endl;
+        "if ($ftype == " << NS_ROOT << "TType::STOP) {" << endl;
       indent_up();
       indent(out) <<
         "break;" << endl;
@@ -766,14 +811,14 @@
         indent(out) <<
           "case " << (*f_iter)->get_key() << ":" << endl;
         indent_up();
-        indent(out) << "if ($ftype == " << type_to_enum((*f_iter)->get_type()) 
<< ") {" << endl;
+        indent(out) << "if ($ftype == " << NS_ROOT << 
type_to_enum((*f_iter)->get_type()) << ") {" << endl;
         indent_up();
         generate_deserialize_field(out, *f_iter, "this->");
         indent_down();
         out <<
           indent() << "} else {" << endl;
         if (binary_inline_) {
-          indent(out) <<  "  $xfer += TProtocol::skipBinary($input, $ftype);" 
<< endl;
+          indent(out) <<  "  $xfer += " << NS_ROOT << 
"TProtocol::skipBinary($input, $ftype);" << endl;
         } else {
           indent(out) <<  "  $xfer += $input->skip($ftype);" << endl;
         }
@@ -786,7 +831,7 @@
       // In the default case we skip the field
       indent(out) <<  "default:" << endl;
       if (binary_inline_) {
-        indent(out) <<  "  $xfer += TProtocol::skipBinary($input, $ftype);" << 
endl;
+        indent(out) <<  "  $xfer += " << NS_ROOT << 
"TProtocol::skipBinary($input, $ftype);" << endl;
       } else {
         indent(out) <<  "  $xfer += $input->skip($ftype);" << endl;
       }
@@ -865,7 +910,7 @@
         indent() << "if (!is_" << expect << "($this->" << 
(*f_iter)->get_name() << ")) {" << endl;
       indent_up();
       out <<
-        indent() << "throw new TProtocolException('Bad type in structure.', 
TProtocolException::INVALID_DATA);" << endl;
+        indent() << "throw new " << NS_ROOT << "TProtocolException('Bad type 
in structure.', " << NS_ROOT << "TProtocolException::INVALID_DATA);" << endl;
       scope_down(out);
     }
 
@@ -878,7 +923,7 @@
       indent(out) <<
         "$xfer += $output->writeFieldBegin(" <<
         "'" << (*f_iter)->get_name() << "', " <<
-        type_to_enum((*f_iter)->get_type()) << ", " <<
+        NS_ROOT << type_to_enum((*f_iter)->get_type()) << ", " <<
         (*f_iter)->get_key() << ");" << endl;
     }
 
@@ -898,7 +943,7 @@
 
   if (binary_inline_) {
     out <<
-      indent() << "$output .= pack('c', TType::STOP);" << endl;
+      indent() << "$output .= pack('c', " << NS_ROOT << "TType::STOP);" << 
endl;
   } else {
     out <<
       indent() << "$xfer += $output->writeFieldStop();" << endl <<
@@ -923,9 +968,9 @@
   string f_service_name = package_dir_+service_name_+".php";
   f_service_.open(f_service_name.c_str());
 
-  f_service_ <<
-    "<?php" << endl <<
-    autogen_comment() <<
+  f_service_ << "<?php" << endl;
+  if(namespace53_) f_service_ << "namespace " << 
php_namespace_suffix(tservice->get_program()) << ";" << endl;
+  f_service_ << autogen_comment() <<
     php_includes();
 
   f_service_ <<
@@ -969,7 +1014,7 @@
   string extends_processor = "";
   if (tservice->get_extends() != NULL) {
     extends = tservice->get_extends()->get_name();
-    extends_processor = " extends " + extends + "Processor";
+    extends_processor = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + extends + "Processor";
   }
 
   // Generate the header portion
@@ -1027,10 +1072,10 @@
       indent() << "  throw new Exception('Function '.$fname.' not 
implemented.');" << endl;
   } else {
     f_service_ <<
-      indent() << "  $input->skip(TType::STRUCT);" << endl <<
+      indent() << "  $input->skip(" << NS_ROOT << "TType::STRUCT);" << endl <<
       indent() << "  $input->readMessageEnd();" << endl <<
-      indent() << "  $x = new TApplicationException('Function '.$fname.' not 
implemented.', TApplicationException::UNKNOWN_METHOD);" << endl <<
-      indent() << "  $output->writeMessageBegin($fname, 
TMessageType::EXCEPTION, $rseqid);" << endl <<
+      indent() << "  $x = new " << NS_ROOT << "TApplicationException('Function 
'.$fname.' not implemented.', " << NS_ROOT << 
"TApplicationException::UNKNOWN_METHOD);" << endl <<
+      indent() << "  $output->writeMessageBegin($fname, " << NS_ROOT << 
"TMessageType::EXCEPTION, $rseqid);" << endl <<
       indent() << "  $x->write($output);" << endl <<
       indent() << "  $output->writeMessageEnd();" << endl <<
       indent() << "  $output->getTransport()->flush();" << endl <<
@@ -1144,14 +1189,14 @@
   }
 
   f_service_ <<
-    indent() << "$bin_accel = ($output instanceof 
TProtocol::$TBINARYPROTOCOLACCELERATED) && 
function_exists('thrift_protocol_write_binary');" << endl;
+    indent() << "$bin_accel = ($output instanceof " << NS_ROOT << 
"TProtocol::$TBINARYPROTOCOLACCELERATED) && 
function_exists('thrift_protocol_write_binary');" << endl;
 
   f_service_ <<
     indent() << "if ($bin_accel)" << endl;
   scope_up(f_service_);
 
   f_service_ <<
-    indent() << "thrift_protocol_write_binary($output, '" << 
tfunction->get_name() << "', TMessageType::REPLY, $result, $seqid, 
$output->isStrictWrite());" << endl;
+    indent() << "thrift_protocol_write_binary($output, '" << 
tfunction->get_name() << "', " << NS_ROOT << "TMessageType::REPLY, $result, 
$seqid, $output->isStrictWrite());" << endl;
 
   scope_down(f_service_);
   f_service_ <<
@@ -1161,7 +1206,7 @@
   // Serialize the request header
   if (binary_inline_) {
     f_service_ <<
-      indent() << "$buff = pack('N', (0x80010000 | TMessageType::REPLY)); " << 
endl <<
+      indent() << "$buff = pack('N', (0x80010000 | " << NS_ROOT << 
"TMessageType::REPLY)); " << endl <<
       indent() << "$buff .= pack('N', strlen('" << tfunction->get_name() << 
"'));" << endl <<
       indent() << "$buff .= '" << tfunction->get_name() << "';" << endl <<
       indent() << "$buff .= pack('N', $seqid);" << endl <<
@@ -1170,7 +1215,7 @@
       indent() << "$output->flush();" << endl;
   } else {
     f_service_ <<
-      indent() << "$output->writeMessageBegin('" << tfunction->get_name() << 
"', TMessageType::REPLY, $seqid);" << endl <<
+      indent() << "$output->writeMessageBegin('" << tfunction->get_name() << 
"', " << NS_ROOT << "TMessageType::REPLY, $seqid);" << endl <<
       indent() << "$result->write($output);" << endl <<
       indent() << "$output->getTransport()->flush();" << endl;
   }
@@ -1238,8 +1283,8 @@
   string extends = "";
   string extends_if = "";
   if (tservice->get_extends() != NULL) {
-    extends = " extends " + tservice->get_extends()->get_name();
-    extends_if = " extends " + tservice->get_extends()->get_name() + "If";
+    extends = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + 
tservice->get_extends()->get_name();
+    extends_if = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + 
tservice->get_extends()->get_name() + "If";
   }
   f_service_ <<
     "interface " << service_name_ << "If" << extends_if << " {" << endl;
@@ -1262,8 +1307,8 @@
   string extends = "";
   string extends_if = "";
   if (tservice->get_extends() != NULL) {
-    extends = " extends " + tservice->get_extends()->get_name();
-    extends_if = " extends " + tservice->get_extends()->get_name() + "Rest";
+    extends = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + 
tservice->get_extends()->get_name();
+    extends_if = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + 
tservice->get_extends()->get_name() + "Rest";
   }
   f_service_ <<
     "class " << service_name_ << "Rest" << extends_if << " {" << endl;
@@ -1359,11 +1404,11 @@
   string extends_client = "";
   if (tservice->get_extends() != NULL) {
     extends = tservice->get_extends()->get_name();
-    extends_client = " extends " + extends + "Client";
+    extends_client = " extends " + 
php_namespace(tservice->get_extends()->get_program()) + extends + "Client";
   }
 
   out <<
-    "class " << service_name_ << "Client" << extends_client << " implements " 
<< service_name_ << "If {" << endl;
+    "class " << service_name_ << "Client" << extends_client << " implements " 
<<  (namespace53_ ? php_namespace(tservice->get_program()) : "") << 
service_name_ << "If {" << endl;
   indent_up();
 
   // Private members
@@ -1433,7 +1478,7 @@
       "public function send_" << function_signature(*f_iter) << endl;
     scope_up(out);
 
-      std::string argsname = php_namespace(tservice->get_program()) + 
service_name_ + "_" + (*f_iter)->get_name() + "_args";
+      std::string argsname = (namespace53_ ? 
php_namespace(tservice->get_program()) : "") + service_name_ + "_" + 
(*f_iter)->get_name() + "_args";
 
       out <<
         indent() << "$args = new " << argsname << "();" << endl;
@@ -1444,14 +1489,14 @@
       }
 
       out <<
-        indent() << "$bin_accel = ($this->output_ instanceof 
TProtocol::$TBINARYPROTOCOLACCELERATED) && 
function_exists('thrift_protocol_write_binary');" << endl;
+        indent() << "$bin_accel = ($this->output_ instanceof " << NS_ROOT << 
"TProtocol::$TBINARYPROTOCOLACCELERATED) && 
function_exists('thrift_protocol_write_binary');" << endl;
 
       out <<
         indent() << "if ($bin_accel)" << endl;
       scope_up(out);
 
       out <<
-        indent() << "thrift_protocol_write_binary($this->output_, '" << 
(*f_iter)->get_name() << "', TMessageType::CALL, $args, $this->seqid_, 
$this->output_->isStrictWrite());" << endl;
+        indent() << "thrift_protocol_write_binary($this->output_, '" << 
(*f_iter)->get_name() << "', " << NS_ROOT << "TMessageType::CALL, $args, 
$this->seqid_, $this->output_->isStrictWrite());" << endl;
 
       scope_down(out);
       out <<
@@ -1461,13 +1506,13 @@
       // Serialize the request header
       if (binary_inline_) {
         out <<
-          indent() << "$buff = pack('N', (0x80010000 | TMessageType::CALL));" 
<< endl <<
+          indent() << "$buff = pack('N', (0x80010000 | " << NS_ROOT << 
"TMessageType::CALL));" << endl <<
           indent() << "$buff .= pack('N', strlen('" << funname << "'));" << 
endl <<
           indent() << "$buff .= '" << funname << "';" << endl <<
           indent() << "$buff .= pack('N', $this->seqid_);" << endl;
       } else {
         out <<
-          indent() << "$this->output_->writeMessageBegin('" << 
(*f_iter)->get_name() << "', TMessageType::CALL, $this->seqid_);" << endl;
+          indent() << "$this->output_->writeMessageBegin('" << 
(*f_iter)->get_name() << "', " << NS_ROOT << "TMessageType::CALL, 
$this->seqid_);" << endl;
       }
 
       // Write to the stream
@@ -1502,7 +1547,7 @@
       scope_up(out);
 
       out <<
-        indent() << "$bin_accel = ($this->input_ instanceof 
TProtocol::$TBINARYPROTOCOLACCELERATED)"
+        indent() << "$bin_accel = ($this->input_ instanceof " << NS_ROOT << 
"TProtocol::$TBINARYPROTOCOLACCELERATED)"
                  << " && function_exists('thrift_protocol_read_binary');" << 
endl;
 
       out <<
@@ -1525,14 +1570,14 @@
           indent() << "$ver = $ver[1];" << endl <<
           indent() << "$mtype = $ver & 0xff;" << endl <<
           indent() << "$ver = $ver & 0xffff0000;" << endl <<
-          indent() << "if ($ver != 0x80010000) throw new 
TProtocolException('Bad version identifier: '.$ver, 
TProtocolException::BAD_VERSION);" << endl;
+          indent() << "if ($ver != 0x80010000) throw new " << NS_ROOT << 
"TProtocolException('Bad version identifier: '.$ver, " << NS_ROOT << 
"TProtocolException::BAD_VERSION);" << endl;
         generate_deserialize_field(out, &ffname, "", true);
         generate_deserialize_field(out, &fseqid, "", true);
       } else {
         out <<
           indent() << "$this->input_->readMessageBegin($fname, $mtype, 
$rseqid);" << endl <<
-          indent() << "if ($mtype == TMessageType::EXCEPTION) {" << endl <<
-          indent() << "  $x = new TApplicationException();" << endl <<
+          indent() << "if ($mtype == " << NS_ROOT << "TMessageType::EXCEPTION) 
{" << endl <<
+          indent() << "  $x = new " << NS_ROOT << "TApplicationException();" 
<< endl <<
           indent() << "  $x->read($this->input_);" << endl <<
           indent() << "  $this->input_->readMessageEnd();" << endl <<
           indent() << "  throw $x;" << endl <<
@@ -1574,7 +1619,7 @@
           "return;" << endl;
       } else {
         out <<
-          indent() << "throw new Exception(\"" << (*f_iter)->get_name() << " 
failed: unknown result\");" << endl;
+          indent() << "throw new " << NS_ROOT << "Exception(\"" << 
(*f_iter)->get_name() << " failed: unknown result\");" << endl;
       }
 
     // Close function
@@ -2046,8 +2091,8 @@
     } else {
       indent(out) <<
         "$output->writeMapBegin(" <<
-        type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
-        type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
+        NS_ROOT << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
+        NS_ROOT << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   } else if (ttype->is_set()) {
@@ -2059,7 +2104,7 @@
     } else {
       indent(out) <<
         "$output->writeSetBegin(" <<
-        type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
+        NS_ROOT << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   } else if (ttype->is_list()) {
@@ -2071,7 +2116,7 @@
     } else {
       indent(out) <<
         "$output->writeListBegin(" <<
-        type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
+        NS_ROOT << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   }
@@ -2313,5 +2358,6 @@
 "    autoload:        Generate PHP with autoload\n"
 "    oop:             Generate PHP with object oriented subclasses\n"
 "    rest:            Generate PHP REST processors\n"
+"    namespace53:     Generate PHP namespaces as defined in PHP 5.3\n"
 )
 

> php namespace generation
> ------------------------
>
>                 Key: THRIFT-1241
>                 URL: https://issues.apache.org/jira/browse/THRIFT-1241
>             Project: Thrift
>          Issue Type: Improvement
>          Components: PHP - Compiler
>    Affects Versions: 0.7
>         Environment: PHP 5.3
>            Reporter: Darius Staisiunas
>              Labels: patch
>             Fix For: 0.7
>
>
> Patch is based mainly on https://issues.apache.org/jira/browse/THRIFT-777, 
> but some more improvements:
> namespace can be specified with dots '.' like for every other language
> for example:
> namespace php com.onego.thrift
> would generate in php file
> namespace com\onego\thrift
> to generate php files with namespaces use:
> thrift --gen php:namespace53 example.thrift

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to