utilizar - sobre php




¿Cuándo usar uno mismo sobre $ esto? (15)

En PHP 5, ¿cuál es la diferencia entre usar self y $this ?

¿Cuándo es apropiado cada uno?


Este es un ejemplo del uso correcto de $ this y self para variables miembro no estáticas y estáticas:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?> 

Respuesta corta

Use $this para referirse al objeto actual. Use self para referirse a la clase actual. En otras palabras, use $this->member para $this->member no estáticos, use self::$member para miembros estáticos.

Respuesta completa

Este es un ejemplo del uso correcto de $this y self para variables miembro no estáticas y estáticas:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo $this->non_static_member . ' '
           . self::$static_member;
    }
}

new X();
?>

Este es un ejemplo de uso incorrecto de $this y self para variables miembro no estáticas y estáticas:

<?php
class X {
    private $non_static_member = 1;
    private static $static_member = 2;

    function __construct() {
        echo self::$non_static_member . ' '
           . $this->static_member;
    }
}

new X();
?>

Aquí hay un ejemplo de polimorfismo con $this para funciones miembro:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        $this->foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

Este es un ejemplo de supresión del comportamiento polimórfico mediante el uso de self para funciones miembro:

<?php
class X {
    function foo() {
        echo 'X::foo()';
    }

    function bar() {
        self::foo();
    }
}

class Y extends X {
    function foo() {
        echo 'Y::foo()';
    }
}

$x = new Y();
$x->bar();
?>

La idea es que $this->foo() llama a la función miembro foo() de cualquier tipo que sea el tipo exacto del objeto actual. Si el objeto es de type X , entonces llama a X::foo() . Si el objeto es de type Y , llama a Y::foo() . Pero con self :: foo (), X::foo() siempre se llama.

De http://www.phpbuilder.com/board/showthread.php?t=10354489 :

Por http://board.phpbuilder.com/member.php?145249-laserlight


Creo que la pregunta no era si puede llamar al miembro estático de la clase llamando a ClassName::staticMember . La pregunta era cuál es la diferencia entre usar self::classmember y $this->classmember .

Por ejemplo, los dos ejemplos siguientes funcionan sin errores, ya sea que uses self:: o $this->

class Person{
    private $name;
    private $address;

    public function __construct($new_name,$new_address){
        $this->name = $new_name;
        $this->address = $new_address;
    }
}

class Person{
    private $name;
    private $address;
    public function __construct($new_name,$new_address){
        self::$name = $new_name;
        self::$address = $new_address;
    }
}

De esta entrada de blog :

  • self refiere a la clase actual
  • self puede utilizarse para llamar a funciones estáticas y hacer referencia a variables miembro estáticas
  • self puede ser usado dentro de funciones estáticas
  • self también puede desactivar el comportamiento polimórfico al pasar por alto el vtable
  • $this refiere al objeto actual
  • $this puede ser usado para llamar a funciones estáticas.
  • $this no debe usarse para llamar a variables miembro estáticas. Use el self en self lugar.
  • $this no puede ser usado dentro de funciones estáticas.

En PHP, utiliza la palabra clave self para acceder a métodos y propiedades estáticas.

El problema es que puedes reemplazar $this->method() con self::method() cualquier lugar, sin importar si el method() está declarado estático o no. Entonces, ¿cuál debería usar?

Considere este código:

class ParentClass {
    function test() {
        self::who();    // will output 'parent'
        $this->who();   // will output 'child'
    }

    function who() {
        echo 'parent';
    }
}

class ChildClass extends ParentClass {
    function who() {
        echo 'child';
    }
}

$obj = new ChildClass();
$obj->test();

En este ejemplo, self::who() siempre generará 'padre', mientras que $this->who() dependerá de la clase que tenga el objeto.

Ahora podemos ver que self se refiere a la clase en la que se llama, mientras que $this refiere a la clase del objeto actual .

Por lo tanto, debe usar self solo cuando $this no está disponible, o cuando no quiere permitir que las clases descendientes sobrescriban el método actual.


La palabra clave self NO se refiere simplemente a la 'clase actual', al menos no de una manera que lo restringe a miembros estáticos. En el contexto de un miembro no estático, self también proporciona una forma de omitir vtable ( vea wiki en vtable ) para el objeto actual. Del mismo modo que puede usar parent::methodName() para llamar a la versión de los padres de una función, también puede llamar a self::methodName() para llamar a la implementación de clases actual de un método.

