Voy a preguntar cuál es la diferencia entre: cont A; $ this-> A and self :: A
timmz
Respuestas:
1728
Respuesta corta
Use $thispara referirse al objeto actual. Use selfpara referirse a la clase actual. En otras palabras, use
$this->memberpara miembros no estáticos, use self::$memberpara miembros estáticos.
Respuesta completa
Aquí hay un ejemplo del uso correcto de $thisy selfpara variables miembro no estáticas y estáticas:
Aquí hay un ejemplo de uso incorrecto de $thisy selfpara variables miembro no estáticas y estáticas:
<?php
class X {private $non_static_member =1;privatestatic $static_member =2;function __construct(){
echo self::$non_static_member .' '. $this->static_member;}}new X();?>
Aquí hay un ejemplo de polimorfismo con $thisfunciones 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();?>
Aquí hay un ejemplo de supresión del comportamiento polimórfico mediante el uso selfde 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 foo()función miembro de lo que sea el tipo exacto del objeto actual. Si el objeto es de type X, así llama X::foo(). Si el objeto es de type Y, llama Y::foo(). Pero con self :: foo (), X::foo()siempre se llama.
Esta respuesta es demasiado simplista. Como se señaló en otras respuestas, selfse usa con el operador de resolución de alcance ::para referirse a la clase actual; Esto se puede hacer tanto en contextos estáticos como no estáticos. Además, es perfectamente legal usarlo $thispara llamar a métodos estáticos (pero no para hacer referencia a campos).
Artefacto
50
También considere usar static :: en lugar de :: self si tiene 5.3+. De lo contrario, puede causarle innumerables dolores de cabeza, vea mi respuesta a continuación para saber por qué.
Sqoo
25
-1. Esta respuesta es engañosa, lea las otras respuestas para obtener más información.
Pacerier
66
Puede estar demasiado simplificado, pero respondió a mi pregunta de nivel básico sin hacer explotar mi cabeza. Obtuve más información que encontré útil más abajo, pero por ahora solo estaba tratando de descubrir por qué golpeé mis atributos de clase con $ this-> attrib y las constantes de clase con self :: constant. Esto me ayudó a entender eso mejor
MydKnight
¿Qué hay de $this::?
James
742
La palabra clave self NO se refiere simplemente a la 'clase actual', al menos no de una manera que lo restrinja a miembros estáticos. Dentro del contexto de un miembro no estático, selftambién proporciona una forma de evitar el vtable ( ver wiki en vtable ) para el objeto actual. Al igual que puede usar parent::methodName()para llamar a la versión principal de una función, también puede llamar self::methodName()para llamar a la implementación de un método de las clases actuales.
Hola, soy Ludwig el geek
Adiós de Ludwig la persona
sayHello()usa el $thispuntero, por lo que se invoca vtable para llamar Geek::getTitle().
sayGoodbye()utiliza self::getTitle(), por lo que vtable no se utiliza y Person::getTitle()se llama. En ambos casos, estamos tratando con el método de un objeto instanciado y tenemos acceso al $thispuntero dentro de las funciones llamadas.
Esta respuesta sería aún mejor si comenzaras con una regla general en lugar de una excepción. Es una cuestión de estilo, no de experiencia técnica. Este es el mejor ejemplo que he visto de la diferencia entre self :: y $ this->, pero es una pena ocultarlo al refutar primero una noción.
adjwilli
3
@adjwilli: ¿Por qué es ese mal estilo? ¿No aumenta la conciencia si la expectativa (tesis) de la OP se desaprueba primero (antítesis) y luego la explicación se da como síntesis?
Hakre
1
Encuentro "clase actual" realmente problemático. Como esa combinación de palabras puede entenderse como "la clase donde selfse ubica" / "la definición de clase, es una parte literal de" así como "la clase del objeto" (que en realidad sería static).
Jakumi
¿Qué hay de $this::?
James
1
@ James: no hay una buena razón para usar $this::; Todos los casos posibles ya están cubiertos por las sintaxis más utilizadas. Dependiendo de lo que quiere decir, el uso $this->, self::o static::.
ToolmakerSteve
460
NO USE self::, usestatic::
Hay otro aspecto de self :: que vale la pena mencionar. Molestamente se self::refiere al alcance en el punto de definición, no en el punto de ejecución . Considere esta clase simple con dos métodos:
classPerson{publicstaticfunction status(){self::getStatus();}protectedstaticfunction getStatus(){
echo "Person is alive";}}
Si llamamos Person::status()veremos "La persona está viva". Ahora considere lo que sucede cuando hacemos una clase que hereda de esto:
classDeceasedextendsPerson{protectedstaticfunction getStatus(){
echo "Person is deceased";}}
Al llamar Deceased::status(), esperaríamos ver "La persona ha fallecido", sin embargo, lo que vemos es "La persona está viva", ya que el alcance contiene la definición del método original cuando self::getStatus()se definió la llamada a .
PHP 5.3 tiene una solución. el static::operador de resolución implementa "enlace estático tardío", que es una forma elegante de decir que está vinculado al alcance de la clase llamada. Cambie la línea status()a static::getStatus()y los resultados son lo que esperaría. En versiones anteriores de PHP, tendrá que encontrar un kludge para hacer esto.
"Llamando fallecido :: estado () esperaríamos ver" La persona ha fallecido "". No. Esta es una llamada a función estática, por lo que no hay polimorfismo involucrado.
cquezel
2
De todos los defectos de PHP, por mi parte, no creo que esto sea una locura en absoluto. ¿De qué otra forma permitirían a los codificadores designar métodos en la clase actual (en lugar de buscarlos en la tabla)? Si lo hubieran nombrado de manera diferente (tal vez con guiones bajos), las personas que desean esta característica lo criticarían por ser feo. De lo contrario, sea cual sea el nombre sensato que puedan usar, parece que siempre habrá personas fácilmente confundidas que lo criticarán por ser un comportamiento "loco", probablemente ajeno a cómo funciona el envío de métodos.
TNE
2
El ejemplo me parece confuso: veo el getStatusmétodo como uno que llamaría para una instancia de clase, no para una clase.
Jānis Elmeris
1
@Sqoo: decir "NO USE self ::, use static ::" es un punto extraño: esas no son deliberadamente la misma operación. Creo que el punto que realmente está diciendo es "es más claro si usa el nombre de clase real 'MyClass ::', en lugar de 'self ::' . Es decir, si desea el comportamiento de self::, puede obtener eso, menos confusamente, mediante el uso del nombre de clase específico, por ejemplo MyClass::.
ToolmakerSteve
248
Para comprender realmente de qué estamos hablando cuando hablamos de selfversus $this, necesitamos profundizar en lo que sucede a nivel conceptual y práctico. Realmente no siento que ninguna de las respuestas haga esto apropiadamente, así que aquí está mi intento.
Comencemos hablando de qué es una clase y un objeto .
Clases y objetos, conceptualmente
Entonces, ¿qué es una clase ? Mucha gente lo define como un plano o una plantilla para un objeto. De hecho, puede leer más sobre las clases en PHP aquí . Y hasta cierto punto, eso es lo que realmente es. Veamos una clase:
Como puede ver, hay una propiedad en esa clase llamada $namey un método (función) llamado sayHello().
Es muy importante tener en cuenta que la clase es una estructura estática. Lo que significa que la clase Person, una vez definida, siempre es la misma en todas partes donde la miras.
Un objeto por otro lado es lo que se llama una instancia de una Clase. Lo que eso significa es que tomamos el "plano" de la clase y lo usamos para hacer una copia dinámica. Esta copia ahora está vinculada específicamente a la variable en la que está almacenada. Por lo tanto, cualquier cambio en una instancia es local para esa instancia.
$bob =newPerson;
$adam =newPerson;
$bob->name ='Bob';
echo $adam->name;// "my name"
Creamos nuevas instancias de una clase usando el newoperador.
Por lo tanto, decimos que una Clase es una estructura global, y un Objeto es una estructura local. No se preocupe por esa ->sintaxis divertida , vamos a entrar en eso en un momento.
Otra cosa de la que deberíamos hablar es que podemos verificar si una instancia es una instanceofclase particular: lo $bob instanceof Personque devuelve un valor booleano si la $bobinstancia se realizó utilizando la Personclase o un hijo de Person.
Estado definitorio
Así que profundicemos un poco en lo que realmente contiene una clase. Hay 5 tipos de "cosas" que contiene una clase:
Propiedades : piense en ellas como variables que contendrá cada instancia.
classFoo{public $bar =1;}
Propiedades estáticas : piense en estas como variables que se comparten a nivel de clase. Lo que significa que nunca se copian por cada instancia.
classFoo{publicstatic $bar =1;}
Métodos : son funciones que cada instancia contendrá (y operará en instancias).
classFoo{publicfunction bar(){}}
Métodos estáticos : son funciones que se comparten en toda la clase. Ellos no operan en los casos, pero en cambio en las propiedades estáticas solamente.
classFoo{publicstaticfunction bar(){}}
Constantes : constantes resueltas por clase. No profundizando aquí, pero agregando para completar:
classFoo{const BAR =1;}
Básicamente, estamos almacenando información sobre la clase y el contenedor de objetos usando "pistas" sobre estática que identifican si la información es compartida (y por lo tanto estática) o no (y por lo tanto dinámica).
Estado y métodos
Dentro de un método, la instancia representa la instancia de un objeto $this. El estado actual de ese objeto está allí, y la mutación (cambio) de cualquier propiedad dará como resultado un cambio en esa instancia (pero no en otras).
Si un método se llama estáticamente, la $thisvariable no está definida . Esto se debe a que no hay una instancia asociada con una llamada estática.
Lo interesante aquí es cómo se hacen las llamadas estáticas. Entonces, hablemos sobre cómo accedemos al estado:
Estado de acceso
Entonces, ahora que hemos almacenado ese estado, necesitamos acceder a él. Esto puede ser un poco complicado (o mucho más que un poco), así que dividámoslo en dos puntos de vista: desde fuera de una instancia / clase (por ejemplo, desde una llamada de función normal, o desde el alcance global), y dentro de una instancia / class (desde un método en el objeto).
Desde fuera de una instancia / clase
Desde el exterior de una instancia / clase, nuestras reglas son bastante simples y predecibles. Tenemos dos operadores, y cada uno nos dice de inmediato si estamos tratando con una instancia o una clase estática:
->- object-operator : esto siempre se usa cuando accedemos a una instancia.
$bob =newPerson;
echo $bob->name;
Es importante tener en cuenta que llamar Person->foono tiene sentido (ya que Persones una clase, no una instancia). Por lo tanto, eso es un error de análisis.
::- scope-resolution-operator : siempre se usa para acceder a una propiedad o método estático de la Clase.
echo Foo::bar()
Además, podemos llamar a un método estático en un objeto de la misma manera:
echo $foo::bar()
Es extremadamente importante tener en cuenta que cuando hacemos esto desde afuera , la instancia del objeto está oculta del bar()método. Lo que significa que es exactamente lo mismo que correr:
$class = get_class($foo);
$class::bar();
Por lo tanto, $thisno está definido en la llamada estática.
Desde el interior de una instancia / clase
Las cosas cambian un poco aquí. Se utilizan los mismos operadores, pero su significado se vuelve significativamente borroso.
El operador de objeto-> todavía se utiliza para realizar llamadas al estado de instancia del objeto.
La llamada Foo::bar()llamará al baz()método de forma estática y, por $thislo tanto , no se completará. Vale la pena señalar que en versiones recientes de PHP (5.3+) esto provocará un E_STRICTerror, porque estamos llamando a métodos no estáticos estáticamente.
Dentro de un contexto de instancia
Por otro lado, dentro de un contexto de instancia, las llamadas realizadas ::dependen del receptor de la llamada (el método al que estamos llamando). Si el método se define como static, utilizará una llamada estática. Si no es así, reenviará la información de la instancia.
Entonces, mirando el código anterior, la llamada $foo->bar()volverá true, ya que la llamada "estática" ocurre dentro de un contexto de instancia.
¿Tener sentido? No lo creo. Es confuso.
Palabras clave de atajo
Debido a que unir todo usando nombres de clase es bastante sucio, PHP proporciona 3 palabras clave básicas de "acceso directo" para facilitar la resolución del alcance.
self- Esto se refiere al nombre de la clase actual. Entonces self::baz()es lo mismo que Foo::baz()dentro de la Fooclase (cualquier método en él).
parent - Esto se refiere al padre de la clase actual.
static- Esto se refiere a la clase llamada. Gracias a la herencia, las clases secundarias pueden anular métodos y propiedades estáticas. Entonces, llamarlos usando en staticlugar de un nombre de clase nos permite resolver de dónde vino la llamada, en lugar del nivel actual.
Ejemplos
La forma más fácil de entender esto es comenzar a mirar algunos ejemplos. Vamos a elegir una clase:
Ahora, también estamos viendo herencia aquí. Ignora por un momento que este es un modelo de objeto malo, pero veamos qué sucede cuando jugamos con esto:
Por lo tanto, el contador de ID se comparte entre las instancias y los elementos secundarios (porque lo estamos utilizando selfpara acceder a él. Si lo utilizáramos static, podríamos anularlo en una clase secundaria).
var_dump($bob->getName());// Bob
var_dump($adam->getName());// Adam
var_dump($billy->getName());// child: Billy
Tenga en cuenta que estamos ejecutando el método de Person::getName()instancia cada vez. Pero estamos usando el parent::getName()para hacerlo en uno de los casos (el caso secundario). Esto es lo que hace que este enfoque sea poderoso.
Palabra de precaución # 1
Tenga en cuenta que el contexto de llamada es lo que determina si se utiliza una instancia. Por lo tanto:
Ahora es realmente raro aquí. Estamos llamando a una clase diferente, pero la $thisque se pasa al Foo::isFoo()método es la instancia de $bar.
Esto puede causar todo tipo de errores y errores conceptuales de WTF. Así que yo recomiendo evitando el ::operador desde el interior de los métodos de instancia en cualquier cosa excepto aquellas tres palabras clave virtuales "atajo" ( static, selfy parent).
Palabra de precaución # 2
Tenga en cuenta que los métodos y propiedades estáticos son compartidos por todos. Eso los convierte básicamente en variables globales. Con los mismos problemas que vienen con los globales. Por lo tanto, dudaría mucho en almacenar información en métodos / propiedades estáticas a menos que se sienta cómodo con que sea realmente global.
Palabra de precaución # 3
En general, querrá usar lo que se conoce como enlace estático tardío utilizando en staticlugar de self. Pero tenga en cuenta que no son lo mismo, por lo que decir "siempre usar en staticlugar de selfes realmente miope. En cambio, deténgase y piense en la llamada que desea hacer y piense si desea que las clases secundarias puedan anular esa estática resuelta llamada.
TL / DR
Lástima, vuelve y léelo. Puede ser demasiado largo, pero es tan largo porque este es un tema complejo
TL / DR # 2
Está bien. En resumen, selfse utiliza para hacer referencia al nombre de la clase actual dentro de una clase, donde se $thisrefiere a la instancia del objeto actual . Tenga en cuenta que selfes un atajo de copiar / pegar. Puede reemplazarlo con seguridad con el nombre de su clase, y funcionará bien. Pero $thises una variable dinámica que no se puede determinar con anticipación (y puede que ni siquiera sea su clase).
TL / DR # 3
Si se usa el operador de objeto ( ->), siempre sabrá que está tratando con una instancia. Si se utiliza el operador de resolución de alcance ( ::), necesita más información sobre el contexto (¿ya estamos en un contexto de objeto? ¿Estamos fuera de un objeto? Etc.).
Palabra de precaución # 1: $ esto no se definirá al llamar a un método estático: 3v4l.org/9kr0e
Mark Achée
Bueno ... $thisno se definirá si sigue "Estándares estrictos" y no llama a métodos estáticos que no están definidos como estáticos. Veo el resultado que explicaste aquí: 3v4l.org/WeHVM De acuerdo, realmente extraño.
Mark Achée
2
Después de leer la larga descripción por completo, me sentí perezosa al desplazarme hacia arriba nuevamente para votarla. Solo bromeé, lo voté: D. Gracias esto es muy útil.
Mr_Green
3
Sería bueno agregar una explicación clara sobre la diferencia entre self :: $ property y self :: property; Creo que eso también es bastante confuso
Tommaso Barbugli
1
WoC # 1 se comporta de manera diferente desde PHP 7. Como Foo::isFoo()se llama estáticamente, $thisno se definirá. Ese es un comportamiento más intuitivo en mi opinión. - Se da otro resultado diferente si Barse extendiera desde Foo. Entonces la llamada Foo::isFoo()estaría realmente dentro del contexto de la instancia (no específica de PHP7).
Kontrollfreak
117
self(no $ self) se refiere al tipo de clase, donde se $thisrefiere a la instancia actual de la clase. selfse usa en funciones miembro estáticas para permitirle acceder a variables miembro estáticas. $thisse usa en funciones miembro no estáticas y es una referencia a la instancia de la clase en la que se llamó a la función miembro.
Porque thises un objeto, lo usas como:$this->member
Debido a selfque no es un objeto, es básicamente un tipo que se refiere automáticamente a la clase actual, lo usa como:self::member
$this-> se utiliza para referirse a una instancia específica de las variables o métodos de una clase (variables miembro).
Example:
$derek =newPerson();
$ derek ahora es una instancia específica de Person. Cada persona tiene un nombre y un apellido, pero $ derek tiene un nombre y apellido específicos (Derek Martin). Dentro de la instancia $ 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, puede reemplazar mentalmente la palabra "estática" con "compartida". Debido a que son compartidos, 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 única conexión ($ conexión estática).
Ejemplo de variables estáticas: Supongamos
que tenemos una clase de base de datos con una sola 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++;}}
Así como los objetos tienen constructores, también tienen destructores, que se ejecutan cuando el objeto muere o se desarma:
function __destruct(){
$num_connections--;}
Cada vez que creamos una nueva instancia, aumentará nuestro contador de conexión en uno. Cada vez que destruimos o dejamos de usar una instancia, disminuirá el contador de conexión en uno. De esta manera, podemos monitorear el número de instancias del objeto de base de datos que tenemos en uso con:
echo DB::num_connections;
Como $ 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 bases 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, vista estática pública :: formato_número_de_teléfono ($ dígitos)) se pueden usar SIN primero instanciar uno de esos objetos (es decir, no se refieren internamente a $ this).
Como puede ver, la función estática pública prettyName no sabe nada sobre el objeto. Simplemente está trabajando con los parámetros que pasa, como una función normal que no es parte de un objeto. ¿Por qué molestarse, entonces, si no podríamos tenerlo como parte del objeto?
Primero, adjuntar funciones a los objetos lo ayuda a mantener las cosas organizadas, para que sepa dónde encontrarlas.
En segundo lugar, evita conflictos de nombres. En un gran proyecto, 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 en el interior del objeto que tiene el método estático que desea hacer referencia a, puede o bien utilizar el nombre Vista :: format_phone_number del objeto ($ pn), o puede utilizar el mismo :: format_phone_number ($ pn) de acceso directo
Lo mismo ocurre con las variables estáticas:
Ejemplo: View :: templates_path versus self :: templates_path
Dentro de la clase DB, si nos referiéramos 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;
En PHP, utiliza la palabra clave self para acceder a propiedades y métodos estáticos.
El problema es que puede reemplazarlo $this->method()en self::method()cualquier lugar, independientemente de si method()se declara estático o no. Entonces, ¿cuál deberías usar?
Considera este código:
classParentClass{function test(){self::who();// will output 'parent'
$this->who();// will output 'child'}function who(){
echo 'parent';}}classChildClassextendsParentClass{function who(){
echo 'child';}}
$obj =newChildClass();
$obj->test();
En este ejemplo, self::who()siempre generará 'padre', mientras $this->who()que dependerá de qué clase tenga el objeto.
Ahora podemos ver que self se refiere a la clase en la que se llama, mientras que se $thisrefiere a la clase del objeto actual .
Por lo tanto, debe usar self solo cuando $thisno esté disponible o cuando no desee permitir que las clases descendientes sobrescriban el método actual.
De acuerdo con http://www.php.net/manual/en/language.oop5.static.php no hay $self. Solo existe $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. Aquí entra en juego la diferencia entre una instancia de objeto y una clase.
Sugerencia: Lea esta respuesta al tropezar con ácido.
a20
16
Creo que la pregunta no era si se puede llamar al miembro estático de la clase llamando ClassName::staticMember. La pregunta era cuál es la diferencia entre usar self::classmembery $this->classmember.
Por ejemplo, los dos ejemplos siguientes funcionan sin ningún error, ya sea que use self::o$this->
Es especialmente divertido que comiences tu respuesta con "Creo que la pregunta no era si puedes 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" y luego procedes a no mostrar ninguna diferencia. De hecho, muestra una instancia de donde las dos opciones funcionan de manera idéntica. -1
Buttle Butkus
Sin embargo útil. El alcance era sobre la resolución y esta parte no está clara en el manual de php. Todavía lo encuentro útil
renoirb el
2
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
K-Gun
16
self hace referencia a la clase actual (en la que se llama),
$thisse refiere al objeto actual. Puedes usar static en lugar de self. Mira el ejemplo:
El puntero del objeto se $thisrefiere al objeto actual.
El valor de la clase se staticrefiere al objeto actual.
El valor selfde la clase se refiere a la clase exacta en la que se definió.
El valor de la clase se parentrefiere al padre de la clase exacta en la que se definió.
Vea el siguiente ejemplo que muestra sobrecarga.
<?php
class A {publicstaticfunction newStaticClass(){returnnewstatic;}publicstaticfunction newSelfClass(){returnnewself;}publicfunction newThisClass(){returnnew $this;}}class B extends A
{publicfunction newParentClass(){returnnew 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());// Aclass C extends B
{publicstaticfunction newSelfClass(){returnnewself;}}
$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 eso utiliza statico $this. Sin embargo, hay momentos en los que necesitaself porque desea la clase original independientemente de lo que la extienda. (Muy, muy raramente)
Esos son los resultados de 2 000 000 ejecuciones, y aquí está el código que utilicé:
<?php
require'../vendor/autoload.php';// My small class to do benchmarks// All it does is looping over every test x times and record the// time it takes using `microtime(true)`// Then, the percentage is calculated, with 100% being the quickest// Times are being rouned for outputting only, not to calculate the percentages
$b =newTleb\Benchmark\Benchmark(2000000);classFoo{publicfunction calling_this(){
$this->called();}publicfunction calling_self(){self::called();}publicfunction calling_static(){static::called();}publicstaticfunction called(){}}
$b->add('$this->',function(){ $foo =newFoo; $foo->calling_this();});
$b->add('self::',function(){ $foo =newFoo; $foo->calling_self();});
$b->add('static::',function(){ $foo =newFoo; $foo->calling_static();});
$b->run();
Llamar a la función no operativa 2 000 000 veces dura 1 s. Tengo que amar PHP.
rr-
Buen viejo PHP. :) Pero una llamada = 0.001ms. ¿Es tan malo?
Tleb
Creo que esto (y otras cosas similares) es la razón por la cual las cosas como ORM se sienten lentas a menos que almacene cosas en caché, y los generadores de sitios estáticos son una cosa.
rr-
2
Teóricamente debería tomar 1 ciclo de reloj del procesador, lo que hace alrededor de 1 / 2e9 s = 0.5 nsestos días
Buddy
Solo vuelve a leer mi respuesta. Tenga cuidado: también crea la clase . No sé por qué no useusé la palabra clave tbh, pero ya no tengo PHP para rehacer un punto de referencia, y realmente no tengo ganas de reinstalarlo.
tleb
13
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 mismo. Además, es perfectamente legal usarlo $thispara llamar a métodos estáticos (pero no para referirse a los campos).
Me encontré con la misma pregunta y la respuesta simple es:
$this requiere una instancia de la clase
self:: no lo hace
Siempre que esté utilizando métodos estáticos o atributos estáticos y desee llamarlos sin tener un objeto de la clase instanciado, debe usarlos self:para llamarlos, porque $thissiempre requiere la creación de un objeto.
$this se refiere al objeto de clase actual, self refiere a la clase actual (No objeto). La clase es el plano del objeto. Entonces define una clase, pero construye objetos.
En otras palabras, use self for staticythis for none-static members or methods .
también en el escenario hijo / padre self / parentse usa principalmente para identificar miembros y métodos de clase padre e hijo.
Solo con fines informativos, a partir de PHP 5.3 cuando se trata de objetos instanciados para obtener el valor de alcance actual, en lugar de usar static::, uno puede usar alternativamente $this::así.
classFoo{const NAME ='Foo';//Always Foo::NAME (Foo) due to selfprotectedstatic $staticName =self::NAME;publicfunction __construct(){
echo $this::NAME;}publicfunction getStaticName(){
echo $this::$staticName;}}classBarextendsFoo{const NAME ='FooBar';/**
* override getStaticName to output Bar::NAME
*/publicfunction getStaticName(){
$this::$staticName = $this::NAME;
parent::getStaticName();}}
$foo =newFoo;//outputs Foo
$bar =newBar;//outputs FooBar
$foo->getStaticName();//outputs Foo
$bar->getStaticName();//outputs FooBar
$foo->getStaticName();//outputs FooBar
El uso del código anterior no es una práctica común o recomendada, pero es simplemente para ilustrar su uso, y es actuar más como un "¿Sabía que?" en referencia a la pregunta del póster original.
También representa el uso de, $object::CONSTANTpor ejemplo echo $foo::NAME;, en lugar de$this::NAME;
Úselo selfsi desea llamar a un método de una clase sin crear un objeto / instancia de esa clase, ahorrando así RAM (a veces use self para ese propósito). En otras palabras, en realidad está llamando a un método estáticamente. Uso thispara la perspectiva del objeto.
De acuerdo con php.net hay tres palabras clave especiales en este contexto: self, parenty static. Se utilizan para acceder a propiedades o métodos desde dentro de la definición de clase.
$this, por otro lado, se usa para llamar a una instancia y métodos de cualquier clase siempre que esa clase sea accesible.
self :: palabra clave utilizada para la clase actual y, básicamente, se utiliza para acceder a miembros estáticos, métodos y constantes. Pero en el caso de $ this no puede llamar al miembro estático, método y funciones.
Puede usar la palabra clave self :: en otra clase y acceder a los miembros estáticos, el método y las constantes. Cuándo se extenderá desde la clase padre e igual en el caso de $ this palabra clave. Puede acceder a los miembros no estáticos, el método y la función en otra clase cuando se extenderá desde la clase principal.
El código que figura a continuación es un ejemplo de self :: y $ this palabra clave. Simplemente copie y pegue el código en su archivo de código y vea el resultado.
class cars{var $doors=4;static $car_wheel=4;publicfunction car_features(){
echo $this->doors." Doors <br>";
echo self::$car_wheel." Wheels <br>";}}class spec extends cars{function car_spec(){print(self::$car_wheel." Doors <br>");print($this->doors." Wheels <br>");}}/********Parent class output*********/
$car =new cars;
print_r($car->car_features());
echo "------------------------<br>";/********Extend class from another class output**********/
$car_spec_show=new spec;print($car_spec_show->car_spec());
Respuestas:
Respuesta corta
Respuesta completa
Aquí hay un ejemplo del uso correcto de
$this
yself
para variables miembro no estáticas y estáticas:Aquí hay un ejemplo de uso incorrecto de
$this
yself
para variables miembro no estáticas y estáticas:Aquí hay un ejemplo de polimorfismo con
$this
funciones miembro:Aquí hay un ejemplo de supresión del comportamiento polimórfico mediante el uso
self
de funciones miembro:De http://www.phpbuilder.com/board/showthread.php?t=10354489 :
Por http://board.phpbuilder.com/member.php?145249-laserlight
fuente
self
se usa con el operador de resolución de alcance::
para referirse a la clase actual; Esto se puede hacer tanto en contextos estáticos como no estáticos. Además, es perfectamente legal usarlo$this
para llamar a métodos estáticos (pero no para hacer referencia a campos).$this::
?La palabra clave self NO se refiere simplemente a la 'clase actual', al menos no de una manera que lo restrinja a miembros estáticos. Dentro del contexto de un miembro no estático,
self
también proporciona una forma de evitar el vtable ( ver wiki en vtable ) para el objeto actual. Al igual que puede usarparent::methodName()
para llamar a la versión principal de una función, también puede llamarself::methodName()
para llamar a la implementación de un método de las clases actuales.Esto generará:
sayHello()
usa el$this
puntero, por lo que se invoca vtable para llamarGeek::getTitle()
.sayGoodbye()
utilizaself::getTitle()
, por lo que vtable no se utiliza yPerson::getTitle()
se llama. En ambos casos, estamos tratando con el método de un objeto instanciado y tenemos acceso al$this
puntero dentro de las funciones llamadas.fuente
self
se ubica" / "la definición de clase, es una parte literal de" así como "la clase del objeto" (que en realidad seríastatic
).$this::
?$this::
; Todos los casos posibles ya están cubiertos por las sintaxis más utilizadas. Dependiendo de lo que quiere decir, el uso$this->
,self::
ostatic::
.NO USE
self::
, usestatic::
Hay otro aspecto de self :: que vale la pena mencionar. Molestamente se
self::
refiere al alcance en el punto de definición, no en el punto de ejecución . Considere esta clase simple con dos métodos:Si llamamos
Person::status()
veremos "La persona está viva". Ahora considere lo que sucede cuando hacemos una clase que hereda de esto:Al llamar
Deceased::status()
, esperaríamos ver "La persona ha fallecido", sin embargo, lo que vemos es "La persona está viva", ya que el alcance contiene la definición del método original cuandoself::getStatus()
se definió la llamada a .PHP 5.3 tiene una solución. el
static::
operador de resolución implementa "enlace estático tardío", que es una forma elegante de decir que está vinculado al alcance de la clase llamada. Cambie la líneastatus()
astatic::getStatus()
y los resultados son lo que esperaría. En versiones anteriores de PHP, tendrá que encontrar un kludge para hacer esto.Ver documentación de PHP
Entonces, para responder la pregunta no como se le preguntó ...
$this->
se refiere al objeto actual (una instancia de una clase), mientras que sestatic::
refiere a una clasefuente
getStatus
método como uno que llamaría para una instancia de clase, no para una clase.self::
, puede obtener eso, menos confusamente, mediante el uso del nombre de clase específico, por ejemploMyClass::
.Para comprender realmente de qué estamos hablando cuando hablamos de
self
versus$this
, necesitamos profundizar en lo que sucede a nivel conceptual y práctico. Realmente no siento que ninguna de las respuestas haga esto apropiadamente, así que aquí está mi intento.Comencemos hablando de qué es una clase y un objeto .
Clases y objetos, conceptualmente
Entonces, ¿qué es una clase ? Mucha gente lo define como un plano o una plantilla para un objeto. De hecho, puede leer más sobre las clases en PHP aquí . Y hasta cierto punto, eso es lo que realmente es. Veamos una clase:
Como puede ver, hay una propiedad en esa clase llamada
$name
y un método (función) llamadosayHello()
.Es muy importante tener en cuenta que la clase es una estructura estática. Lo que significa que la clase
Person
, una vez definida, siempre es la misma en todas partes donde la miras.Un objeto por otro lado es lo que se llama una instancia de una Clase. Lo que eso significa es que tomamos el "plano" de la clase y lo usamos para hacer una copia dinámica. Esta copia ahora está vinculada específicamente a la variable en la que está almacenada. Por lo tanto, cualquier cambio en una instancia es local para esa instancia.
Creamos nuevas instancias de una clase usando el
new
operador.Por lo tanto, decimos que una Clase es una estructura global, y un Objeto es una estructura local. No se preocupe por esa
->
sintaxis divertida , vamos a entrar en eso en un momento.Otra cosa de la que deberíamos hablar es que podemos verificar si una instancia es una
instanceof
clase particular: lo$bob instanceof Person
que devuelve un valor booleano si la$bob
instancia se realizó utilizando laPerson
clase o un hijo dePerson
.Estado definitorio
Así que profundicemos un poco en lo que realmente contiene una clase. Hay 5 tipos de "cosas" que contiene una clase:
Propiedades : piense en ellas como variables que contendrá cada instancia.
Propiedades estáticas : piense en estas como variables que se comparten a nivel de clase. Lo que significa que nunca se copian por cada instancia.
Métodos : son funciones que cada instancia contendrá (y operará en instancias).
Métodos estáticos : son funciones que se comparten en toda la clase. Ellos no operan en los casos, pero en cambio en las propiedades estáticas solamente.
Constantes : constantes resueltas por clase. No profundizando aquí, pero agregando para completar:
Básicamente, estamos almacenando información sobre la clase y el contenedor de objetos usando "pistas" sobre estática que identifican si la información es compartida (y por lo tanto estática) o no (y por lo tanto dinámica).
Estado y métodos
Dentro de un método, la instancia representa la instancia de un objeto
$this
. El estado actual de ese objeto está allí, y la mutación (cambio) de cualquier propiedad dará como resultado un cambio en esa instancia (pero no en otras).Si un método se llama estáticamente, la
$this
variable no está definida . Esto se debe a que no hay una instancia asociada con una llamada estática.Lo interesante aquí es cómo se hacen las llamadas estáticas. Entonces, hablemos sobre cómo accedemos al estado:
Estado de acceso
Entonces, ahora que hemos almacenado ese estado, necesitamos acceder a él. Esto puede ser un poco complicado (o mucho más que un poco), así que dividámoslo en dos puntos de vista: desde fuera de una instancia / clase (por ejemplo, desde una llamada de función normal, o desde el alcance global), y dentro de una instancia / class (desde un método en el objeto).
Desde fuera de una instancia / clase
Desde el exterior de una instancia / clase, nuestras reglas son bastante simples y predecibles. Tenemos dos operadores, y cada uno nos dice de inmediato si estamos tratando con una instancia o una clase estática:
->
- object-operator : esto siempre se usa cuando accedemos a una instancia.Es importante tener en cuenta que llamar
Person->foo
no tiene sentido (ya quePerson
es una clase, no una instancia). Por lo tanto, eso es un error de análisis.::
- scope-resolution-operator : siempre se usa para acceder a una propiedad o método estático de la Clase.Además, podemos llamar a un método estático en un objeto de la misma manera:
Es extremadamente importante tener en cuenta que cuando hacemos esto desde afuera , la instancia del objeto está oculta del
bar()
método. Lo que significa que es exactamente lo mismo que correr:Por lo tanto,
$this
no está definido en la llamada estática.Desde el interior de una instancia / clase
Las cosas cambian un poco aquí. Se utilizan los mismos operadores, pero su significado se vuelve significativamente borroso.
El operador de objeto
->
todavía se utiliza para realizar llamadas al estado de instancia del objeto.Llamar al
bar()
método en$foo
(una instancia deFoo
) utilizando el operador de objeto:$foo->bar()
dará como resultado la versión de la instancia de$a
.Así es como esperamos.
::
Aunque el significado del operador cambia. Depende del contexto de la llamada a la función actual:Dentro de un contexto estático
Dentro de un contexto estático, cualquier llamada realizada con
::
también será estática. Veamos un ejemplo:La llamada
Foo::bar()
llamará albaz()
método de forma estática y, por$this
lo tanto , no se completará. Vale la pena señalar que en versiones recientes de PHP (5.3+) esto provocará unE_STRICT
error, porque estamos llamando a métodos no estáticos estáticamente.Dentro de un contexto de instancia
Por otro lado, dentro de un contexto de instancia, las llamadas realizadas
::
dependen del receptor de la llamada (el método al que estamos llamando). Si el método se define comostatic
, utilizará una llamada estática. Si no es así, reenviará la información de la instancia.Entonces, mirando el código anterior, la llamada
$foo->bar()
volverátrue
, ya que la llamada "estática" ocurre dentro de un contexto de instancia.¿Tener sentido? No lo creo. Es confuso.
Palabras clave de atajo
Debido a que unir todo usando nombres de clase es bastante sucio, PHP proporciona 3 palabras clave básicas de "acceso directo" para facilitar la resolución del alcance.
self
- Esto se refiere al nombre de la clase actual. Entoncesself::baz()
es lo mismo queFoo::baz()
dentro de laFoo
clase (cualquier método en él).parent
- Esto se refiere al padre de la clase actual.static
- Esto se refiere a la clase llamada. Gracias a la herencia, las clases secundarias pueden anular métodos y propiedades estáticas. Entonces, llamarlos usando enstatic
lugar de un nombre de clase nos permite resolver de dónde vino la llamada, en lugar del nivel actual.Ejemplos
La forma más fácil de entender esto es comenzar a mirar algunos ejemplos. Vamos a elegir una clase:
Ahora, también estamos viendo herencia aquí. Ignora por un momento que este es un modelo de objeto malo, pero veamos qué sucede cuando jugamos con esto:
Por lo tanto, el contador de ID se comparte entre las instancias y los elementos secundarios (porque lo estamos utilizando
self
para acceder a él. Si lo utilizáramosstatic
, podríamos anularlo en una clase secundaria).Tenga en cuenta que estamos ejecutando el método de
Person::getName()
instancia cada vez. Pero estamos usando elparent::getName()
para hacerlo en uno de los casos (el caso secundario). Esto es lo que hace que este enfoque sea poderoso.Palabra de precaución # 1
Tenga en cuenta que el contexto de llamada es lo que determina si se utiliza una instancia. Por lo tanto:
No siempre es verdad.
Ahora es realmente raro aquí. Estamos llamando a una clase diferente, pero la
$this
que se pasa alFoo::isFoo()
método es la instancia de$bar
.Esto puede causar todo tipo de errores y errores conceptuales de WTF. Así que yo recomiendo evitando el
::
operador desde el interior de los métodos de instancia en cualquier cosa excepto aquellas tres palabras clave virtuales "atajo" (static
,self
yparent
).Palabra de precaución # 2
Tenga en cuenta que los métodos y propiedades estáticos son compartidos por todos. Eso los convierte básicamente en variables globales. Con los mismos problemas que vienen con los globales. Por lo tanto, dudaría mucho en almacenar información en métodos / propiedades estáticas a menos que se sienta cómodo con que sea realmente global.
Palabra de precaución # 3
En general, querrá usar lo que se conoce como enlace estático tardío utilizando en
static
lugar deself
. Pero tenga en cuenta que no son lo mismo, por lo que decir "siempre usar enstatic
lugar deself
es realmente miope. En cambio, deténgase y piense en la llamada que desea hacer y piense si desea que las clases secundarias puedan anular esa estática resuelta llamada.TL / DR
Lástima, vuelve y léelo. Puede ser demasiado largo, pero es tan largo porque este es un tema complejo
TL / DR # 2
Está bien. En resumen,
self
se utiliza para hacer referencia al nombre de la clase actual dentro de una clase, donde se$this
refiere a la instancia del objeto actual . Tenga en cuenta queself
es un atajo de copiar / pegar. Puede reemplazarlo con seguridad con el nombre de su clase, y funcionará bien. Pero$this
es una variable dinámica que no se puede determinar con anticipación (y puede que ni siquiera sea su clase).TL / DR # 3
Si se usa el operador de objeto (
->
), siempre sabrá que está tratando con una instancia. Si se utiliza el operador de resolución de alcance (::
), necesita más información sobre el contexto (¿ya estamos en un contexto de objeto? ¿Estamos fuera de un objeto? Etc.).fuente
$this
no se definirá si sigue "Estándares estrictos" y no llama a métodos estáticos que no están definidos como estáticos. Veo el resultado que explicaste aquí: 3v4l.org/WeHVM De acuerdo, realmente extraño.Foo::isFoo()
se llama estáticamente,$this
no se definirá. Ese es un comportamiento más intuitivo en mi opinión. - Se da otro resultado diferente siBar
se extendiera desdeFoo
. Entonces la llamadaFoo::isFoo()
estaría realmente dentro del contexto de la instancia (no específica de PHP7).self
(no $ self) se refiere al tipo de clase, donde se$this
refiere a la instancia actual de la clase.self
se usa 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ó a la función miembro.Porque
this
es un objeto, lo usas como:$this->member
Debido a
self
que no es un objeto, es básicamente un tipo que se refiere automáticamente a la clase actual, lo usa como:self::member
fuente
$this->
se utiliza para referirse a una instancia específica de las variables o métodos de una clase (variables miembro).$ derek ahora es una instancia específica de Person. Cada persona tiene un nombre y un apellido, pero $ derek tiene un nombre y apellido específicos (Derek Martin). Dentro de la instancia $ 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, puede reemplazar mentalmente la palabra "estática" con "compartida". Debido a que son compartidos, 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 única conexión ($ conexión estática).
Ejemplo de variables estáticas: Supongamos que tenemos una clase de base de datos con una sola variable miembro: static $ num_ connections; Ahora, pon esto en el constructor:
Así como los objetos tienen constructores, también tienen destructores, que se ejecutan cuando el objeto muere o se desarma:
Cada vez que creamos una nueva instancia, aumentará nuestro contador de conexión en uno. Cada vez que destruimos o dejamos de usar una instancia, disminuirá el contador de conexión en uno. De esta manera, podemos monitorear el número de instancias del objeto de base de datos que tenemos en uso con:
Como $ 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 bases 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, vista estática pública :: formato_número_de_teléfono ($ dígitos)) se pueden usar SIN primero instanciar uno de esos objetos (es decir, no se refieren internamente a $ this).
Ejemplo de método estático:
Como puede ver, la función estática pública prettyName no sabe nada sobre el objeto. Simplemente está trabajando con los parámetros que pasa, como una función normal que no es parte de un objeto. ¿Por qué molestarse, entonces, si no podríamos tenerlo como parte del objeto?
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 en el interior del objeto que tiene el método estático que desea hacer referencia a, puede o bien utilizar el nombre Vista :: format_phone_number del objeto ($ pn), o puede utilizar el mismo :: format_phone_number ($ pn) de acceso directo
Lo mismo ocurre con las variables estáticas: Ejemplo: View :: templates_path versus self :: templates_path
Dentro de la clase DB, si nos referiéramos 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 :)
fuente
$
signo. Por ejemploself::$templates_path
De esta publicación de blog :
fuente
En PHP, utiliza la palabra clave self para acceder a propiedades y métodos estáticos.
El problema es que puede reemplazarlo
$this->method()
enself::method()
cualquier lugar, independientemente de simethod()
se declara estático o no. Entonces, ¿cuál deberías usar?Considera este código:
En este ejemplo,
self::who()
siempre generará 'padre', mientras$this->who()
que dependerá de qué clase tenga el objeto.Ahora podemos ver que self se refiere a la clase en la que se llama, mientras que se
$this
refiere a la clase del objeto actual .Por lo tanto, debe usar self solo cuando
$this
no esté disponible o cuando no desee permitir que las clases descendientes sobrescriban el método actual.fuente
Dentro de una definición de clase, se
$this
refiere al objeto actual, mientras que seself
refiere a la clase actual.Es necesario hacer referencia a un elemento de clase usando
self
, y hacer referencia a un elemento de objeto usando$this
.fuente
fuente
De acuerdo con http://www.php.net/manual/en/language.oop5.static.php no hay
$self
. Solo existe$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. Aquí entra en juego la diferencia entre una instancia de objeto y una clase.fuente
Creo que la pregunta no era si se puede llamar al miembro estático de la clase llamando
ClassName::staticMember
. La pregunta era cuál es la diferencia entre usarself::classmember
y$this->classmember
.Por ejemplo, los dos ejemplos siguientes funcionan sin ningún error, ya sea que use
self::
o$this->
fuente
Fatal error: Access to undeclared static property: Person::$name in D:\LAMP\www\test.php on line 16
self
hace referencia a la clase actual (en la que se llama),$this
se refiere al objeto actual. Puedes usar static en lugar de self. Mira el ejemplo:Salida: padre hijo
fuente
$this
refiere al objeto actual.static
refiere al objeto actual.self
de la clase se refiere a la clase exacta en la que se definió.parent
refiere al padre de la clase exacta en la que se definió.Vea el siguiente ejemplo que muestra sobrecarga.
La mayoría de las veces desea referirse a la clase actual, por eso utiliza
static
o$this
. Sin embargo, hay momentos en los que necesitaself
porque desea la clase original independientemente de lo que la extienda. (Muy, muy raramente)fuente
Como nadie aquí habló de actuaciones, aquí hay un pequeño punto de referencia que hice (5.6):
Esos son los resultados de 2 000 000 ejecuciones, y aquí está el código que utilicé:
fuente
1 / 2e9 s = 0.5 ns
estos díasuse
usé la palabra clave tbh, pero ya no tengo PHP para rehacer un punto de referencia, y realmente no tengo ganas de reinstalarlo.Cuando
self
se usa con el::
operador, se refiere a la clase actual, que se puede hacer tanto en contextos estáticos como no estáticos.$this
se refiere al objeto mismo. Además, es perfectamente legal usarlo$this
para llamar a métodos estáticos (pero no para referirse a los campos).fuente
Me encontré con la misma pregunta y la respuesta simple es:
$this
requiere una instancia de la claseself::
no lo haceSiempre que esté utilizando métodos estáticos o atributos estáticos y desee llamarlos sin tener un objeto de la clase instanciado, debe usarlos
self:
para llamarlos, porque$this
siempre requiere la creación de un objeto.fuente
$this
se refiere al objeto de clase actual,self
refiere a la clase actual (No objeto). La clase es el plano del objeto. Entonces define una clase, pero construye objetos.En otras palabras, use
self for static
ythis for none-static members or methods
.también en el escenario hijo / padre
self / parent
se usa principalmente para identificar miembros y métodos de clase padre e hijo.fuente
Además ya
$this::
no se ha discutido todavía.Solo con fines informativos, a partir de PHP 5.3 cuando se trata de objetos instanciados para obtener el valor de alcance actual, en lugar de usar
static::
, uno puede usar alternativamente$this::
así.http://ideone.com/7etRHy
El uso del código anterior no es una práctica común o recomendada, pero es simplemente para ilustrar su uso, y es actuar más como un "¿Sabía que?" en referencia a la pregunta del póster original.
También representa el uso de,
$object::CONSTANT
por ejemploecho $foo::NAME;
, en lugar de$this::NAME;
fuente
Úselo
self
si desea llamar a un método de una clase sin crear un objeto / instancia de esa clase, ahorrando así RAM (a veces use self para ese propósito). En otras palabras, en realidad está llamando a un método estáticamente. Usothis
para la perspectiva del objeto.fuente
Caso 1: El uso
self
se puede usar para constantes de claseSi desea llamarlo fuera de la clase, use
classA::POUNDS_TO_KILOGRAMS
para acceder a las constantesCaso 2: para propiedades estáticas
fuente
De acuerdo con php.net hay tres palabras clave especiales en este contexto:
self
,parent
ystatic
. Se utilizan para acceder a propiedades o métodos desde dentro de la definición de clase.$this
, por otro lado, se usa para llamar a una instancia y métodos de cualquier clase siempre que esa clase sea accesible.fuente
self :: palabra clave utilizada para la clase actual y, básicamente, se utiliza para acceder a miembros estáticos, métodos y constantes. Pero en el caso de $ this no puede llamar al miembro estático, método y funciones.
Puede usar la palabra clave self :: en otra clase y acceder a los miembros estáticos, el método y las constantes. Cuándo se extenderá desde la clase padre e igual en el caso de $ this palabra clave. Puede acceder a los miembros no estáticos, el método y la función en otra clase cuando se extenderá desde la clase principal.
El código que figura a continuación es un ejemplo de self :: y $ this palabra clave. Simplemente copie y pegue el código en su archivo de código y vea el resultado.
fuente