You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@thrift.apache.org by ro...@apache.org on 2012/09/05 21:47:17 UTC

svn commit: r1381323 [1/5] - in /thrift/trunk: compiler/cpp/src/generate/ lib/php/ lib/php/lib/ lib/php/lib/Thrift/ lib/php/lib/Thrift/Base/ lib/php/lib/Thrift/ClassLoader/ lib/php/lib/Thrift/Exception/ lib/php/lib/Thrift/Factory/ lib/php/lib/Thrift/Pr...

Author: roger
Date: Wed Sep  5 19:47:14 2012
New Revision: 1381323

URL: http://svn.apache.org/viewvc?rev=1381323&view=rev
Log:
THRIFT-1615 PHP Namespace (was Thrift for Symfony 2)
Patch: Xavier HAUSHERR

Added:
    thrift/trunk/lib/php/lib/
    thrift/trunk/lib/php/lib/Thrift/
    thrift/trunk/lib/php/lib/Thrift/Base/
    thrift/trunk/lib/php/lib/Thrift/Base/TBase.php
    thrift/trunk/lib/php/lib/Thrift/ClassLoader/
    thrift/trunk/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php
    thrift/trunk/lib/php/lib/Thrift/Exception/
    thrift/trunk/lib/php/lib/Thrift/Exception/TApplicationException.php
    thrift/trunk/lib/php/lib/Thrift/Exception/TException.php
    thrift/trunk/lib/php/lib/Thrift/Exception/TProtocolException.php
    thrift/trunk/lib/php/lib/Thrift/Exception/TTransportException.php
    thrift/trunk/lib/php/lib/Thrift/Factory/
    thrift/trunk/lib/php/lib/Thrift/Factory/TBinaryProtocolFactory.php
    thrift/trunk/lib/php/lib/Thrift/Factory/TCompactProtocolFactory.php
    thrift/trunk/lib/php/lib/Thrift/Factory/TJSONProtocolFactory.php
    thrift/trunk/lib/php/lib/Thrift/Factory/TProtocolFactory.php
    thrift/trunk/lib/php/lib/Thrift/Factory/TStringFuncFactory.php
    thrift/trunk/lib/php/lib/Thrift/Factory/TTransportFactory.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/
    thrift/trunk/lib/php/lib/Thrift/Protocol/JSON/
    thrift/trunk/lib/php/lib/Thrift/Protocol/JSON/BaseContext.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/JSON/ListContext.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/JSON/LookaheadReader.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/JSON/PairContext.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/TBinaryProtocol.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/TBinaryProtocolAccelerated.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/TCompactProtocol.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/TJSONProtocol.php
    thrift/trunk/lib/php/lib/Thrift/Protocol/TProtocol.php
    thrift/trunk/lib/php/lib/Thrift/Serializer/
    thrift/trunk/lib/php/lib/Thrift/Serializer/TBinarySerializer.php
    thrift/trunk/lib/php/lib/Thrift/Server/
    thrift/trunk/lib/php/lib/Thrift/Server/TForkingServer.php
    thrift/trunk/lib/php/lib/Thrift/Server/TServer.php
    thrift/trunk/lib/php/lib/Thrift/Server/TServerSocket.php
    thrift/trunk/lib/php/lib/Thrift/Server/TServerTransport.php
    thrift/trunk/lib/php/lib/Thrift/Server/TSimpleServer.php
    thrift/trunk/lib/php/lib/Thrift/StringFunc/
    thrift/trunk/lib/php/lib/Thrift/StringFunc/Core.php
    thrift/trunk/lib/php/lib/Thrift/StringFunc/Mbstring.php
    thrift/trunk/lib/php/lib/Thrift/StringFunc/TStringFunc.php
    thrift/trunk/lib/php/lib/Thrift/Transport/
    thrift/trunk/lib/php/lib/Thrift/Transport/TBufferedTransport.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TFramedTransport.php
    thrift/trunk/lib/php/lib/Thrift/Transport/THttpClient.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TMemoryBuffer.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TNullTransport.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TPhpStream.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TSocket.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TSocketPool.php
    thrift/trunk/lib/php/lib/Thrift/Transport/TTransport.php
    thrift/trunk/lib/php/lib/Thrift/Type/
    thrift/trunk/lib/php/lib/Thrift/Type/TMessageType.php
    thrift/trunk/lib/php/lib/Thrift/Type/TType.php
    thrift/trunk/lib/php/test/Test/
    thrift/trunk/lib/php/test/Test/Thrift/
    thrift/trunk/lib/php/test/Test/Thrift/Fixtures.php
    thrift/trunk/lib/php/test/Test/Thrift/Protocol/
    thrift/trunk/lib/php/test/Test/Thrift/Protocol/TestTJSONProtocol.php
Modified:
    thrift/trunk/compiler/cpp/src/generate/t_php_generator.cc
    thrift/trunk/lib/php/Makefile.am
    thrift/trunk/lib/php/README
    thrift/trunk/lib/php/README.apache
    thrift/trunk/lib/php/src/protocol/TBinaryProtocol.php
    thrift/trunk/lib/php/src/protocol/TBinarySerializer.php
    thrift/trunk/lib/php/src/protocol/TCompactProtocol.php
    thrift/trunk/lib/php/src/protocol/TJSONProtocol.php
    thrift/trunk/lib/php/src/protocol/TProtocol.php
    thrift/trunk/lib/php/src/server/TForkingServer.php
    thrift/trunk/lib/php/src/server/TServer.php
    thrift/trunk/lib/php/src/server/TSimpleServer.php
    thrift/trunk/lib/php/src/transport/TBufferedTransport.php
    thrift/trunk/lib/php/src/transport/TFramedTransport.php
    thrift/trunk/lib/php/src/transport/THttpClient.php
    thrift/trunk/lib/php/src/transport/TMemoryBuffer.php
    thrift/trunk/lib/php/src/transport/TNullTransport.php
    thrift/trunk/lib/php/src/transport/TPhpStream.php
    thrift/trunk/lib/php/src/transport/TServerSocket.php
    thrift/trunk/lib/php/src/transport/TServerTransport.php
    thrift/trunk/lib/php/src/transport/TSocket.php
    thrift/trunk/lib/php/src/transport/TSocketPool.php
    thrift/trunk/lib/php/src/transport/TTransport.php
    thrift/trunk/lib/php/src/transport/TTransportFactory.php
    thrift/trunk/lib/php/test/Makefile.am
    thrift/trunk/test/php/TestClient.php
    thrift/trunk/tutorial/php/PhpClient.php
    thrift/trunk/tutorial/php/PhpServer.php

Modified: thrift/trunk/compiler/cpp/src/generate/t_php_generator.cc
URL: http://svn.apache.org/viewvc/thrift/trunk/compiler/cpp/src/generate/t_php_generator.cc?rev=1381323&r1=1381322&r2=1381323&view=diff
==============================================================================
--- thrift/trunk/compiler/cpp/src/generate/t_php_generator.cc (original)
+++ thrift/trunk/compiler/cpp/src/generate/t_php_generator.cc Wed Sep  5 19:47:14 2012
@@ -33,7 +33,6 @@ using namespace std;
 #define NSGLOBAL_A ("\\" + NSGLOBAL )
 #define NSGLOBAL_B ( NSGLOBAL + "\\")
 #define NSGLOBAL_AB ("\\" + NSGLOBAL + "\\")
