English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Tutoriales básicos de PHP

Tutoriales avanzados de PHP

PHP y MySQL

Manual de referencia PHP

Programación orientada a objetos en PHP

En el diseño de programas orientados a objetos (inglés: Object-orientación de programación, abreviatura: OOP) en la que un objeto es un todo compuesto por una descripción de información y de cómo se procesa esa información, que es una abstracción del mundo real.

En el mundo real, las cosas a las que nos enfrentamos son objetos, como computadoras, televisores, bicicletas, etc.

Las tres características principales de los objetos:

  • El comportamiento de los objetos: Las operaciones que se pueden aplicar a los objetos, encender, apagar son comportamientos.

  • La forma de los objetos: Cuando se aplican esos métodos, cómo responden los objetos, color, tamaño, forma.

  • La representación de objetos: La representación de objetos es equivalente a una tarjeta de identidad, la distinción específica está en qué es diferente en las mismas conductas y estados.

Por ejemplo, Animal (animal) es una clase abstracta, podemos concretar un perro y una oveja, y el perro y la oveja son objetos específicos, que tienen propiedades de color, que se pueden escribir, pueden correr, etc.

面向对象内容

  • − Define las características abstractas de una cosa. La definición de una clase incluye la forma de los datos y las operaciones sobre los datos.

  • 对象 − Es una instancia de la clase.

  • Variable miembro − Definido en el interior de la clase, es una variable que no es visible desde afuera, pero se puede acceder a través de las funciones miembro. Después de que la clase se ejemplifica como un objeto, esta variable se puede llamar atributo del objeto.

  • Función miembro − Definido en el interior de la clase, se puede utilizar para acceder a los datos del objeto.

  • herencia − La herencia es el mecanismo por el cual la subclase comparte automáticamente las estructuras de datos y métodos de la clase padre, que es una relación entre clases. Al definir y implementar una clase, se puede hacer en base a una clase ya existente, tomando el contenido definido por la clase existente como su propio contenido y añadiendo algunos nuevos.

  • 父类 − Una clase que es heredada por otra clase se puede llamar clase padre, o clase base, o clase super.

  • 子类 − Un clase que hereda de otra clase se llama subclase, también se puede llamar clase derivada.

  • 多态 − La polimorfismo es que las mismas funciones o métodos pueden actuar sobre varios tipos de objetos y obtener diferentes resultados. Diferentes objetos, al recibir el mismo mensaje pueden producir diferentes resultados, este fenómeno se llama polimorfismo.

  • 重载 − En términos simples, es la situación en la que las funciones o métodos tienen el mismo nombre, pero diferentes listas de parámetros. En tales funciones o métodos con nombres idénticos pero parámetros diferentes, se denominan entre sí funciones o métodos sobrecargados.

  • 抽象性 − La abstracción es la abstracción de objetos que tienen una estructura de datos (propiedades) y comportamientos (operaciones) consistentes en una clase. Una clase es así de abstracta, que refleja las propiedades importantes relacionadas con la aplicación, ignorando otros contenidos irrelevantes. Cualquier división de clases es subjetiva, pero debe estar relacionada con la aplicación específica.

  • 封装 − La encapsulación es la asociación de las propiedades y comportamientos de un objeto existente en el mundo real en una unidad lógica.

  • Constructor − Se utiliza principalmente para inicializar un objeto en el momento de su creación, es decir, asignar valores iniciales a las variables miembro del objeto, y se utiliza junto con el operador new en las sentencias de creación de objetos.

  • 析构函数 − Función destruidora (destructor) y función constructora al revés, cuando el objeto termina su ciclo de vida (por ejemplo, cuando se completa la función en la que reside el objeto), el sistema ejecuta automáticamente la función destruidora. La función destruidora a menudo se utiliza para hacer 'limpieza y reparación' (por ejemplo, si se abre un espacio de memoria con new al crear el objeto, se debe liberar con delete antes de salir).

En la imagen siguiente, creamos tres objetos a través de la clase Car: Mercedes, Bmw y Audi.

$mercedes = new Car();
$bmw = new Car();
$audi = new Car();

Definición de clase PHP

