PHP Velho Oeste 2024

class

Una clase es una colección de variables y funciones que trabajan con estas variables. Las variables se definen utilizando var y las funciones utilizando function. Una clase se define empleando la siguiente sintáxis:

<?php
class Cart {
    var 
$items;  // Objetos en nuestro carrito de compras

    // Agregar $num artículos de $artnr al carrito

    
function add_item($artnr$num) {
        
$this->items[$artnr] += $num;
    }

    
// Sacar $num artículos de $artnr fuera del carrito

    
function remove_item($artnr$num) {
        if (
$this->items[$artnr] > $num) {
            
$this->items[$artnr] -= $num;
            return 
true;
        } elseif (
$this->items[$artnr] == $num) {
            unset(
$this->items[$artnr]);
            return 
true;
        } else {
            return 
false;
        }
    }
}
?>

Esto define una clase llamada Cart que consiste de una matriz asociativa de artículos en el carrito y dos funciones para agregar y quitar elementos de este carrito.

Advertencia

NO se puede separar una definición de clase en múltiples ficheros. Tampoco es posible separar una definición de clase en múltiples bloques PHP, a menos que la división sea dentro de una declaración de método. Lo siguiente no funcionará:

<?php
class test {
?>
<?php
    
function test() {
        print 
'OK';
    }
}
?>

Sin embargo, lo siguiente es permitido:

<?php
class test {
    function 
test() {
        
?>
        <?php
        
print 'OK';
    }
}
?>

Las siguientes notas de precaución son válidas para PHP 4.

Precaución

El nombre stdClass es usado internamente por Zend y está reservado. No es posible tener una clase llamada stdClass en PHP.

Precaución

Los nombres de función __sleep y __wakeup son mágicos en las clases de PHP. No se puede tener funciones con estos nombres en ninguna clase a menos que se desee la funcionalidad mágica asociada con ellas. Ver abajo para más información.

Precaución

PHP reserva todos los nombres de función que empiezan con __ como mágicos. Se recomienda que no se utilicen nombres de función con __ en PHP a menos que se quiera alguna funcionalidad mágica que esté documentada.

En PHP 4, para variables var solamente se permiten inicializadores constantes. Para inicializar variables con valores no constantes, se requiere una función de inicialización que es invocada automáticamente cuando un objeto se está construyendo a partir de la clase. Tal función es llamada un constructor (ver más abajo).

<?php
class Cart {
    
/* Ninguno de estos funcionará en PHP 4. */
    
var $todays_date date("Y-m-d");
    var 
$name $firstname;
    var 
$owner 'Fred ' 'Jones';
    
/* Pero matrices que contengan valores constantes, si lo harán. */
    
var $items = array("VCR""TV");
}

/* Esta es la manera en que debería hacerse. */
class Cart {
    var 
$todays_date;
    var 
$name;
    var 
$owner;
    var 
$items = array("VCR""TV");

    function 
Cart() {
        
$this->todays_date date("Y-m-d");
        
$this->name $GLOBALS['firstname'];
        
/* etc. . . */
    
}
}
?>

Las clases son tipos, es decir, son planos para las variables de verdad. Se tiene que crear una variable del tipo deseado con el operador new.

<?php
$cart 
= new Cart;
$cart->add_item("10"1);

$another_cart = new Cart;
$another_cart->add_item("0815"3);
?>

Esto crea los objetos $cart y $another_cart, ambos de la clase Cart. La función add_item() del objeto $cart es invocada para agregar 1 elemento del artículo 10 a $cart. 3 elementos del artículo número 0815 son agregados a $another_cart.

Ambos, $cart y $another_cart, tienen las funciones add_item(), remove_item() y una variable items. Estas son funciones y variables distintas. Se puede pensar en los objetos como algo semejante a directorios en un sistema de ficheros. En un sistema de ficheros se pueden tener dos diferentes ficheros llamados README.TXT, siempre y cuando éstos, estén en directorios distintos. Tal como con los directorios donde se tiene que teclear la trayectoria de nombre completa para poder alcanzar cada fichero desde el directorio de nivel máximo, se tiene que especificar el nombre completo de la función que se desea invocar: en términos de PHP, el directorio de nivel máximo sería el espacio de nombres global, y el separador en las trayectorias de nombre sería ->. Así, los nombres $cart->items y $another_cart->items nombran a dos variables distintas. Nótese que la variable se llama $cart->items, y no $cart->$items, es decir, un nombre de variable en PHP tiene únicamente un sólo signo de dólar ($).

<?php
// correcto, solamente un $
$cart->items = array("10" => 1);

// inválido, porque $cart->$items se vuelve $cart->""
$cart->$items = array("10" => 1);

// correcto, pero podría ser o no lo que se pretendía:
// $cart->$myvar se vuelve $cart->items
$myvar 'items';
$cart->$myvar = array("10" => 1);  
?>