class Person {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }

    public function getTitle() {
        return $this->getName()." the person";
    }

    public function sayHello() {
        echo "Hello, I'm ".$this->getTitle()."<br/>";
    }

    public function sayGoodbye() {
        echo "Goodbye from ".self::getTitle()."<br/>";
    }
}

class Geek extends Person {
    public function __construct($name) {
        parent::__construct($name);
    }

    public function getTitle() {
        return $this->getName()." the geek";
    }
}

$geekObj = new Geek("Ludwig");
$geekObj->sayHello();
$geekObj->sayGoodbye();

Esto dará como resultado:

Hola soy luis el friki
Adiós de ludwig la persona

sayHello() usa el puntero $this , por lo que se invoca vtable para llamar a Geek::getTitle() . sayGoodbye() usa self::getTitle() , por lo que no se usa vtable, y se llama Person::getTitle() . En ambos casos, estamos tratando con el método de un objeto instanciado y tenemos acceso al puntero $this dentro de las funciones llamadas.


Según http://www.php.net/manual/en/language.oop5.static.php no hay $self . Solo hay $this , para referirse a la instancia actual de la clase (el objeto), y self, que puede usarse para referirse a miembros estáticos de una clase. La diferencia entre una instancia de objeto y una clase entra en juego aquí.


$this-> se usa para referirse a una instancia específica de las variables de una clase (variables miembro) o métodos.

Example: 
$derek = new Person();

$ derek es ahora una instancia específica de Person. Cada persona tiene un primer nombre y un último nombre, pero $ derek tiene un primer nombre y un apellido (Derek Martin) específicos. Dentro de la instancia de $ derek, podemos referirnos a ellos como $ this-> first_name y $ this-> last_name

ClassName :: se usa para referirse a ese tipo de clase, y sus variables estáticas, métodos estáticos. Si ayuda, puedes reemplazar mentalmente la palabra "estática" por "compartida". Debido a que se comparten, no pueden referirse a $ this, que se refiere a una instancia específica (no compartida). Las variables estáticas (es decir, $ db_connection estática) se pueden compartir entre todas las instancias de un tipo de objeto. Por ejemplo, todos los objetos de la base de datos comparten una sola conexión ($ estática de conexión).

Variables estáticas Ejemplo: Pretenda que tenemos una clase de base de datos con una única variable miembro: static $ num_connections; Ahora, pon esto en el constructor:

function __construct()
{
    if(!isset $num_connections || $num_connections==null)
    {
        $num_connections=0;
    }
    else
    {
        $num_connections++;
    }
}

Al igual que los objetos tienen constructores, también tienen destructores, que se ejecutan cuando el objeto muere o no está configurado:

function __destruct()
{
    $num_connections--;
}

Cada vez que creamos una nueva instancia, aumentará nuestro contador de conexión en uno. Cada vez que destruyamos o dejemos de usar una instancia, disminuirá el contador de conexión en uno. De esta manera, podemos monitorear la cantidad de instancias del objeto de base de datos que tenemos en uso con:

echo DB::num_connections;

Debido a que $ num_connections es estático (compartido), reflejará el número total de objetos de base de datos activos. Es posible que haya visto esta técnica utilizada para compartir conexiones de base de datos entre todas las instancias de una clase de base de datos. Esto se hace porque la creación de la conexión de la base de datos lleva mucho tiempo, por lo que es mejor crear solo una y compartirla (esto se denomina patrón Singleton).

Los métodos estáticos (es decir, la vista estática pública :: format_phone_number ($ dígitos)) se pueden usar SIN la primera instancia de uno de esos objetos (es decir, no se refieren internamente a $ this).

Ejemplo de método estático:

public static function prettyName($first_name, $last_name)
{
    echo ucfirst($first_name).' '.ucfirst($last_name);
}

echo Person::prettyName($derek->first_name, $derek->last_name);

Como puede ver, la función estática pública prettyName no sabe nada sobre el objeto. Simplemente funciona con los parámetros que se pasan, como una función normal que no forma parte de un objeto. ¿Por qué molestarse, entonces, si no pudiéramos tenerlo como parte del objeto?

  1. Primero, adjuntar funciones a objetos le ayuda a mantener las cosas organizadas, para que sepa dónde encontrarlas.
  2. En segundo lugar, evita conflictos de nombres. En un proyecto grande, es probable que dos desarrolladores creen funciones getName (). Si uno crea un ClassName1 :: getName (), y el otro crea ClassName2 :: getName (), no hay ningún problema. No conflicto. ¡Yay métodos estáticos!