-#define NS_ROOT ( namespace_php_ ? "\\" : "")
 
 
 /**
@@ -60,19 +59,12 @@ class t_php_generator : public t_oop_gen
     iter = parsed_options.find("server");
     phps_ = (iter != parsed_options.end());
 
-    iter = parsed_options.find("autoload");
-    autoload_ = (iter != parsed_options.end());
-
     iter = parsed_options.find("oop");
     oop_ = (iter != parsed_options.end());
 
-    iter = parsed_options.find("namespace");
-    namespace_php_ = (iter != parsed_options.end());
-
     iter = parsed_options.find("nsglobal");
     if(iter != parsed_options.end()) {
-      if(namespace_php_) nsglobal_ = iter->second;
-      else throw "cannot use nsglobal without namespace.";
+      nsglobal_ = iter->second;
     }
     else {
       nsglobal_ = ""; // by default global namespace is empty
@@ -114,7 +106,6 @@ class t_php_generator : public t_oop_gen
 
   void generate_php_struct(t_struct* tstruct, bool is_exception);
   void generate_php_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception=false);
-  void _generate_php_struct_definition(std::ofstream& out, t_struct* tstruct, bool is_xception=false);
   void generate_php_struct_reader(std::ofstream& out, t_struct* tstruct);
   void generate_php_struct_writer(std::ofstream& out, t_struct* tstruct);
   void generate_php_function_helpers(t_function* tfunction);
@@ -130,7 +121,6 @@ class t_php_generator : public t_oop_gen
   void generate_service_interface (t_service* tservice);
   void generate_service_rest      (t_service* tservice);
   void generate_service_client    (t_service* tservice);
-  void _generate_service_client   (std::ofstream &out, t_service* tservice);
   void generate_service_processor (t_service* tservice);
   void generate_process_function  (t_service* tservice, t_function* tfunction);
 
@@ -195,13 +185,13 @@ class t_php_generator : public t_oop_gen
   std::string php_includes();
   std::string declare_field(t_field* tfield, bool init=false, bool obj=false);
   std::string function_signature(t_function* tfunction, std::string prefix="");
-  std::string argument_list(t_struct* tstruct);
+  std::string argument_list(t_struct* tstruct, bool addStructSignature = true);
   std::string type_to_cast(t_type* ttype);
   std::string type_to_enum(t_type* ttype);
 
-  std::string php_namespace_base(const t_program* p, bool modern) {
+  std::string php_namespace_base(const t_program* p) {
     std::string ns = p->get_namespace("php");
-    const char * delimiter = modern ? "\\" : "_";
+    const char * delimiter = "\\";
     size_t position = ns.find('.');
     while (position != string::npos) {
       ns.replace(position, 1, delimiter);
@@ -212,35 +202,35 @@ class t_php_generator : public t_oop_gen
 
   //general use namespace prefixing: \my\namespace\ or my_namespace_
   string php_namespace(const t_program* p) {
-    string ns = php_namespace_base(p, namespace_php_);
-    if(namespace_php_) return (nsglobal_.size() ? NSGLOBAL_AB : NSGLOBAL_B) + (ns.size() ? (ns + "\\") : "");
-    else return (nsglobal_.size() ? NSGLOBAL + "_" : "") + (ns.size() ? (ns + "_") : "");
+    string ns = php_namespace_base(p);
+    return (nsglobal_.size() ? NSGLOBAL_AB : NSGLOBAL_B) + (ns.size() ? (ns + "\\") : "");
   }
 
   //setting the namespace of a file: my\namespace
   string php_namespace_suffix(const t_program* p) {
-    string ns = php_namespace_base(p, namespace_php_);
-    if (namespace_php_) return (nsglobal_.size() ? NSGLOBAL_B : NSGLOBAL) + ns;
-    //provides consistent behavior even though this function is never called when namespace_php_ is false
-    else return (nsglobal_.size() ? (NSGLOBAL + "_") : "") + ns;
+    string ns = php_namespace_base(p);
+
+    return (nsglobal_.size() ? NSGLOBAL_B : NSGLOBAL) + ns;
   }
 
-  //writing an autload identifier into globals: my\namespace\ or my_namespace_
-  string php_namespace_autoload(const t_program* p) {
-    std::string ns = php_namespace_base(p, namespace_php_);
-    if (namespace_php_) return (nsglobal_.size() ? NSGLOBAL_B : NSGLOBAL) + (ns.size() ? (ns + "\\") : "");
-    else return (nsglobal_.size() ? (NSGLOBAL + "_") : "") + (ns.size() ? (ns + "_") : "");
+  //add a directory to allready existing namespace
+  string php_namespace_directory(string directory, bool end = true) {
+    if(end) {
+      return ";";
+    } else {
+      return "";
+    }
   }
 
-  string php_namespace_constant(const t_program* p) {
-    std::string ns = php_namespace_base(p, false);
-    return ns.size() ? (ns + "_") : "";
+  //writing an autload identifier into globa;ls: my\namespace\ or my_namespace_
+  string php_namespace_autoload(const t_program* p) {
+    std::string ns = php_namespace_base(p);
+    return (nsglobal_.size() ? NSGLOBAL_B : NSGLOBAL) + (ns.size() ? (ns + "\\") : "");
   }
 
   //declaring a type: typename or my_namespace_typename
   string php_namespace_declaration(t_type* t) {
-    if(namespace_php_) return t->get_name();
-    return php_namespace(t->get_program()) + t->get_name();
+    return t->get_name();
   }
 
   std::string php_path(t_program* p) {
@@ -256,7 +246,69 @@ class t_php_generator : public t_oop_gen
       }
     }
 
-    return ((namespace_php_) ? ns + '/' : "" ) + p->get_name();
+    return ns + '/';
+  }
+
+  /**
+   * Transform class_method into ClassMethod
+   *
+   * @param str
+   * @return stirng
+   */
+  string classify(string str)
+  {
+    string classe = "";
+
+    vector<string> x = split(str, '_');
+
+    for (size_t i = 0; i < x.size(); ++i) {
+      classe = classe + capitalize(x[i]);
+    }
+
+    return classe;
+  }
+
+  /**
+   * Split method
+   * @param s
+   * @param delim
+   * @param elems
+   * @return
+   */
+  vector<string> &split(const string &s, char delim, vector<string> &elems) {
+    stringstream ss(s);
+    string item;
+
+    while(getline(ss, item, delim)) {
+      elems.push_back(item);
+    }
+
+    return elems;
+  }
+
+  vector<string> split(const string &s, char delim) {
+    vector<string> elems;
+
+    return split(s, delim, elems);
+  }
+
+  /**
+   * Capitalize method
+   * @param str
+   * @return
+   */
+  string capitalize(string str)
+  {
+    string::iterator it(str.begin());
+
+    if (it != str.end())
+        str[0] = toupper((unsigned char)str[0]);
+
+//    while(++it != str.end())
+//    {
+//      *it = tolower((unsigned char)*it);
+//    }
+    return str;
   }
 
  private:
@@ -265,7 +317,6 @@ class t_php_generator : public t_oop_gen
    * File streams
    */
   std::ofstream f_types_;
-  std::ofstream f_consts_;
   std::ofstream f_helpers_;
   std::ofstream f_service_;
 
@@ -286,20 +337,10 @@ class t_php_generator : public t_oop_gen
   bool phps_;
 
   /**
-   * Generate PHP code that uses autoload
-   */
-  bool autoload_;
-
-  /**
    * Whether to use OOP base class TBase
    */
   bool oop_;
-  
-  /**
-   * Generate namespaces in PHP5.3 style
-   */
-  bool namespace_php_;
- 
+
   /**
    * Global namespace for PHP 5.3
    */
@@ -321,49 +362,42 @@ bool t_php_generator::is_valid_namespace
 void t_php_generator::init_generator() {
   // Make output directory
   MKDIR(get_out_dir().c_str());
-  package_dir_ = get_out_dir()+"/"+program_name_+"/";
-  MKDIR(package_dir_.c_str());
+
+  // Create Real directory Namespaces
+  vector<string> NSx = split(php_namespace_suffix(get_program()), '\\');
+  package_dir_ = get_out_dir();
+
+  for (size_t i = 0; i < NSx.size(); ++i) {
+	package_dir_ = package_dir_ + "/" + NSx[i] + "/";
+	MKDIR(package_dir_.c_str());
+  }
+
   // Make output file
-  string f_types_name = package_dir_+program_name_+"_types.php";
+  string f_types_name = package_dir_+"Types.php";
   f_types_.open(f_types_name.c_str());
 
   // Print header
   f_types_ <<
     "<?php" << endl;
-  if(namespace_php_) f_types_ << "namespace " << php_namespace_suffix(get_program()) << ";" << endl;
+    f_types_ << "namespace " << php_namespace_suffix(get_program()) << ";" << endl << endl;
   f_types_ << autogen_comment() << php_includes();
 
-  // Include other Thrift includes
-  const vector<t_program*>& includes = program_->get_includes();
-  for (size_t i = 0; i < includes.size(); ++i) {
-    string package = includes[i]->get_name();
-    string prefix = php_path(includes[i]);
-    f_types_ <<
-      "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" << prefix << "/" << package << "_types.php';" << endl;
-  }
   f_types_ << endl;
-
-  // Print header
-  if (!program_->get_consts().empty()) {
-    string f_consts_name = package_dir_+program_name_+"_constants.php";
-    f_consts_.open(f_consts_name.c_str());
-    f_consts_ <<
-      "<?php" << endl;
-     if(namespace_php_) 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['" << php_namespace_constant(get_program()) << program_name_ << "_CONSTANTS'] = array();" << endl <<
-      endl;
-  }
 }
 
 /**
  * Prints standard php includes
  */
 string t_php_generator::php_includes() {
-  return
-    string("include_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';\n\n");
+  string TBase = "use Thrift\\Base\\TBase;\n";
+  string TType = "use Thrift\\Type\\TType;\n";
+  string TMessageType = "use Thrift\\Type\\TMessageType;\n";
+  string TException = "use Thrift\\Exception\\TException;\n";
+  string TProtocolException = "use Thrift\\Exception\\TProtocolException;\n";
+  string TProtocol = "use Thrift\\Protocol\\TProtocol;\n";
+  string TApplicationException = "use Thrift\\Exception\\TApplicationException;\n\n";
+
+  return TBase + TType + TMessageType + TException + TProtocolException + TProtocol + TApplicationException;
 }
 
 /**
@@ -371,13 +405,8 @@ string t_php_generator::php_includes() {
  */
 void t_php_generator::close_generator() {
   // Close types file
-  f_types_ << "?>" << endl;
+    f_types_ << endl;
   f_types_.close();
-
-  if (!program_->get_consts().empty()) {
-    f_consts_ << "?>" << endl;
-    f_consts_.close();
-  }
 }
 
 /**
@@ -396,26 +425,14 @@ void t_php_generator::generate_typedef(t
  * @param tenum The enumeration
  */
 void t_php_generator::generate_enum(t_enum* tenum) {
-  f_types_ <<
-    "$GLOBALS['" << php_namespace(tenum->get_program()) << "E_" << tenum->get_name() << "'] = array(" << endl;
-
   vector<t_enum_value*> constants = tenum->get_constants();
   vector<t_enum_value*>::iterator c_iter;
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    int value = (*c_iter)->get_value();
-    f_types_ <<
-      "  '" << (*c_iter)->get_name() << "' => " << value << "," << endl;
-  }
-
-  f_types_ <<
-    ");" << endl << endl;
-
 
   // We're also doing it this way to see how it performs. It's more legible
   // 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) {
