public class User {
        public $userid;
        public $username;
        private $password;

        public class UserProfile {
            // Some code here

        private class UserHistory {
            // Some code here




OuterClass outerObj = new OuterClass(arguments);
outerObj.InnerClass innerObj = InnerClass(arguments);



If a class is useful to only one other class, then it is logical to
relate and embed it in that class and keep the two together.


Consider two top-level classes, A and B, where B needs access to
members of A that would otherwise be declared private. By hiding class
B within class A, A’s members can be declared private and B can access
them. In addition, B itself can be hidden from the outside world.


A nested class usually relates to it’s parent class and together form a “package”




class OuterClass {}

namespace OuterClass;
class InnerClass {}



namespace {

    class Package {

        /* protect constructor so that objects can't be instantiated from outside
         * Since all classes inherit from Package class, they can instantiate eachother
         * simulating protected InnerClasses
        protected function __construct() {}

        /* This magic method is called everytime an inaccessible method is called 
         * (either by visibility contrains or it doesn't exist)
         * Here we are simulating shared protected methods across "package" classes
         * This method is inherited by all child classes of Package 
        public function __call($method, $args) {

            //class name
            $class = get_class($this);

            /* we check if a method exists, if not we throw an exception 
             * similar to the default error
            if (method_exists($this, $method)) {

                /* The method exists so now we want to know if the 
                 * caller is a child of our Package class. If not we throw an exception
                 * Note: This is a kind of a dirty way of finding out who's
                 * calling the method by using debug_backtrace and reflection 
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
                if (isset($trace[2])) {
                    $ref = new ReflectionClass($trace[2]['class']);
                    if ($ref->isSubclassOf(__CLASS__)) {
                        return $this->$method($args);
                throw new \Exception("Call to private method $class::$method()");
            } else {
                throw new \Exception("Call to undefined method $class::$method()");


namespace Package {
    class MyParent extends \Package {
        public $publicChild;
        protected $protectedChild;

        public function __construct() {
            //instantiate public child inside parent
            $this->publicChild = new \Package\MyParent\PublicChild();
            //instantiate protected child inside parent
            $this->protectedChild = new \Package\MyParent\ProtectedChild();

        public function test() {
            echo "Call from parent -> ";

            echo "<br>Siblings<br>";

namespace Package\MyParent
    class PublicChild extends \Package {
        //Makes the constructor public, hence callable from outside 
        public function __construct() {}
        protected function protectedMethod() {
            echo "I'm ".get_class($this)." protected method<br>";

        protected function callSibling($sibling) {
            echo "Call from " . get_class($this) . " -> ";
    class ProtectedChild extends \Package { 
        protected function protectedMethod() {
            echo "I'm ".get_class($this)." protected method<br>";

        protected function callSibling($sibling) {
            echo "Call from " . get_class($this) . " -> ";


$parent = new Package\MyParent();
$pubChild = new Package\MyParent\PublicChild();//create new public child (possible)
$protChild = new Package\MyParent\ProtectedChild(); //create new protected child (ERROR)


Call from parent -> I'm Package protected method
I'm Package protected method

Call from Package -> I'm Package protected method
Fatal error: Call to protected Package::__construct() from invalid context