SELF :: Si está codificando fuera del objeto que tiene el método estático al que desea referirse, debe llamarlo usando el nombre del objeto View :: format_phone_number ($ phone_number); Si está codificando dentro del objeto que tiene el método estático al que desea referirse, puede usar el nombre del objeto View :: format_phone_number ($ pn), O puede usar el atajo self :: format_phone_number ($ pn)

Lo mismo ocurre con las variables estáticas: Ejemplo: Ver :: templates_path versus self :: templates_path

Dentro de la clase DB, si nos estuviéramos refiriendo a un método estático de algún otro objeto, usaríamos el nombre del objeto: Ejemplo: Session :: getUsersOnline ();

Pero si la clase DB quisiera referirse a su propia variable estática, solo diría self: Ejemplo: self :: connection;

Espero que ayude a aclarar las cosas :)


self (no $ self) se refiere al tipo de clase, donde como $this refiere a la instancia actual de la clase. self es para uso en funciones miembro estáticas para permitirle acceder a variables miembro estáticas. $this se usa en funciones miembro no estáticas, y es una referencia a la instancia de la clase en la que se llamó la función miembro.

Como this es un objeto, lo usas como: $this->member

Debido a que self no es un objeto, es básicamente un tipo que se refiere automáticamente a la clase actual, se usa como: self::member


self refiere a la clase actual (en la que se llama),

$this refiere al objeto actual. Puedes usar estática en lugar de auto. Vea el ejemplo:

    class ParentClass {
            function test() {
                    self::which();  // output 'parent'
                    $this->which(); // output 'child'
            }

            function which() {
                    echo 'parent';
            }
    }

    class ChildClass extends ParentClass {
            function which() {
                    echo 'child';
            }
    }

    $obj = new ChildClass();
    $obj->test();

Salida: padre hijo


Me encontré con la misma pregunta y la respuesta simple es:

  • $ Esto requiere una instancia de la clase.
  • self :: does

Siempre que utilice métodos estáticos o atributos estáticos y desee llamarlos sin tener un objeto de la clase instanciada, debe usar self :: para llamarlos, porque $ esto siempre requiere que se cree un objeto.


Úselo selfsi desea llamar a un método de una clase sin crear un objeto / instancia de esa clase, y así ahorrar RAM (a veces usar el self para ese propósito). En otras palabras, en realidad está llamando a un método estáticamente. Utilizar thispara la perspectiva del objeto.


Caso 1: El uso selfpuede usarse para constantes de clase

 class classA { 
     const FIXED_NUMBER = 4; 
     self::POUNDS_TO_KILOGRAMS
}

Si desea llamarlo fuera de la clase, use classA::POUNDS_TO_KILOGRAMSpara acceder a las constantes

Caso 2: Para propiedades estáticas

class classC {
     public function __construct() { 
     self::$_counter++; $this->num = self::$_counter;
   }
}

Cuando selfse usa con el ::operador, se refiere a la clase actual, que se puede hacer tanto en contextos estáticos como no estáticos. $thisse refiere al objeto en sí. Además, es perfectamente legal usarlo $thispara llamar a métodos estáticos (pero no para referirse a campos).


  • El puntero del objeto $ esto se refiere al objeto actual.
  • El valor de la clase "estático" se refiere al objeto actual.
  • El valor de clase "self" se refiere a la clase exacta en la que se definió.
  • El valor de clase "padre" se refiere al padre de la clase exacta en la que se definió.

Vea el siguiente ejemplo que muestra la sobrecarga.

<?php

class A {

    public static function newStaticClass()
    {
        return new static;
    }

    public static function newSelfClass()
    {
        return new self;
    }

    public function newThisClass()
    {
        return new $this;
    }
}

class B extends A
{
    public function newParentClass()
    {
        return new parent;
    }
}


$b = new B;

var_dump($b::newStaticClass()); // B
var_dump($b::newSelfClass()); // A because self belongs to "A"
var_dump($b->newThisClass()); // B
var_dump($b->newParentClass()); // A


class C extends B
{
    public static function newSelfClass()
    {
        return new self;
    }
}


$c = new C;

var_dump($c::newStaticClass()); // C
var_dump($c::newSelfClass()); // C because self now points to "C" class
var_dump($c->newThisClass()); // C
var_dump($b->newParentClass()); // A because parent was defined *way back* in class "B"

La mayoría de las veces desea referirse a la clase actual por lo que usa statico $this. Sin embargo, hay ocasiones en las que necesitas self porque quieres la clase original independientemente de lo que la extienda. (Muy, muy rara vez)







scope