@@ -446,9 +463,9 @@ void t_php_generator::generate_const(t_c
   string name = tconst->get_name();
   t_const_value* value = tconst->get_value();
 
-  f_consts_ << "$GLOBALS['" << php_namespace_constant(get_program()) << program_name_ << "_CONSTANTS']['" << name << "'] = ";
-  f_consts_ << render_const_value(type, value);
-  f_consts_ << ";" << endl << endl;
+  f_types_ << "$GLOBALS['" << program_name_ << "_CONSTANTS']['" << name << "'] = ";
+  f_types_ << render_const_value(type, value);
+  f_types_ << ";" << endl << endl;
 }
 
 /**
@@ -487,7 +504,7 @@ string t_php_generator::render_const_val
   } else if (type->is_enum()) {
     indent(out) << value->get_integer();
   } else if (type->is_struct() || type->is_xception()) {
-    out << "new " << NS_ROOT << php_namespace(type->get_program()) << type->get_name() << "(array(" << endl;
+    out << "new " << 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;
@@ -580,7 +597,7 @@ void t_php_generator::generate_php_struc
 void t_php_generator::generate_php_type_spec(ofstream& out,
                                              t_type* t) {
   t = get_true_type(t);
-  indent(out) << "'type' => " << NS_ROOT << type_to_enum(t) << "," << endl;
+  indent(out) << "'type' => " << type_to_enum(t) << "," << endl;
 
   if (t->is_base_type() || t->is_enum()) {
     // Noop, type is all we need
@@ -589,8 +606,8 @@ void t_php_generator::generate_php_type_
   } 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' => " << NS_ROOT << type_to_enum(ktype) << "," << endl;
-    indent(out) << "'vtype' => " << NS_ROOT << type_to_enum(vtype) << "," << endl;
+    indent(out) << "'ktype' => " << type_to_enum(ktype) << "," << endl;
+    indent(out) << "'vtype' => " << type_to_enum(vtype) << "," << endl;
     indent(out) << "'key' => array(" << endl;
     indent_up();
     generate_php_type_spec(out, ktype);
@@ -608,7 +625,7 @@ void t_php_generator::generate_php_type_
     } else {
       etype = get_true_type(((t_set*)t)->get_elem_type());
     }
-    indent(out) << "'etype' => " << NS_ROOT << type_to_enum(etype) <<"," << endl;
+    indent(out) << "'etype' => " << type_to_enum(etype) <<"," << endl;
     indent(out) << "'elem' => array(" << endl;
     indent_up();
     generate_php_type_spec(out, etype);
@@ -651,33 +668,6 @@ void t_php_generator::generate_php_struc
   indent(out) << "}" << endl;
 }
 
-
-void t_php_generator::generate_php_struct_definition(ofstream& out,
-                                                     t_struct* tstruct,
-                                                     bool is_exception) {
-  if (autoload_) {
-    // Make output file
-    ofstream autoload_out;
-    string f_struct = program_name_+"."+(tstruct->get_name())+".php";
-    string f_struct_name = package_dir_+f_struct;
-    autoload_out.open(f_struct_name.c_str());
-    autoload_out << "<?php" << endl
-      << "/**" << endl << " *  @generated" << endl << " */" << endl;
-    if(namespace_php_) autoload_out << "namespace " << php_namespace_suffix(tstruct->get_program()) << ";" << endl;
-    _generate_php_struct_definition(autoload_out, tstruct, is_exception);
-    autoload_out << endl << "?>" << endl;
-    autoload_out.close();
-
-    f_types_ <<
-      "$GLOBALS['THRIFT_AUTOLOAD']['" <<
-      lowercase(php_namespace_autoload(tstruct->get_program()) + tstruct->get_name()) <<
-      "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
-
-  } else {
-    _generate_php_struct_definition(out, tstruct, is_exception);
-  }
-}
-
 /**
  * Generates a struct definition for a thrift data type. This is nothing in PHP
  * where the objects are all just associative arrays (unless of course we
@@ -685,7 +675,7 @@ void t_php_generator::generate_php_struc
  *
  * @param tstruct The struct definition
  */
-void t_php_generator::_generate_php_struct_definition(ofstream& out,
+void t_php_generator::generate_php_struct_definition(ofstream& out,
                                                      t_struct* tstruct,
                                                      bool is_exception) {
   const vector<t_field*>& members = tstruct->get_members();
@@ -694,9 +684,9 @@ void t_php_generator::_generate_php_stru
   out <<
     "class " << php_namespace_declaration(tstruct);
   if (is_exception) {
-    out << " extends " << NS_ROOT << "TException";
+    out << " extends " << "TException";
   } else if (oop_) {
-    out << " extends " << NS_ROOT << "TBase";
+    out << " extends " << "TBase";
   }
   out <<
     " {" << endl;
@@ -808,7 +798,7 @@ void t_php_generator::generate_php_struc
       t_field ffid(g_type_i16, "fid");
       generate_deserialize_field(out, &fftype);
       out <<
-        indent() << "if ($ftype == " << NS_ROOT << "TType::STOP) {" << endl <<
+        indent() << "if ($ftype == " << "TType::STOP) {" << endl <<
         indent() << "  break;" << endl <<
         indent() << "}" << endl;
       generate_deserialize_field(out, &ffid);
@@ -817,7 +807,7 @@ void t_php_generator::generate_php_struc
         "$xfer += $input->readFieldBegin($fname, $ftype, $fid);" << endl;
       // Check for field STOP marker and break
       indent(out) <<
-        "if ($ftype == " << NS_ROOT << "TType::STOP) {" << endl;
+        "if ($ftype == " << "TType::STOP) {" << endl;
       indent_up();
       indent(out) <<
         "break;" << endl;
@@ -837,14 +827,14 @@ void t_php_generator::generate_php_struc
         indent(out) <<
           "case " << (*f_iter)->get_key() << ":" << endl;
         indent_up();
-        indent(out) << "if ($ftype == " << NS_ROOT << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
+        indent(out) << "if ($ftype == " << 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 += " << NS_ROOT << "TProtocol::skipBinary($input, $ftype);" << endl;
+          indent(out) <<  "  $xfer += " << "TProtocol::skipBinary($input, $ftype);" << endl;
         } else {
           indent(out) <<  "  $xfer += $input->skip($ftype);" << endl;
         }
@@ -857,7 +847,7 @@ void t_php_generator::generate_php_struc
       // In the default case we skip the field
       indent(out) <<  "default:" << endl;
       if (binary_inline_) {
-        indent(out) <<  "  $xfer += " << NS_ROOT << "TProtocol::skipBinary($input, $ftype);" << endl;
+        indent(out) <<  "  $xfer += " << "TProtocol::skipBinary($input, $ftype);" << endl;
       } else {
         indent(out) <<  "  $xfer += $input->skip($ftype);" << endl;
       }
@@ -936,7 +926,7 @@ void t_php_generator::generate_php_struc
         indent() << "if (!is_" << expect << "($this->" << (*f_iter)->get_name() << ")) {" << endl;
       indent_up();
       out <<
-        indent() << "throw new " << NS_ROOT << "TProtocolException('Bad type in structure.', " << NS_ROOT << "TProtocolException::INVALID_DATA);" << endl;
+        indent() << "throw new " << "TProtocolException('Bad type in structure.', " << "TProtocolException::INVALID_DATA);" << endl;
       scope_down(out);
     }
 
@@ -949,7 +939,7 @@ void t_php_generator::generate_php_struc
       indent(out) <<
         "$xfer += $output->writeFieldBegin(" <<
         "'" << (*f_iter)->get_name() << "', " <<
-        NS_ROOT << type_to_enum((*f_iter)->get_type()) << ", " <<
+        type_to_enum((*f_iter)->get_type()) << ", " <<
         (*f_iter)->get_key() << ");" << endl;
     }
 
