Close #4875
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 6562e99..32ad618 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -416,10 +416,29 @@
 			$params = array($method, array_slice($URI->rsegments, 2));
 			$method = '_remap';
 		}
-		elseif ( ! is_callable(array($class, $method)))
+		elseif ( ! method_exists($class, $method))
 		{
 			$e404 = TRUE;
 		}
+		/**
+		 * DO NOT CHANGE THIS, NOTHING ELSE WORKS!
+		 *
+		 * - method_exists() returns true for non-public methods, which passes the previous elseif
+		 * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct()
+		 * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited
+		 * - People will only complain if this doesn't work, even though it is documented that it shouldn't.
+		 *
+		 * ReflectionMethod::isConstructor() is the ONLY reliable check,
+		 * knowing which method will be executed as a constructor.
+		 */
+		elseif ( ! is_callable(array($class, $method)) && strcasecmp($class, $method) === 0)
+		{
+			$reflection = new ReflectionMethod($class, $method);
+			if ( ! $reflection->isPublic() OR $reflection->isConstructor())
+			{
+				$e404 = TRUE;
+			}
+		}
 	}
 
 	if ($e404)
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index ee66cc0..b7be086 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -11,6 +11,10 @@
 
    -  Fixed a new URL-encoding attack vector in :doc:`Security Library <libraries/security>` method ``xss_clean()`` affecting Firefox.
 
+-  General Changes
+
+   -  Allowed PHP 4-style constructors (``Mathching_name::Matching_name()`` methods) to be used as routes, if there's a ``__construct()`` to override them.
+
 Version 3.1.1
 =============