Lowercase autoload strings

Summary: PHP is undebatably the worst programming language in the world. Class names are case insensitive, so new $tHiNg = new $THing. Garbase. Now autoload has to deal with the fallout.

Reviewed By: dreiss

Test Plan: autoload enabled falcon code


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665375 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_generator.h b/compiler/cpp/src/generate/t_generator.h
index 8452f1f..72ef144 100644
--- a/compiler/cpp/src/generate/t_generator.h
+++ b/compiler/cpp/src/generate/t_generator.h
@@ -137,6 +137,12 @@
     in[0] = tolower(in[0]);
     return in;
   }
+  std::string lowercase(std::string in) {
+    for (size_t i = 0; i < in.size(); ++i) {
+      in[i] = tolower(in[i]);
+    }
+    return in;
+  }
 
   /**
    * Get the true type behind a series of typedefs.
diff --git a/compiler/cpp/src/generate/t_php_generator.cc b/compiler/cpp/src/generate/t_php_generator.cc
index b1182d1..eeac91e 100644
--- a/compiler/cpp/src/generate/t_php_generator.cc
+++ b/compiler/cpp/src/generate/t_php_generator.cc
@@ -378,7 +378,7 @@
     autoload_out.close();
 
     f_types_ <<
-      "$GLOBALS['THRIFT_AUTOLOAD']['" << php_namespace(tstruct->get_program()) << tstruct->get_name() << "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
+      "$GLOBALS['THRIFT_AUTOLOAD']['" << lowercase(php_namespace(tstruct->get_program()) + tstruct->get_name()) << "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
 
   } else {
     _generate_php_struct_definition(out, tstruct, is_exception);
@@ -444,8 +444,20 @@
         }
       }
       out <<
-        indent() << "if (is_array($vals)) {" << endl <<
-        indent() << "  parent::__construct(self::$_TSPEC, $vals);" << endl <<
+        indent() << "if (is_array($vals)) {" << endl;
+      indent_up();
+      if (oop_) {
+        out << indent() << "parent::construct(self::$_TSPEC, $vals);" << endl;
+      } else {
+        for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+          out <<
+            indent() << "if (isset($vals['" << (*m_iter)->get_name() << "'])) {" << endl <<
+            indent() << "  $this->" << (*m_iter)->get_name() << " = $vals['" << (*m_iter)->get_name() << "'];" << endl <<
+            indent() << "}" << endl;
+        }
+      }
+      indent_down();
+      out <<
         indent() << "}" << endl;
     }
     scope_down(out);
@@ -1079,7 +1091,7 @@
     autoload_out.close();
 
     f_service_ <<
-      "$GLOBALS['THRIFT_AUTOLOAD']['" << service_name_ << "Client" << "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
+      "$GLOBALS['THRIFT_AUTOLOAD']['" << lowercase(service_name_ + "Client") << "'] = '" << program_name_ << "/" << f_struct << "';" << endl;
 
   } else {
     _generate_service_client(f_service_, tservice);
diff --git a/lib/php/src/autoload.php b/lib/php/src/autoload.php
index b5886c5..43b2470 100644
--- a/lib/php/src/autoload.php
+++ b/lib/php/src/autoload.php
@@ -16,19 +16,26 @@
  * code. The generated code will *not* include any defined Thrift classes by
  * default, except for the service interfaces. The generated code will populate
  * values into $GLOBALS['THRIFT_AUTOLOAD'] which can be used by the autoload
- * method below. If you have your own autoload system already in place, you
- * should merge the following functionality into your autoload system.
+ * method below. If you have your own autoload system already in place, rename your
+ * __autoload function to something else and then do:
+ * $GLOBALS['AUTOLOAD_HOOKS'][] = 'my_autoload_func';
  *
  * Generate this code using the -phpa Thrift generator flag.
  */
 
 $GLOBALS['THRIFT_AUTOLOAD'] = array();
+$GLOBALS['AUTOLOAD_HOOKS'] = array();
 
 if (!function_exists('__autoload')) {
   function __autoload($class) {
     global $THRIFT_AUTOLOAD;
-    if (isset($THRIFT_AUTOLOAD[$class])) {
-      include_once $GLOBALS['THRIFT_ROOT'].'/lib/packages/'.$THRIFT_AUTOLOAD[$class];
+    $classl = strtolower($classl);
+    if (isset($THRIFT_AUTOLOAD[$classl])) {
+      include_once $GLOBALS['THRIFT_ROOT'].'/packages/'.$THRIFT_AUTOLOAD[$classl];
+    } else if (!empty($GLOBALS['AUTOLOAD_HOOKS'])) {
+      foreach ($GLOBALS['AUTOLOAD_HOOKS'] as $hook) {
+        $hook($class);
+      }
     }
   }
 }