@@ -969,7 +959,7 @@ void t_php_generator::generate_php_struc
 
   if (binary_inline_) {
     out <<
-      indent() << "$output .= pack('c', " << NS_ROOT << "TType::STOP);" << endl;
+      indent() << "$output .= pack('c', " << "TType::STOP);" << endl;
   } else {
     out <<
       indent() << "$xfer += $output->writeFieldStop();" << endl <<
@@ -995,19 +985,11 @@ void t_php_generator::generate_service(t
   f_service_.open(f_service_name.c_str());
 
   f_service_ << "<?php" << endl;
-  if(namespace_php_) f_service_ << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl;
+  f_service_ << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl;
   f_service_ << autogen_comment() <<
     php_includes();
 
   f_service_ <<
-    "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" << php_path(program_) << "/" << program_name_ << "_types.php';" << endl;
-
-  if (tservice->get_extends() != NULL) {
-    f_service_ <<
-      "include_once $GLOBALS['THRIFT_ROOT'].'/packages/" << php_path(tservice->get_extends()->get_program()) << "/" << tservice->get_extends()->get_name() << ".php';" << endl;
-  }
-
-  f_service_ <<
     endl;
 
   // Generate the three main parts of the service (well, two for now in PHP)
@@ -1022,7 +1004,7 @@ void t_php_generator::generate_service(t
   }
 
   // Close service file
-  f_service_ << "?>" << endl;
+  f_service_ << endl;
   f_service_.close();
 }
 
@@ -1095,13 +1077,13 @@ void t_php_generator::generate_service_p
     indent() << "if (!method_exists($this, $methodname)) {" << endl;
   if (binary_inline_) {
     f_service_ <<
-      indent() << "  throw new Exception('Function '.$fname.' not implemented.');" << endl;
+      indent() << "  throw new \\Exception('Function '.$fname.' not implemented.');" << endl;
   } else {
     f_service_ <<
-      indent() << "  $input->skip(" << NS_ROOT << "TType::STRUCT);" << endl <<
+      indent() << "  $input->skip(" << "TType::STRUCT);" << endl <<
       indent() << "  $input->readMessageEnd();" << 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 = new " << "TApplicationException('Function '.$fname.' not implemented.', " << "TApplicationException::UNKNOWN_METHOD);" << endl <<
+      indent() << "  $output->writeMessageBegin($fname, " << "TMessageType::EXCEPTION, $rseqid);" << endl <<
       indent() << "  $x->write($output);" << endl <<
       indent() << "  $output->writeMessageEnd();" << endl <<
       indent() << "  $output->getTransport()->flush();" << endl <<
@@ -1192,7 +1174,7 @@ void t_php_generator::generate_process_f
     indent_down();
     for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
       f_service_ <<
-        indent() << "} catch (" << php_namespace((*x_iter)->get_type()->get_program()) << (*x_iter)->get_type()->get_name() << " $" << (*x_iter)->get_name() << ") {" << endl;
+        indent() << "} catch (" << php_namespace(get_true_type((*x_iter)->get_type())->get_program()) << (*x_iter)->get_type()->get_name() << " $" << (*x_iter)->get_name() << ") {" << endl;
       if (!tfunction->is_oneway()) {
         indent_up();
         f_service_ <<
@@ -1215,14 +1197,14 @@ void t_php_generator::generate_process_f
   }
 
   f_service_ <<
-    indent() << "$bin_accel = ($output instanceof " << NS_ROOT << "TProtocol::$TBINARYPROTOCOLACCELERATED) && function_exists('thrift_protocol_write_binary');" << endl;
+    indent() << "$bin_accel = ($output instanceof " << "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() << "', " << NS_ROOT << "TMessageType::REPLY, $result, $seqid, $output->isStrictWrite());" << endl;
+    indent() << "thrift_protocol_write_binary($output, '" << tfunction->get_name() << "', " << "TMessageType::REPLY, $result, $seqid, $output->isStrictWrite());" << endl;
 
   scope_down(f_service_);
   f_service_ <<
@@ -1232,7 +1214,7 @@ void t_php_generator::generate_process_f
   // Serialize the request header
   if (binary_inline_) {
     f_service_ <<
-      indent() << "$buff = pack('N', (0x80010000 | " << NS_ROOT << "TMessageType::REPLY)); " << endl <<
+      indent() << "$buff = pack('N', (0x80010000 | " << "TMessageType::REPLY)); " << endl <<
       indent() << "$buff .= pack('N', strlen('" << tfunction->get_name() << "'));" << endl <<
       indent() << "$buff .= '" << tfunction->get_name() << "';" << endl <<
       indent() << "$buff .= pack('N', $seqid);" << endl <<
@@ -1241,7 +1223,7 @@ void t_php_generator::generate_process_f
       indent() << "$output->flush();" << endl;
   } else {
     f_service_ <<
-      indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', " << NS_ROOT << "TMessageType::REPLY, $seqid);" << endl <<
+      indent() << "$output->writeMessageBegin('" << tfunction->get_name() << "', " << "TMessageType::REPLY, $seqid);" << endl <<
       indent() << "$result->write($output);" << endl <<
       indent() << "$output->writeMessageEnd();" << endl <<
       indent() << "$output->getTransport()->flush();" << endl;
@@ -1390,7 +1372,7 @@ void t_php_generator::generate_service_r
       }
     }
     f_service_ <<
-      indent() << "return $this->impl_->" << (*f_iter)->get_name() << "(" << argument_list((*f_iter)->get_arglist()) << ");" << endl;
+      indent() << "return $this->impl_->" << (*f_iter)->get_name() << "(" << argument_list((*f_iter)->get_arglist(), false) << ");" << endl;
     indent_down();
     indent(f_service_) <<
       "}" << endl <<
@@ -1401,36 +1383,12 @@ void t_php_generator::generate_service_r
     "}" << endl << endl;
 }
 
-void t_php_generator::generate_service_client(t_service* tservice) {
-  if (autoload_) {
-    // Make output file
-    ofstream autoload_out;
-    string f_struct = program_name_+"."+(tservice->get_name())+".client.php";
-    string f_struct_name = package_dir_+f_struct;
-    autoload_out.open(f_struct_name.c_str());
-    autoload_out << "<?php" << endl
-      << "/**" << endl << " *  @generated" << endl << " */" << endl;
-    if(namespace_php_) autoload_out << endl << "namespace " << php_namespace_suffix(tservice->get_program()) << ";" << endl << endl;
-    _generate_service_client(autoload_out, tservice);
-    autoload_out << endl << "?>" << endl;
-    autoload_out.close();
-
-    f_service_ <<
-      "$GLOBALS['THRIFT_AUTOLOAD']['" <<
-      lowercase(php_namespace_autoload(get_program()) + service_name_ + "Client") <<
-      "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
-
-  } else {
-    _generate_service_client(f_service_, tservice);
-  }
-}
-
 /**
  * Generates a service client definition.
  *
  * @param tservice The service to generate a server for.
  */
-void t_php_generator::_generate_service_client(ofstream& out, t_service* tservice) {
+void t_php_generator::generate_service_client(t_service* tservice) {
   string extends = "";
   string extends_client = "";
   if (tservice->get_extends() != NULL) {
@@ -1438,33 +1396,33 @@ void t_php_generator::_generate_service_
     extends_client = " extends " + php_namespace(tservice->get_extends()->get_program()) + extends + "Client";
   }
 
-  out <<
+  f_service_ <<
     "class " << php_namespace_declaration(tservice) << "Client" << extends_client << " implements " <<  php_namespace(tservice->get_program()) << service_name_ << "If {" << endl;
   indent_up();
 
   // Private members
   if (extends.empty()) {
-    out <<
+    f_service_ <<
       indent() << "protected $input_ = null;" << endl <<
       indent() << "protected $output_ = null;" << endl <<
       endl;
-    out <<
+    f_service_ <<
       indent() << "protected $seqid_ = 0;" << endl <<
       endl;
   }
 
   // Constructor function
-  out <<
+  f_service_ <<
     indent() << "public function __construct($input, $output=null) {" << endl;
   if (!extends.empty()) {
-    out <<
+    f_service_ <<
       indent() << "  parent::__construct($input, $output);" << endl;
   } else {
-    out <<
+    f_service_ <<
       indent() << "  $this->input_ = $input;" << endl <<
       indent() << "  $this->output_ = $output ? $output : $input;" << endl;
   }
-  out <<
+  f_service_ <<
     indent() << "}" << endl << endl;
 
   // Generate client method implementations
@@ -1477,10 +1435,10 @@ void t_php_generator::_generate_service_
     string funname = (*f_iter)->get_name();
 
     // Open function
-    indent(out) <<
+    indent(f_service_) <<
       "public function " << function_signature(*f_iter) << endl;
-    scope_up(out);
-      indent(out) <<
+    scope_up(f_service_);
+      indent(f_service_) <<
         "$this->send_" << funname << "(";
 
       bool first = true;
@@ -1488,80 +1446,80 @@ void t_php_generator::_generate_service_
         if (first) {
           first = false;
         } else {
-          out << ", ";
+          f_service_ << ", ";
         }
-        out << "$" << (*fld_iter)->get_name();
+        f_service_ << "$" << (*fld_iter)->get_name();
       }
-      out << ");" << endl;
+      f_service_ << ");" << endl;
 
       if (!(*f_iter)->is_oneway()) {
-        out << indent();
+        f_service_ << indent();
         if (!(*f_iter)->get_returntype()->is_void()) {
-          out << "return ";
+          f_service_ << "return ";
         }
-        out <<
+        f_service_ <<
           "$this->recv_" << funname << "();" << endl;
       }
-    scope_down(out);
-    out << endl;
+    scope_down(f_service_);
+    f_service_ << endl;
 
-    indent(out) <<
+    indent(f_service_) <<
       "public function send_" << function_signature(*f_iter) << endl;
-    scope_up(out);
+    scope_up(f_service_);
 
       std::string argsname = php_namespace(tservice->get_program()) + service_name_ + "_" + (*f_iter)->get_name() + "_args";
 
-      out <<
+      f_service_ <<
         indent() << "$args = new " << argsname << "();" << endl;
 
       for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
-        out <<
+        f_service_ <<
           indent() << "$args->" << (*fld_iter)->get_name() << " = $" << (*fld_iter)->get_name() << ";" << endl;
       }
 
