¿Puedo/Cómo… llamar a una función protegida fuera de una clase en PHP?

4 minutos de lectura

Tengo una función protegida que se define dentro de una determinada clase. Quiero poder llamar a esta función protegida fuera de la clase dentro de otra función. ¿Es esto posible y, de ser así, cómo puedo lograrlo?

class cExample{

   protected function funExample(){
   //functional code goes here

   return $someVar
   }//end of function

}//end of class


function outsideFunction(){

//Calls funExample();

}

  • no puedes Eso anularía el propósito de tener una función protegida en primer lugar. Podría tener un método público que invoque el método protegido en su nombre, pero entonces, ¿por qué tener un método protegido para empezar?

    – Marc B.

    18/06/2013 a las 16:30

  • Un duplicado de stackoverflow.com/q/12255740/2088851

    – Voitcus

    18 de junio de 2013 a las 16:34

Avatar de usuario de Peter Geer
pedro geer

Técnicamente, es posible invocar métodos privados y protegidos utilizando la API de reflexión. Sin embargo, el 99% de las veces hacerlo es una muy mala idea. Si puede modificar la clase, entonces la solución correcta probablemente sea simplemente hacer público el método. Después de todo, si necesita acceder a él fuera de la clase, eso anula el punto de marcarlo como protegido.

Aquí hay un ejemplo de reflexión rápida, en caso de que esta sea una de las pocas situaciones en las que es realmente necesario:

<?php
class foo { 
    protected function bar($param){
        echo $param;
    }
}

$r = new ReflectionMethod('foo', 'bar');
$r->setAccessible(true);
$r->invoke(new foo(), "Hello World");

  • Esta es la respuesta correcta para las personas que saben lo que están haciendo.

    –Andras Gyomrey

    27/03/2018 a las 10:00

  • Nota al margen: Esto está disponible en PHP 5.4+ (¡Sí!)

    –Lucas Bustamante

    10 oct 2018 a las 23:29

  • ¿Algún cambio/nuevas posibilidades en 2018?

    – beppe9000

    23 de noviembre de 2018 a las 20:22

  • Esto es oro puro (y la respuesta real a la pregunta)

    – CptAJ

    16 de enero de 2019 a las 14:04

Ese es el punto de OOP – encapsulación:

Privado

Only can be used inside the class. Not inherited by child classes.

Protegido

Only can be used inside the class and child classes. Inherited by child classes.

Público

Can be used anywhere. Inherited by child classes.

Si aún desea activar esa función en el exterior, puede declarar un método público que active su método protegido:

protected function b(){

}

public function a(){
  $this->b() ;
  //etc
}

  • Puede acceder al miembro protegido de otra instancia si ambos extienden la misma clase abstracta. No lo creí hasta que lo vi.

    – Daniel W.

    28 de junio de 2018 a las 13:33

Avatar de usuario de Lucas Bustamante
lucas bustamante

Si el método de los padres está protegido, puede usar una clase anónima:

class Foo {
    protected function do_foo() {
        return 'Foo!';
    }
}

$bar = new class extends Foo {
    public function do_foo() {
      return parent::do_foo();
    }
}

$bar->do_foo(); // "Foo!"

https://www.php.net/manual/en/language.oop5.anonymous.php

  • Me gusta este enfoque ya que mantiene la semántica de OOP

    – KalenGi

    16 sep a las 19:52

Puede anular esta clase con otra en la que lo haga público.

class cExample2 extends cExample {
  public function funExample(){
    return parent::funExample()
  }
}

(Tenga en cuenta que esto no funcionará con miembros privados)

Pero la idea de miembros privados y protegidos es NO SER llamados desde afuera.

Otra opción (PHP 7.4)

<?php
class cExample {
   protected function funExample(){
       return 'it works!';
   }
}

$example = new cExample();

$result = Closure::bind(
    fn ($class) => $class->funExample(), null, get_class($example)
)($example);

echo $result; // it works!

  • En PHP 7.3, recibí el siguiente error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ')' Tuve que usar esta sintaxis en su lugar: $result = Closure::bind(function ($class) { return $class->funExample(); }, null, get_class($example))($example);

    – Guy Paddock

    12 de julio de 2021 a las 18:41


avatar de usuario de mhlavac
mhlavac

Si desea compartir código entre sus clases, puede usar rasgos, pero depende de cómo quiera usar su función/método.

De todos modos

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();

Esto funcionará, pero tenga en cuenta que no sabe de qué está hecha su clase de esta manera. Si cambia el rasgo, todas las clases que lo usen también se modificarán. También es una buena práctica escribir una interfaz para cada rasgo que utilice.

  • En PHP 7.3, recibí el siguiente error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ')' Tuve que usar esta sintaxis en su lugar: $result = Closure::bind(function ($class) { return $class->funExample(); }, null, get_class($example))($example);

    – Guy Paddock

    12 de julio de 2021 a las 18:41


avatar de usuario de liyakat
liyakat

aquí puedo darte un ejemplo como el siguiente

<?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();
?>

u otra forma de usar con el último php

En PHP puedes hacer esto usando Reflections. Para invocar métodos protegidos o privados, use el método setAccessible() http://php.net/reflectionmethod.setaccessible (simplemente configúrelo en VERDADERO)

¿Ha sido útil esta solución?