特定のクラス内で定義されている保護された関数があります。この保護された関数をクラス外の別の関数内で呼び出すことができるようにしたい。これは可能ですか、それが可能であればどのように達成できますか
class cExample{
protected function funExample(){
//functional code goes here
return $someVar
}//end of function
}//end of class
function outsideFunction(){
//Calls funExample();
}
それがOOP-カプセル化のポイントです:
プライベート
Only can be used inside the class. Not inherited by child classes.
保護
Only can be used inside the class and child classes. Inherited by child classes.
公開
Can be used anywhere. Inherited by child classes.
それでもその関数を外部でトリガーしたい場合は、保護されたメソッドをトリガーするパブリックメソッドを宣言できます。
protected function b(){
}
public function a(){
$this->b() ;
//etc
}
技術的には、リフレクションAPIを使用してプライベートメソッドと保護メソッドを呼び出すことができます。ただし、99%の場合、これは非常に悪い考えです。クラスを変更できる場合、おそらく正しい解決策は、メソッドをパブリックにすることです。結局のところ、クラスの外でそれにアクセスする必要がある場合、それを保護されているとマークするという点は無効になります。
これが実際に必要な非常に数少ない状況の1つである場合の簡単なリフレクションの例を次に示します。
<?php
class foo {
protected function bar($param){
echo $param;
}
}
$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");
このクラスは、このクラスを公開する別のクラスでオーバーライドできます。
class cExample2 extends cExample {
public function funExample(){
return parent::funExample()
}
}
(これはプライベートメンバーでは機能しません)
ただし、プライベートおよび保護されたメンバーの考えは、外部から呼び出されないことです。
クラス間でコードを共有する場合は、特性を使用できますが、関数/メソッドの使用方法によって異なります。
とにかく
trait cTrait{
public function myFunction() {
$this->funExample();
}
}
class cExample{
use cTrait;
protected function funExample() {
//functional code goes here
return $someVar
}//end of function
}//end of class
$object = new cExample();
$object->myFunction();
これは機能しますが、クラスがこのように構成されているかどうかはわかりません。トレイトを変更すると、それを使用するすべてのクラスも変更されます。また、使用するすべての特性のインターフェースを作成することもお勧めします。
ここで私はあなたに以下のような一例を与えることができます
<?php
class dog {
public $Name;
private function getName() {
return $this->Name;
}
}
class poodle extends dog {
public function bark() {
print "'Woof', says " . $this->getName();
}
}
$poppy = new poodle;
$poppy->Name = "Poppy";
$poppy->bark();
?>
または最新のphpで使用する別の方法
PHPでは、Reflectionsを使用してこれを実行できます。保護されたメソッドまたはプライベートメソッドを呼び出すには、setAccessible()メソッドを使用します http://php.net/reflectionmethod.setaccessible ( TRUEに設定)
何をしているのかわかっている場合は、匿名クラスを使用できます(PHP 7以降)
class Bar {
protected baz() {
return 'Baz!';
}
}
$foo = new class extends Bar {
public baz() {
parent::baz();
}
}
$foo->baz(); // "Baz!"