-      out <<
-        indent() << "$bin_accel = ($this->output_ instanceof " << NS_ROOT << "TProtocol::$TBINARYPROTOCOLACCELERATED) && function_exists('thrift_protocol_write_binary');" << endl;
+      f_service_ <<
+        indent() << "$bin_accel = ($this->output_ instanceof " << "TProtocol::$TBINARYPROTOCOLACCELERATED) && function_exists('thrift_protocol_write_binary');" << endl;
 
-      out <<
+      f_service_ <<
         indent() << "if ($bin_accel)" << endl;
-      scope_up(out);
+      scope_up(f_service_);
 
-      out <<
-        indent() << "thrift_protocol_write_binary($this->output_, '" << (*f_iter)->get_name() << "', " << NS_ROOT << "TMessageType::CALL, $args, $this->seqid_, $this->output_->isStrictWrite());" << endl;
+      f_service_ <<
+        indent() << "thrift_protocol_write_binary($this->output_, '" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $args, $this->seqid_, $this->output_->isStrictWrite());" << endl;
 
-      scope_down(out);
-      out <<
+      scope_down(f_service_);
+      f_service_ <<
         indent() << "else" << endl;
-      scope_up(out);
+      scope_up(f_service_);
 
       // Serialize the request header
       if (binary_inline_) {
-        out <<
-          indent() << "$buff = pack('N', (0x80010000 | " << NS_ROOT << "TMessageType::CALL));" << endl <<
+        f_service_ <<
+          indent() << "$buff = pack('N', (0x80010000 | " << "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() << "', " << NS_ROOT << "TMessageType::CALL, $this->seqid_);" << endl;
+        f_service_ <<
+          indent() << "$this->output_->writeMessageBegin('" << (*f_iter)->get_name() << "', " << "TMessageType::CALL, $this->seqid_);" << endl;
       }
 
       // Write to the stream
       if (binary_inline_) {
-        out <<
+        f_service_ <<
           indent() << "$args->write($buff);" << endl <<
           indent() << "$this->output_->write($buff);" << endl <<
           indent() << "$this->output_->flush();" << endl;
       } else {
-        out <<
+        f_service_ <<
           indent() << "$args->write($this->output_);" << endl <<
           indent() << "$this->output_->writeMessageEnd();" << endl <<
           indent() << "$this->output_->getTransport()->flush();" << endl;
       }
 
-    scope_down(out);
+    scope_down(f_service_);
 
-    scope_down(out);
+    scope_down(f_service_);
 
 
     if (!(*f_iter)->is_oneway()) {
@@ -1572,22 +1530,22 @@ void t_php_generator::_generate_service_
                                string("recv_") + (*f_iter)->get_name(),
                                &noargs);
       // Open function
-      out <<
+      f_service_ <<
         endl <<
         indent() << "public function " << function_signature(&recv_function) << endl;
-      scope_up(out);
+      scope_up(f_service_);
 
-      out <<
-        indent() << "$bin_accel = ($this->input_ instanceof " << NS_ROOT << "TProtocol::$TBINARYPROTOCOLACCELERATED)"
+      f_service_ <<
+        indent() << "$bin_accel = ($this->input_ instanceof " << "TProtocol::$TBINARYPROTOCOLACCELERATED)"
                  << " && function_exists('thrift_protocol_read_binary');" << endl;
 
-      out <<
+      f_service_ <<
         indent() << "if ($bin_accel) $result = thrift_protocol_read_binary($this->input_, '" << resultname << "', $this->input_->isStrictRead());" << endl;
-      out <<
+      f_service_ <<
         indent() << "else" << endl;
-      scope_up(out);
+      scope_up(f_service_);
 
-      out <<
+      f_service_ <<
         indent() << "$rseqid = 0;" << endl <<
         indent() << "$fname = null;" << endl <<
         indent() << "$mtype = 0;" << endl <<
@@ -1596,39 +1554,39 @@ void t_php_generator::_generate_service_
       if (binary_inline_) {
         t_field ffname(g_type_string, "fname");
         t_field fseqid(g_type_i32, "rseqid");
-        out <<
+        f_service_ <<
           indent() << "$ver = unpack('N', $this->input_->readAll(4));" << endl <<
           indent() << "$ver = $ver[1];" << endl <<
           indent() << "$mtype = $ver & 0xff;" << endl <<
           indent() << "$ver = $ver & 0xffff0000;" << 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);
+          indent() << "if ($ver != 0x80010000) throw new " << "TProtocolException('Bad version identifier: '.$ver, " << "TProtocolException::BAD_VERSION);" << endl;
+        generate_deserialize_field(f_service_, &ffname, "", true);
+        generate_deserialize_field(f_service_, &fseqid, "", true);
       } else {
-        out <<
+        f_service_ <<
           indent() << "$this->input_->readMessageBegin($fname, $mtype, $rseqid);" << endl <<
-          indent() << "if ($mtype == " << NS_ROOT << "TMessageType::EXCEPTION) {" << endl <<
-          indent() << "  $x = new " << NS_ROOT << "TApplicationException();" << endl <<
+          indent() << "if ($mtype == " << "TMessageType::EXCEPTION) {" << endl <<
+          indent() << "  $x = new " << "TApplicationException();" << endl <<
           indent() << "  $x->read($this->input_);" << endl <<
           indent() << "  $this->input_->readMessageEnd();" << endl <<
           indent() << "  throw $x;" << endl <<
           indent() << "}" << endl;
       }
 
-      out <<
+      f_service_ <<
         indent() << "$result = new " << resultname << "();" << endl <<
         indent() << "$result->read($this->input_);" << endl;
 
       if (!binary_inline_) {
-        out <<
+        f_service_ <<
           indent() << "$this->input_->readMessageEnd();" << endl;
       }
 
-      scope_down(out);
+      scope_down(f_service_);
 
       // Careful, only return result if not a void function
       if (!(*f_iter)->get_returntype()->is_void()) {
-        out <<
+        f_service_ <<
           indent() << "if ($result->success !== null) {" << endl <<
           indent() << "  return $result->success;" << endl <<
           indent() << "}" << endl;
@@ -1638,7 +1596,7 @@ void t_php_generator::_generate_service_
       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) {
-        out <<
+        f_service_ <<
           indent() << "if ($result->" << (*x_iter)->get_name() << " !== null) {" << endl <<
           indent() << "  throw $result->" << (*x_iter)->get_name() << ";" << endl <<
           indent() << "}" << endl;
@@ -1646,22 +1604,22 @@ void t_php_generator::_generate_service_
 
       // Careful, only return _result if not a void function
       if ((*f_iter)->get_returntype()->is_void()) {
-        indent(out) <<
+        indent(f_service_) <<
           "return;" << endl;
       } else {
-        out <<
-          indent() << "throw new " << NS_ROOT << "Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
+        f_service_ <<
+          indent() << "throw new \\Exception(\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
       }
 
     // Close function
-    scope_down(out);
-    out << endl;
+    scope_down(f_service_);
+    f_service_ << endl;
 
     }
   }
 
   indent_down();
-  out <<
+  f_service_ <<
     "}" << endl << endl;
 }
 