El formato de sintaxis común para definir una clase en PHP es el siguiente:

<?php
class phpClass {
  var $var1;
  var $var2 ='cadena constante';
  
  function myfunc ($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

Se analiza como sigue:

  • La clase se utiliza class Después del operador de clave.

  • En el paréntesis grande ({}) después del nombre de la clase se pueden definir variables y métodos.

  • Las variables de la clase se utilizan var para declarar, las variables también pueden inicializarse con un valor.

  • La definición de la función es similar a la definición de la función en PHP, pero la función solo puede ser accedida a través de la clase y los objetos instanciados de la clase.

Ejemplo

<?php
class Site {
  /* Variable miembro */
  var $url;
  var $title;
  
  /* Función miembro */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

Variable $this Representa el objeto propio.

PHP_EOL Para el salto de línea.

Creación de objetos en PHP

Después de la creación de la clase, podemos usar new Operador para crear objetos de la clase:

$w3codebox = new Site;
$taobao = new Site;
$google = new Site;

En el código anterior, creamos tres objetos, cada uno de los cuales es independiente. Ahora veamos cómo acceder a los métodos miembros y las variables miembros.

Llamar a métodos miembros

Después de la creación del objeto, podemos usar el objeto para llamar a los métodos miembros, los métodos miembros solo pueden operar las variables miembros del objeto:

// Llamar a la función miembro, configurar el título y la URL
$w3codebox->setTitle( "基础教程网" );
$taobao->setTitle('淘宝');
$google->setTitle( "Google 搜索" );
$w3codebox->setUrl( 'www.w3>setUrl( 'codebox.com' );
$taobao->setUrl('www.taobao.com');
$google->setUrl( 'www.google.com' );
// 调用成员函数,获取标题和URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();

El código completo es el siguiente:

在线示例

<?php
class Site {
  /* Variable miembro */
  var $url;
  var $title;
  
  /* Función miembro */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
$w3codebox = new Site;
$taobao = new Site;
$google = new Site;
// Llamar a la función miembro, configurar el título y la URL
$w3codebox->setTitle( "基础教程网" );
$taobao->setTitle( "天猫商城" );
$google->setTitle( "Google 搜索" );
$w3codebox->setUrl( 'www.w3>setUrl( 'codebox.com' );
$taobao->setUrl( 'www.tmall.com' );
$google->setUrl( 'www.google.com' );
// 调用成员函数,获取标题和URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

Ejecutando el código anterior, el resultado de salida es:

基础教程网
天猫商城
Google 搜索
es.oldtoolbag.com
www.tmall.com
www.google.com

PHP 构造函数

构造函数是一种特殊的方法。主要用来在创建对象时初始化对象,即为对象成员变量赋初始值,在创建对象的语句中与 new 运算符一起使用。

PHP 5 允许开发者在一个类中定义一个方法作为构造函数,语法格式如下:

void __construct ([ mixed $args [, $... ]]] )

在上面的实例中我们就可以通过构造方法来初始化 $url 和 $title 变量:

function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

现在我们就不需要再调用 setTitle 和 setUrl 方法了:

在线示例

$w3codebox = new Site('es.oldtoolbag.com', '基础教程网');
$tmall= new Site('www.tmall.com', '天猫商城');
$google = new Site('www.google.com', 'Google 搜索');
// 调用成员函数,获取标题和URL
$w3codebox->getTitle();
$tmall->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$tmall->getUrl();
$google->getUrl();

析构函数

析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。

PHP 5 引入了析构函数的概念,这类似于其他面向对象的语言,其语法格式如下:

void __destruct ( void )

Ejemplo

<?php
class MyDestructableClass {
   function __construct() {
       print "构造函数\n";
       $this->name = "MyDestructableClass";
   }
   function __destruct() {
       print "Destruir " . $this->name . "\n";
   }
}
$obj = new MyDestructableClass();
?>

Ejecutando el código anterior, el resultado de salida es:

Constructor
Destrucción de MyDestructableClass

herencia

PHP utiliza la palabra clave extends Para heredar una clase, PHP no admite la herencia múltiple, el formato es el siguiente:

class Child extends Parent {
   // Parte del código
}

Ejemplo

En el ejemplo, la clase Child_Site hereda la clase Site y expande las funciones:

<?php 
// La subclase extiende la categoría de sitio
class Child_Site extends Site {
   var $category;
    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

Reescritura de métodos

Si el método heredado de la clase padre no satisface las necesidades de la subclase, se puede modificar, este proceso se llama sobrescripción de métodos (override) o reescritura de métodos.

En el ejemplo, se sobrescriben los métodos getUrl y getTitle:

function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

Control de acceso

PHP realiza el control de acceso a las propiedades o métodos mediante la adición de las palabras clave public (público), protected (protegido) o private (privado) delante de ellos.

  • public (público):Los miembros de la clase públicos pueden ser accedidos en cualquier lugar.

  • protected (protegido):Los miembros de la clase protegidos pueden ser accedidos por sí mismos, sus subclases y sus clases padre.

  • private (privado):Los miembros de la clase privados solo pueden ser accedidos por la clase en la que se definen.

Control de acceso a las propiedades

Las propiedades de la clase deben definirse como públicas, protegidas o privadas. Si se utiliza var, se considera pública.

<?php
/**
 * Definir MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj = new MyClass();
echo $obj->public; // Esta línea se puede ejecutar normalmente
echo $obj->protected; // Esta línea generará un error fatal
echo $obj->private; // Esta línea también generará un error fatal
$obj->printHello(); // Salida de Public, Protected y Private
/**
 *Definir MyClass2
 */
class MyClass2 extends MyClass
{
    // Se puede redefinecer public y protected, pero no private
    protected $protected = 'Protected'2';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // Esta línea se puede ejecutar normalmente
echo $obj2->private; // No definido private
echo $obj2->protected; // Esta línea generará un error fatal
$obj2->printHello(); // Salida Public, Protected2 y Undefined
?>

Control de acceso a los métodos

Los métodos de la clase pueden definirse como públicos, privados o protegidos. Si no se establecen estas palabras clave, el método se considera público por defecto.

<?php
/**
 * Definir MyClass
 */
class MyClass
{
    // Declarar un constructor público
    public function __construct() { }
    // Declarar un método público
    public function MyPublic() { }
    // Declarar un método protegido
    protected function MyProtected() { }
    // Declarar un método privado
    private function MyPrivate() { }
    // Este método es público
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // Esta línea se puede ejecutar normalmente
$myclass->MyProtected(); // Esta línea generará un error fatal
$myclass->MyPrivate(); // Esta línea generará un error fatal
$myclass->Foo(); // Públicas, protegidas y privadas pueden ejecutarse
/**
 * Definir MyClass2
 */
class MyClass2 extends MyClass
{
    // Este método es público
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // Esta línea generará un error fatal
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Esta línea se puede ejecutar normalmente
$myclass2->Foo2(); // Las públicas y protegidas pueden ejecutarse, pero no las privadas
class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }
    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}
class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

Interfaz

Al usar la interfaz (interface), se puede especificar que una clase debe implementar ciertos métodos, pero no es necesario definir el contenido específico de estos métodos.

La interfaz se define mediante interface Se definen con un keyword, al igual que se define una clase estándar, pero todos los métodos definidos están vacíos.

Todos los métodos definidos en la interfaz deben ser públicos, esta es la característica de la interfaz.

Para implementar una interfaz, usar implements Operador. La clase debe implementar todos los métodos definidos en la interfaz, de lo contrario se generará un error fatal. Una clase puede implementar múltiples interfaces, separando los nombres de las interfaces con comas.

<?php
// Declarar una interfaz 'iTemplate'
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
// Implementar interfaz
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{' . $name . '}', $value, $template);
        }
 
        return $template;
    }
}

Constante

Se puede definir un valor que siempre sea constante en la clase. Al definir y usar una constante, no es necesario usar el símbolo $.

El valor de la constante debe ser un valor fijo, no puede ser una variable, una propiedad de clase, el resultado de una operación matemática o una llamada a una función.

Desde PHP 5.3.0 en adelante, se puede usar una variable para llamar dinámicamente a la clase. Pero el valor de la variable no puede ser un keyword (como self, parent o static).

Ejemplo

<?php
class MyClass
{
    const constant = '常量值';
    function showConstant() {
        echo self::constant . PHP_EOL;
    }
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // desde 5.3.0 comienza
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // desde PHP 5.3.0 comienza
?>

clase abstracta

Cualquier clase que tenga al menos un método declarado como abstracto debe declararse como abstracta.

Las clases definidas como abstractas no pueden ser instanciadas.

Los métodos definidos como abstractos solo declaran la forma de su llamada (parámetros), no pueden definir su implementación funcional específica.

cuando se hereda una clase abstracta, la subclase debe definir todos los métodos abstractos de la clase padre; además, los controles de acceso de estos métodos deben ser los mismos que en la clase padre (o más amplios). Por ejemplo, si un método abstracto se declara como protegido, entonces el método implementado en la subclase debe declararse como protegido o público, y no como privado.

<?php
clase abstracta AbstractClass
{
 // se requiere que las subclases definan estos métodos
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);
    // método común (no abstracto)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}
class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}
class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

Ejecutando el código anterior, el resultado de salida es:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Además, el método de la subclase puede incluir parámetros opcionales que no existen en el método abstracto de la clase padre.

Por ejemplo, si la subclase define un parámetro opcional mientras que la declaración del método abstracto de la clase padre no lo incluye, también puede ejecutarse normalmente.

<?php
clase abstracta AbstractClass
{
    // Nuestro método abstracto solo necesita definir los parámetros necesarios
    abstract protected function prefixName($name);
}
class ConcreteClass extends AbstractClass
{
    // Nuestra subclase puede definir parámetros opcionales que no existen en la firma del padre.
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            $prefix = "Mr";
        } elseif ($name == "Pacwoman") {
            $prefix = "Mrs";
        } else {
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

El resultado de la salida es:

Mr. Pacman
Mrs. Pacwoman

Palabra clave static

Al declarar una propiedad o método de clase como static (estático), se puede acceder directamente sin instanciar la clase.

Las propiedades estáticas no pueden ser accedidas a través de un objeto que ya ha sido instanciado de una clase (pero los métodos estáticos pueden).

Dado que los métodos estáticos pueden ser llamados sin necesidad de un objeto, la variable de pseudocontexto $this no está disponible en los métodos estáticos.

Las propiedades estáticas no pueden ser accedidas por un objeto. -> operador para acceder.

Desde PHP 5.3.0 en adelante, se puede usar una variable para llamar dinámicamente a la clase. Pero el valor de la variable no puede ser las palabras clave self, parent o static.

<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
?>

Ejecutar el programa anterior, el resultado de salida es:

foo
foo

Palabra clave final

PHP 5 Se ha añadido una palabra clave final. Si un método de la clase padre se declara como final, la clase hija no puede sobrescribir ese método. Si una clase se declara como final, no puede ser heredada.

La ejecución del siguiente código generará un error: }}

<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called" . PHP_EOL;
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called" . PHP_EOL;
   }
}
class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called" . PHP_EOL;
   }
}
// Mensaje de error Fatal error: Cannot override final method BaseClass::moreTesting()
?>

Llamar al método de construcción de la clase padre

PHP no llama automáticamente al método de construcción de la clase padre en el método de construcción de la subclase. Para ejecutar el método de construcción de la clase padre, debe llamarlo en el método de construcción de la subclase parent::__construct() .

<?php
class BaseClass {
   function __construct() {
       print "Método de construcción de la clase BaseClass" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();  // El método de construcción de la subclase no puede llamar automáticamente al método de construcción de la clase padre
       print "Método de construcción de la clase SubClass" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // Heredar el método de construcción de BaseClass
}
// Llamar al método de construcción de BaseClass
$obj = new BaseClass();
// Llamar a los métodos de construcción de BaseClass y SubClass
$obj = new SubClass();
// Llamar al método de construcción de BaseClass
$obj = new OtherSubClass();
?>

Ejecutar el programa anterior, el resultado de salida es:

Método de construcción de la clase BaseClass
Método de construcción de la clase BaseClass
Método de construcción de la clase SubClass
Método de construcción de la clase BaseClass