Dentro de una definición de clase, no se conoce bajo que nombre el objeto será accesible dentro del programa: al momento en que la clase Cart fue escrita, se desconocía si el objeto sería nombrado $cart, $another_cart, o algo distinto posteriormente. Siendo así, no se puede escribir $cart->items dentro de la clase Cart propiamente. En cambio, para ser capáz de acceder a sus propias funciones y variables desde el interior de una clase, es posible utilizar la pseudovariable $this que puede ser leída como 'lo mío' u 'objeto actual'. Así, '$this->items[$artnr] += $num' puede leerse como 'agregar $num al contador $artnr de mi propia matriz de artículos' o 'agregar $num al contador $artnr de la matriz de artículos dentro del objeto actual'.

Nota:

La pseudovariable $this normalmente no está definida si el método en el que se encuentra alojada es invocado de manera estática. Pero, ésta, no es una regla estricta: $this está definida si un método es invocado estáticamente desde el interior de otro objeto. En este caso, el valor de $this será aquel del objeto que realiza la invocación. Esto se ilustra en el siguiente ejemplo:

<?php
class A
{
    function 
foo()
    {
        if (isset(
$this)) {
            echo 
'$this is defined (';
            echo 
get_class($this);
            echo 
")\n";
        } else {
            echo 
"\$this is not defined.\n";
        }
    }
}

class 
B
{
    function 
bar()
    {
        
A::foo();
    }
}

$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>

El resultado del ejemplo sería:

$this is defined (a)
$this is not defined.
$this is defined (b)
$this is not defined.

Nota:

Existen algunas funciones apropiadas para manejar clases y objetos. Quizas se quiera echar un vistazo al las Funciones Clase/Objeto.

add a note add a note

User Contributed Notes 5 notes

up
7
ender911t at gmail dot com
8 years ago
Overrides in child are called when calling a function from the parent

<?PHP
class Par
{
   var
$test;
   function
__construct($in)
   {
     
$this->test = $in;
   }

   function
getTest()
   {
      return
$this->test;
   }

   function
runTest()
   {
      return
$this->getTest();
   }
}

class
Chi extends Par
{
   var
$i;
   function
__construct($in)
   {
     
$this->i = $in;
     
parent::__construct($in."X");
   }

   function
getTest()
   {
      return
$this->i;
   }

   function
runParentTestA()
   {
      return
parent::runTest();
   }

   function
runParentTestB()
   {
      return
parent::getTest();
   }
}

$p = new Par("par");
$c = new Chi("chi");

echo
$p->runTest()." == par";
echo
$c->runTest()." == chi";
echo
$c->runParentTestA()." == chi";
echo
$c->runParentTestB()." == chiX";
?>
up
5
anthonymccuen at yahoo dot com
11 years ago
You can also use "var" to declare multiple public instance variables like in C:

int main(int *argc, const char *argv[]) {
    int a, b, c, d, e, f;
   
    a = 50;
    // blah blah blah code here
    // ...
   
    return 0;
}

Same as PHP:

<?php
class MyClass {
    var
$myvar, $anotherVar, $something, $str;
}
?>
up
1
masonswolf at gmail dot com
11 years ago
You can invoke a class above its definitions in some cases, but there are very important exceptions to this behavior. If your class extends another class, and the interpreter doesn't see the extended class first, then it won't be added to the symbol table until the code has stepped through it in runtime. As a result, if you try to invoke it above the definition, you'll get a "class not found" fatal error.

And those suck.

So, to provide an example, the following will output a fatal error
<?php
Bar
::bar();
exit;

class
Bar extends Foo { } //will fatal because Foo not seen yet

class Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

However, THIS code will work just fine:
<?php
Bar
::bar();
exit;

class
Foo {
    static function
bar() { echo 'yep, this is Foo::bar'; }
}

class
Bar extends Foo { } //will work because Foo came first
?>

Notice that if you include a file containing the class you will extend, and then extend the class in the same file as its invocation, you can also get the class not found fatal. This happens even if the 'include' call happens before the child class's definition.

Eg. the following will also output a fatal error
<?php
include_once('file_with_foo.php');

Bar::bar();
exit;

class
Bar extends Foo { }
?>

Hope that clarifies things.
up
-9
pov at fingerprint.fr
12 years ago
I just discovered a behaviour that has to be mentioned.

Let's consider the following file

<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
?>

You may expect :
- an error on the Foo::bar call, because the class is not defined
- removing the code after the exit without side-effect

But it won't, and it will output the string !
It seems every class definition is executed at parse-time.

But without errors; if your file is
<?php
Foo
::bar();
exit;

class
Foo {
  function
bar() { echo 'yep, this is Foo::bar'; }
}
class
Foo {
  function
bar() { echo 'yep, this is another Foo::bar'; }
}
?>
it will still output the first string, not doing any "Already exiting class" error !

So if you intend preventing a double include by doing in an included file :
<?php
if (class_exists('Foo')) { return; }

class
Foo {
  static function
register() { ... }
}
Foo::register();
?>
the Foo::register method won't be called !

Very strange development choice; I suppose it is due to ascending compatibility.
Hope it can help...
up
-10
boukeversteegh at gmail dot com
13 years ago
You can also instantiate objects using variables containing the name of the class:

<?php

$type
= 'Foo';
$foo   = new $type();

print_r( $foo );
/* Prints:
Foo Object
(
)
*/
?>

The following works as well:
<?php

$somefoo   
= new Foo();
$anotherfoo = new $somefoo();

# so you don't have to do:
$anotherfoo = new get_class( $somefoo)();
?>
To Top