@@ -2122,8 +2080,8 @@ void t_php_generator::generate_serialize
     } else {
       indent(out) <<
         "$output->writeMapBegin(" <<
-        NS_ROOT << type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
-        NS_ROOT << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
+        type_to_enum(((t_map*)ttype)->get_key_type()) << ", " <<
+        type_to_enum(((t_map*)ttype)->get_val_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   } else if (ttype->is_set()) {
@@ -2135,7 +2093,7 @@ void t_php_generator::generate_serialize
     } else {
       indent(out) <<
         "$output->writeSetBegin(" <<
-        NS_ROOT << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
+        type_to_enum(((t_set*)ttype)->get_elem_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   } else if (ttype->is_list()) {
@@ -2147,7 +2105,7 @@ void t_php_generator::generate_serialize
     } else {
       indent(out) <<
         "$output->writeListBegin(" <<
-        NS_ROOT << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
+        type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " <<
         "count($" << prefix << "));" << endl;
     }
   }
@@ -2300,7 +2258,7 @@ string t_php_generator::function_signatu
 /**
  * Renders a field list
  */
-string t_php_generator::argument_list(t_struct* tstruct) {
+string t_php_generator::argument_list(t_struct* tstruct, bool addStructSignature) {
   string result = "";
 
   const vector<t_field*>& fields = tstruct->get_members();
@@ -2312,6 +2270,17 @@ string t_php_generator::argument_list(t_
     } else {
       result += ", ";
     }
+
+    t_type* type = (*f_iter)->get_type();
+
+    //Set type name
+    if(addStructSignature and type->is_struct())
+    {
+      string className = php_namespace(type->get_program()) + php_namespace_directory("Definition", false) + classify(type->get_name());
+
+      result += className + " ";
+    }
+
     result += "$" + (*f_iter)->get_name();
   }
   return result;
@@ -2388,9 +2357,7 @@ string t_php_generator ::type_to_enum(t_
 THRIFT_REGISTER_GENERATOR(php, "PHP",
 "    inlined:         Generate PHP inlined files\n"
 "    server:          Generate PHP server stubs\n"
-"    autoload:        Generate PHP with autoload\n"
 "    oop:             Generate PHP with object oriented subclasses\n"
 "    rest:            Generate PHP REST processors\n"
-"    namespace:       Generate PHP namespaces as defined in PHP >= 5.3\n"
 )
 

Modified: thrift/trunk/lib/php/Makefile.am
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/Makefile.am?rev=1381323&r1=1381322&r2=1381323&view=diff
==============================================================================
--- thrift/trunk/lib/php/Makefile.am (original)
+++ thrift/trunk/lib/php/Makefile.am Wed Sep  5 19:47:14 2012
@@ -34,29 +34,62 @@ phpmoduledir = `php-config --extension-d
 phpmodule_SCRIPTS = src/ext/thrift_protocol/modules/thrift_protocol.so
 endif
 
-phpdir = $(PHP_PREFIX)
-php_DATA =  \
-  src/autoload.php \
-  src/Thrift.php
+phpdir = $(PHP_PREFIX)/Thrift
 
-phpprotocoldir = $(phpdir)/protocol
+phpbasedir = $(phpdir)/Base
+phpbase_DATA = \
+  lib/Thrift/Base/TBase.php
+
+phpexceptiondir = $(phpdir)/Exception
+phpexception_DATA = \
+  lib/Thrift/Exception/TApplicationException.php \
+  lib/Thrift/Exception/TException.php \
+  lib/Thrift/Exception/TProtocolException.php \
+  lib/Thrift/Exception/TTransportException.php
+
+phpfactorydir = $(phpdir)/Factory
+phpfactory_DATA = \
+  lib/Thrift/Factory/TBinaryProtocolFactory.php \
+  lib/Thrift/Factory/TCompactProtocolFactory.php \
+  lib/Thrift/Factory/TJSONProtocolFactory.php \
+  lib/Thrift/Factory/TProtocolFactory.php \
+  lib/Thrift/Factory/TTransportFactory.php
+
+phpprotocoldir = $(phpdir)/Protocol
 phpprotocol_DATA = \
-  src/protocol/TBinaryProtocol.php \
-  src/protocol/TBinarySerializer.php \
-  src/protocol/TProtocol.php \
-  src/protocol/TJSONProtocol.php
+  lib/Thrift/Protocol/TBinaryProtocolAccelerated.php \
+  lib/Thrift/Protocol/TBinaryProtocol.php \
+  lib/Thrift/Protocol/TCompactProtocol.php \
+  lib/Thrift/Protocol/TJSONProtocol.php \
+  lib/Thrift/Protocol/TProtocol.php
 
-phptransportdir = $(phpdir)/transport
+phpprotocoljsondir = $(phpprotocoldir)/JSON
+phpprotocoljson_DATA = \
+  lib/Thrift/Protocol/JSON/BaseContext.php \
+  lib/Thrift/Protocol/JSON/ListContext.php \
+  lib/Thrift/Protocol/JSON/LookaheadReader.php \
+  lib/Thrift/Protocol/JSON/PairContext.php
+
+phpserializerdir = $(phpdir)/Serializer
+phpserializer_DATA = \
+  lib/Thrift/Serializer/TBinarySerializer.php
+
+phptransportdir = $(phpdir)/Transport
 phptransport_DATA = \
-  src/transport/TBufferedTransport.php \
-  src/transport/TFramedTransport.php \
-  src/transport/THttpClient.php \
-  src/transport/TMemoryBuffer.php \
-  src/transport/TNullTransport.php \
-  src/transport/TPhpStream.php \
-  src/transport/TSocket.php \
-  src/transport/TSocketPool.php \
-  src/transport/TTransport.php
+  lib/Thrift/Transport/TBufferedTransport.php \
+  lib/Thrift/Transport/TFramedTransport.php \
+  lib/Thrift/Transport/THttpClient.php \
+  lib/Thrift/Transport/TMemoryBuffer.php \
+  lib/Thrift/Transport/TNullTransport.php \
+  lib/Thrift/Transport/TPhpStream.php \
+  lib/Thrift/Transport/TSocket.php \
+  lib/Thrift/Transport/TSocketPool.php \
+  lib/Thrift/Transport/TTransport.php
+
+phptypedir = $(phpdir)/Type
+phptype_DATA = \
+  lib/Thrift/Type/TMessageType.php \
+  lib/Thrift/Type/TType.php
 
 EXTRA_DIST = src thrift_protocol.ini README.apache
 

Modified: thrift/trunk/lib/php/README
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/README?rev=1381323&r1=1381322&r2=1381323&view=diff
==============================================================================
--- thrift/trunk/lib/php/README (original)
+++ thrift/trunk/lib/php/README Wed Sep  5 19:47:14 2012
@@ -29,24 +29,14 @@ features (i.e. APC cacheing using asbolu
 
 To use Thrift in your PHP codebase, take the following steps:
 
-#1) Copy all of thrift/lib/php/src into your PHP codebase
-#2) Set $GLOBALS['THRIFT_ROOT'] to the path you installed Thrift
-#3) include_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
-
-Note that #3 must be done before including any other Thrift files.
-If you do not do #2, Thrift.php will set this global for you, but it will be
-done using dirname(__FILE__), which is less efficient than providing the static
-string yourself.
-
-When you generate a Thrift package using the compiler, it makes an assumption
-about where your generated code will live. If your file is "MyPackage.thrift",
-the generated files must be installed into:
-
-$GLOBALS['THRIFT_ROOT'].'/packages/MyPackage/';
-
-This allows the code generator to compile your code without any extra flags
-for the target directory names while still allowing your include paths to
-be absolute (if you have an absolute THRIFT_ROOT).
+#1) Copy all of thrift/lib/php/lib into your PHP codebase
+#2) Configure Symfony Autoloader (or whatever you usually use)
+
+After thaht, you have to manually include the Thrift package
+created by the compiler:
+
+require_once 'packages/Service/Service.php';
+require_once 'packages/Service/Types.php';
 
 Dependencies
 ============

Modified: thrift/trunk/lib/php/README.apache
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/README.apache?rev=1381323&r1=1381322&r2=1381323&view=diff
==============================================================================
--- thrift/trunk/lib/php/README.apache (original)
+++ thrift/trunk/lib/php/README.apache Wed Sep  5 19:47:14 2012
@@ -32,17 +32,29 @@ Sample Code
 
 <?php
 
+namespace MyNamespace;
+
 /**
- * Example of how to build a Thrift server in Apache/PHP
- *
+ * Include path
+ */
+$THRIFT_ROOT = '/your/thrift/root/lib';
+
+/**
+ * Init Autloader
  */
+require_once $THRIFT_ROOT . '/Thrift/ClassLoader/ThriftClassLoader.php';
 
-$GLOBALS['THRIFT_ROOT'] = '/your/thrift/root';
+$loader = new ThriftClassLoader();
+$loader->registerNamespace('Thrift', $THRIFT_ROOT);
+$loader->registerDefinition('Thrift', $THRIFT_ROOT . '/packages');
+$loader->register();
 
-include_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/packages/Service/Service.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/transport/TPhpStream.php';
-include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php';
+use Thrift\Transport\TPhpStream;
+use Thrift\Protocol\TBinaryProtocol;
+
+/**
+ * Example of how to build a Thrift server in Apache/PHP
+ */
 
 class ServiceHandler implements ServiceIf {
   // Implement your interface and methods here

Added: thrift/trunk/lib/php/lib/Thrift/Base/TBase.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/Base/TBase.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/Base/TBase.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/Base/TBase.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,367 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Base;
+
+use Thrift\Type\TType;
+
+/**
+ * Base class from which other Thrift structs extend. This is so that we can
+ * cut back on the size of the generated code which is turning out to have a
+ * nontrivial cost just to load thanks to the wondrously abysmal implementation
+ * of PHP. Note that code is intentionally duplicated in here to avoid making
+ * function calls for every field or member of a container..
+ */
+abstract class TBase {
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  abstract function read($input);
+
+  abstract function write($output);
+
+  public function __construct($spec=null, $vals=null) {
+    if (is_array($spec) && is_array($vals)) {
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    }
+  }
+
+  public function __wakeup()
+  {
+    $this->__construct(get_object_vars($this));
+  }
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}

Added: thrift/trunk/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/ClassLoader/ThriftClassLoader.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,223 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * ClassLoader to load Thrift library and definitions
+ * Inspired from UniversalClassLoader from Symfony 2 
+ *
+ * @package thrift.classloader
+ */
+
+namespace Thrift\ClassLoader;
+
+class ThriftClassLoader
+{
+    /**
+     * Namespaces path
+     * @var array
+     */
+    protected $namespaces = array();
+
+    /**
+     * Thrift definition paths
+     * @var type
+     */
+    protected $definitions = array();
+
+    /**
+     * Do we use APC cache ?
+     * @var boolean
+     */
+    protected $apc = false;
+
+    /**
+     * APC Cache prefix
+     * @var string
+     */
+    protected $apc_prefix;
+
+    /**
+     * Set autoloader to use APC cache
+     * @param boolean $apc
+     * @param string $apc_prefix
+     */
+    public function __construct($apc = false, $apc_prefix = null)
+    {
+        $this->apc = $apc;
+        $this->apc_prefix = $apc_prefix;
+    }
+
+    /**
+     * Registers a namespace.
+     *
+     * @param string       $namespace The namespace
+     * @param array|string $paths     The location(s) of the namespace
+     */
+    public function registerNamespace($namespace, $paths)
+    {
+        $this->namespaces[$namespace] = (array) $paths;
+    }
+
+    /**
+     * Registers a Thrift definition namespace.
+     *
+     * @param string       $namespace The definition namespace
+     * @param array|string $paths     The location(s) of the definition namespace
+     */
+    public function registerDefinition($namespace, $paths)
+    {
+        $this->definitions[$namespace] = (array) $paths;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param Boolean $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+    }
+
+    /**
+     * Loads the given class, definition or interface.
+     *
+     * @param string $class The name of the class
+     */
+    public function loadClass($class)
+    {
+        if (
+            (true === $this->apc && ($file = $this->findFileInApc($class))) or
+            ($file = $this->findFile($class))
+        )
+        {
+            require_once $file;
+        }
+    }
+
+    /**
+     * Loads the given class or interface in APC.
+     * @param string $class The name of the class
+     * @return string
+     */
+    protected function findFileInApc($class)
+    {
+        if (false === $file = apc_fetch($this->apc_prefix.$class)) {
+            apc_store($this->apc_prefix.$class, $file = $this->findFile($class));
+        }
+
+        return $file;
+    }
+
+    /**
+     * Find class in namespaces or definitions directories
+     * @param string $class
+     * @return string
+     */
+    public function findFile($class)
+    {
+        // Remove first backslash
+        if ('\\' == $class[0])
+        {
+            $class = substr($class, 1);
+        }
+
+        if (false !== $pos = strrpos($class, '\\'))
+        {
+            // Namespaced class name
+            $namespace = substr($class, 0, $pos);
+
+            // Iterate in normal namespaces
+            foreach ($this->namespaces as $ns => $dirs)
+            {
+                //Don't interfere with other autoloaders
+                if (0 !== strpos($namespace, $ns))
+                {
+                    continue;
+                }
+
+                foreach ($dirs as $dir)
+                {
+                    $className = substr($class, $pos + 1);
+
+                    $file = $dir.DIRECTORY_SEPARATOR.
+                                 str_replace('\\', DIRECTORY_SEPARATOR, $namespace).
+                                 DIRECTORY_SEPARATOR.
+                                 $className.'.php';
+
+                    if (file_exists($file))
+                    {
+                        return $file;
+                    }
+                }
+            }
+
+            // Iterate in Thrift namespaces
+
+            // Remove first part of namespace
+            $m = explode('\\', $class);
+
+            // Ignore wrong call
+            if(count($m) <= 1)
+            {
+                return;
+            }
+
+            $class = array_pop($m);
+            $namespace = implode('\\', $m);
+
+            foreach ($this->definitions as $ns => $dirs)
+            {
+                //Don't interfere with other autoloaders
+                if (0 !== strpos($namespace, $ns))
+                {
+                    continue;
+                }
+
+                foreach ($dirs as $dir)
+                {
+                    /**
+                     * Available in service: Interface, Client, Processor, Rest
+                     * And every service methods (_.+)
+                     */
+                    if(
+                        0 === preg_match('#(.+)(if|client|processor|rest)$#i', $class, $n) and
+                        0 === preg_match('#(.+)_[a-z0-9]+_(args|result)$#i', $class, $n)
+                    )
+                    {
+                        $className = 'Types';
+                    }
+                    else
+                    {
+                        $className = $n[1];
+                    }
+
+                    $file = $dir.DIRECTORY_SEPARATOR .
+                                 str_replace('\\', DIRECTORY_SEPARATOR, $namespace) .
+                                 DIRECTORY_SEPARATOR .
+                                 $className . '.php';
+
+                    if (file_exists($file))
+                    {
+                        return $file;
+                    }
+                }
+            }
+        }
+    }
+}

Added: thrift/trunk/lib/php/lib/Thrift/Exception/TApplicationException.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/Exception/TApplicationException.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/Exception/TApplicationException.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/Exception/TApplicationException.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,69 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+use Thrift\Type\TType;
+
+class TApplicationException extends TException {
+  static $_TSPEC =
+    array(1 => array('var' => 'message',
+                     'type' => TType::STRING),
+          2 => array('var' => 'code',
+                     'type' => TType::I32));
+
+  const UNKNOWN = 0;
+  const UNKNOWN_METHOD = 1;
+  const INVALID_MESSAGE_TYPE = 2;
+  const WRONG_METHOD_NAME = 3;
+  const BAD_SEQUENCE_ID = 4;
+  const MISSING_RESULT = 5;
+  const INTERNAL_ERROR = 6;
+  const PROTOCOL_ERROR = 7;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+
+  public function read($output) {
+    return $this->_read('TApplicationException', self::$_TSPEC, $output);
+  }
+
+  public function write($output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin('TApplicationException');
+    if ($message = $this->getMessage()) {
+      $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
+      $xfer += $output->writeString($message);
+      $xfer += $output->writeFieldEnd();
+    }
+    if ($code = $this->getCode()) {
+      $xfer += $output->writeFieldBegin('type', TType::I32, 2);
+      $xfer += $output->writeI32($code);
+      $xfer += $output->writeFieldEnd();
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+}

Added: thrift/trunk/lib/php/lib/Thrift/Exception/TException.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/Exception/TException.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/Exception/TException.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/Exception/TException.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,369 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Type\TType;
+use Thrift\Base\TBase;
+
+/**
+ * NOTE(mcslee): This currently contains a ton of duplicated code from TBase
+ * because we need to save CPU cycles and this is not yet in an extension.
+ * Ideally we'd multiply-inherit TException from both Exception and Base, but
+ * that's not possible in PHP and there are no modules either, so for now we
+ * apologetically take a trip to HackTown.
+ *
+ * Can be called with standard Exception constructor (message, code) or with
+ * Thrift Base object constructor (spec, vals).
+ *
+ * @param mixed $p1 Message (string) or type-spec (array)
+ * @param mixed $p2 Code (integer) or values (array)
+ */
+class TException extends \Exception {
+  function __construct($p1=null, $p2=0) {
+    if (is_array($p1) && is_array($p2)) {
+      $spec = $p1;
+      $vals = $p2;
+      foreach ($spec as $fid => $fspec) {
+        $var = $fspec['var'];
+        if (isset($vals[$var])) {
+          $this->$var = $vals[$var];
+        }
+      }
+    } else {
+      parent::__construct($p1, $p2);
+    }
+  }
+
+  static $tmethod = array(TType::BOOL   => 'Bool',
+                          TType::BYTE   => 'Byte',
+                          TType::I16    => 'I16',
+                          TType::I32    => 'I32',
+                          TType::I64    => 'I64',
+                          TType::DOUBLE => 'Double',
+                          TType::STRING => 'String');
+
+  private function _readMap(&$var, $spec, $input) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kread = $vread = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kread = 'read'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vread = 'read'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $var = array();
+    $_ktype = $_vtype = $size = 0;
+    $xfer += $input->readMapBegin($_ktype, $_vtype, $size);
+    for ($i = 0; $i < $size; ++$i) {
+      $key = $val = null;
+      if ($kread !== null) {
+        $xfer += $input->$kread($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $class = $kspec['class'];
+          $key = new $class();
+          $xfer += $key->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($key, $kspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($key, $kspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($key, $kspec, $input, true);
+          break;
+        }
+      }
+      if ($vread !== null) {
+        $xfer += $input->$vread($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $class = $vspec['class'];
+          $val = new $class();
+          $xfer += $val->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($val, $vspec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($val, $vspec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($val, $vspec, $input, true);
+          break;
+        }
+      }
+      $var[$key] = $val;
+    }
+    $xfer += $input->readMapEnd();
+    return $xfer;
+  }
+
+  private function _readList(&$var, $spec, $input, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $eread = $vread = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $eread = 'read'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    $var = array();
+    $_etype = $size = 0;
+    if ($set) {
+      $xfer += $input->readSetBegin($_etype, $size);
+    } else {
+      $xfer += $input->readListBegin($_etype, $size);
+    }
+    for ($i = 0; $i < $size; ++$i) {
+      $elem = null;
+      if ($eread !== null) {
+        $xfer += $input->$eread($elem);
+      } else {
+        $espec = $spec['elem'];
+        switch ($etype) {
+        case TType::STRUCT:
+          $class = $espec['class'];
+          $elem = new $class();
+          $xfer += $elem->read($input);
+          break;
+        case TType::MAP:
+          $xfer += $this->_readMap($elem, $espec, $input);
+          break;
+        case TType::LST:
+          $xfer += $this->_readList($elem, $espec, $input, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_readList($elem, $espec, $input, true);
+          break;
+        }
+      }
+      if ($set) {
+        $var[$elem] = true;
+      } else {
+        $var []= $elem;
+      }
+    }
+    if ($set) {
+      $xfer += $input->readSetEnd();
+    } else {
+      $xfer += $input->readListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _read($class, $spec, $input) {
+    $xfer = 0;
+    $fname = null;
+    $ftype = 0;
+    $fid = 0;
+    $xfer += $input->readStructBegin($fname);
+    while (true) {
+      $xfer += $input->readFieldBegin($fname, $ftype, $fid);
+      if ($ftype == TType::STOP) {
+        break;
+      }
+      if (isset($spec[$fid])) {
+        $fspec = $spec[$fid];
+        $var = $fspec['var'];
+        if ($ftype == $fspec['type']) {
+          $xfer = 0;
+          if (isset(TBase::$tmethod[$ftype])) {
+            $func = 'read'.TBase::$tmethod[$ftype];
+            $xfer += $input->$func($this->$var);
+          } else {
+            switch ($ftype) {
+            case TType::STRUCT:
+              $class = $fspec['class'];
+              $this->$var = new $class();
+              $xfer += $this->$var->read($input);
+              break;
+            case TType::MAP:
+              $xfer += $this->_readMap($this->$var, $fspec, $input);
+              break;
+            case TType::LST:
+              $xfer += $this->_readList($this->$var, $fspec, $input, false);
+              break;
+            case TType::SET:
+              $xfer += $this->_readList($this->$var, $fspec, $input, true);
+              break;
+            }
+          }
+        } else {
+          $xfer += $input->skip($ftype);
+        }
+      } else {
+        $xfer += $input->skip($ftype);
+      }
+      $xfer += $input->readFieldEnd();
+    }
+    $xfer += $input->readStructEnd();
+    return $xfer;
+  }
+
+  private function _writeMap($var, $spec, $output) {
+    $xfer = 0;
+    $ktype = $spec['ktype'];
+    $vtype = $spec['vtype'];
+    $kwrite = $vwrite = null;
+    if (isset(TBase::$tmethod[$ktype])) {
+      $kwrite = 'write'.TBase::$tmethod[$ktype];
+    } else {
+      $kspec = $spec['key'];
+    }
+    if (isset(TBase::$tmethod[$vtype])) {
+      $vwrite = 'write'.TBase::$tmethod[$vtype];
+    } else {
+      $vspec = $spec['val'];
+    }
+    $xfer += $output->writeMapBegin($ktype, $vtype, count($var));
+    foreach ($var as $key => $val) {
+      if (isset($kwrite)) {
+        $xfer += $output->$kwrite($key);
+      } else {
+        switch ($ktype) {
+        case TType::STRUCT:
+          $xfer += $key->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($key, $kspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($key, $kspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($key, $kspec, $output, true);
+          break;
+        }
+      }
+      if (isset($vwrite)) {
+        $xfer += $output->$vwrite($val);
+      } else {
+        switch ($vtype) {
+        case TType::STRUCT:
+          $xfer += $val->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($val, $vspec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($val, $vspec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($val, $vspec, $output, true);
+          break;
+        }
+      }
+    }
+    $xfer += $output->writeMapEnd();
+    return $xfer;
+  }
+
+  private function _writeList($var, $spec, $output, $set=false) {
+    $xfer = 0;
+    $etype = $spec['etype'];
+    $ewrite = null;
+    if (isset(TBase::$tmethod[$etype])) {
+      $ewrite = 'write'.TBase::$tmethod[$etype];
+    } else {
+      $espec = $spec['elem'];
+    }
+    if ($set) {
+      $xfer += $output->writeSetBegin($etype, count($var));
+    } else {
+      $xfer += $output->writeListBegin($etype, count($var));
+    }
+    foreach ($var as $key => $val) {
+      $elem = $set ? $key : $val;
+      if (isset($ewrite)) {
+        $xfer += $output->$ewrite($elem);
+      } else {
+        switch ($etype) {
+        case TType::STRUCT:
+          $xfer += $elem->write($output);
+          break;
+        case TType::MAP:
+          $xfer += $this->_writeMap($elem, $espec, $output);
+          break;
+        case TType::LST:
+          $xfer += $this->_writeList($elem, $espec, $output, false);
+          break;
+        case TType::SET:
+          $xfer += $this->_writeList($elem, $espec, $output, true);
+          break;
+        }
+      }
+    }
+    if ($set) {
+      $xfer += $output->writeSetEnd();
+    } else {
+      $xfer += $output->writeListEnd();
+    }
+    return $xfer;
+  }
+
+  protected function _write($class, $spec, $output) {
+    $xfer = 0;
+    $xfer += $output->writeStructBegin($class);
+    foreach ($spec as $fid => $fspec) {
+      $var = $fspec['var'];
+      if ($this->$var !== null) {
+        $ftype = $fspec['type'];
+        $xfer += $output->writeFieldBegin($var, $ftype, $fid);
+        if (isset(TBase::$tmethod[$ftype])) {
+          $func = 'write'.TBase::$tmethod[$ftype];
+          $xfer += $output->$func($this->$var);
+        } else {
+          switch ($ftype) {
+          case TType::STRUCT:
+            $xfer += $this->$var->write($output);
+            break;
+          case TType::MAP:
+            $xfer += $this->_writeMap($this->$var, $fspec, $output);
+            break;
+          case TType::LST:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, false);
+            break;
+          case TType::SET:
+            $xfer += $this->_writeList($this->$var, $fspec, $output, true);
+            break;
+          }
+        }
+        $xfer += $output->writeFieldEnd();
+      }
+    }
+    $xfer += $output->writeFieldStop();
+    $xfer += $output->writeStructEnd();
+    return $xfer;
+  }
+
+}

Added: thrift/trunk/lib/php/lib/Thrift/Exception/TProtocolException.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/Exception/TProtocolException.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/Exception/TProtocolException.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/Exception/TProtocolException.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,48 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.protocol
+ * @author: rmarin (marin.radu@facebook.com)
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+
+/**
+ * Protocol module. Contains all the types and definitions needed to implement
+ * a protocol encoder/decoder.
+ *
+ * @package thrift.protocol
+ */
+
+/**
+ * Protocol exceptions
+ */
+class TProtocolException extends TException {
+  const UNKNOWN = 0;
+  const INVALID_DATA = 1;
+  const NEGATIVE_SIZE = 2;
+  const SIZE_LIMIT = 3;
+  const BAD_VERSION = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}

Added: thrift/trunk/lib/php/lib/Thrift/Exception/TTransportException.php
URL: http://svn.apache.org/viewvc/thrift/trunk/lib/php/lib/Thrift/Exception/TTransportException.php?rev=1381323&view=auto
==============================================================================
--- thrift/trunk/lib/php/lib/Thrift/Exception/TTransportException.php (added)
+++ thrift/trunk/lib/php/lib/Thrift/Exception/TTransportException.php Wed Sep  5 19:47:14 2012
@@ -0,0 +1,41 @@
+<?php
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ * @package thrift.transport
+ */
+
+namespace Thrift\Exception;
+
+use Thrift\Exception\TException;
+
+/**
+ * Transport exceptions
+ */
+class TTransportException extends TException {
+
+  const UNKNOWN = 0;
+  const NOT_OPEN = 1;
+  const ALREADY_OPEN = 2;
+  const TIMED_OUT = 3;
+  const END_OF_FILE = 4;
+
+  function __construct($message=null, $code=0) {
+    parent::__construct($message, $code);
+  }
+}
\ No newline at end of file