php - Changing the visibility scope of parent methods in child classes -


i've got validator class , uservalidator class extends it.

my validator has public method setrule(...) public visibility.

when extend want change visibility of setrule(...) parent method private/protected within child it's visible child , no outsiders can call method from child.

is possible? if so, how achieve it?

from architectural point of view not recommended. stated in comments clean way set method protected children can access it.

i cannot think of single use case put me in need call public method on parent class not allowed call on child class.

that's against open/closed principle. classes should open extension, not modification.

since not question i'll provide way how can achieved though. note:

  • this method makes use of class responsible instantiation
  • it's hack. solution not make use of php's native language features when throwing accessibility errors.

first let's define classes had

<?php  class validator {      public function setrule()     {         echo "hello world";     }  }  class uservalidator extends validator {      public $prop = 'property';  } 

there's nothing special here. let's go on , create custom exception class visibility error.

<?php  class methodnotaccessibleexception extends exception {} 

this exception thrown when try invoke "pseudo-private" method on child class.

now want create class responsible instantiating child class. wrapper defines lock property holds method names should not accessible.

<?php  class privateinstancecreator {      protected $reflectionclass;     protected $lock = [];     protected $instance;      public function __construct($classname, $args = [])      {         // we'll store instance of reflection class         // , instance of real class         $this->reflectionclass = new reflectionclass($classname);         $this->instance = $this->reflectionclass->newinstanceargs($args);         return $this;     }      // lock method able make method on     // target class "pseudo-private"     public function lock($method)     {         $this->lock[] = $method;         return $this;     }      // real magic going on here     // remember. class wrapper real class     // if method invoked method     // in real instance , invoke it...     public function __call($method, $args)     {         // ... method defined         // locked, we'll raise exception method         // private         if(in_array($method, $this->lock))         {             $reflectionmethod = $this->reflectionclass->getmethod($method);             if($reflectionmethod->ispublic())                 throw new methodnotaccessibleexception('method: __' . $method . '__ private , not invoked');         }          return call_user_func_array([$this->instance, $method], $args);     }      // same goes properties     // in case we'll no protection     public function __get($prop)     {         return $this->instance->{$prop};     }  } 

our final step instantiation.

<?php  $uservalidator = new privateinstancecreator('uservalidator', []); $uservalidator->lock('setrule');  $uservalidator->setrule(); //will throw exception 

instead of instantiating class directly we'll using our custom wrapper class. of course handle in child class itself, that's way accomplish task without touching classes directly.

having said that, it still dirty hack usage should avoided if possible. if instantiate child class directly inherited methods still public.

so if developer has no knowlege wrapper class he'll have hard time figure out how instantiate child class properly.

update:

to make child class uninstantiable directly can set constructor private , call newinstancewithoutconstructor() reflection class, dirtier, since make dependency injection class impossible. i'm mentioning completenesses sake. usage still not recommended


Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -