Recorrer propiedades objetos

 <?php

        //Recorrer objetos

        class MiClase {

            public $var1 = 'valor 1';
            public $var2 = 'valor 2';
            public $var3 = 'valor 3';
            protected $protected = 'variable protegida';
            private $private = 'variable privada';

            function iterateVisible() {
                echo "MiClase::iterateVisible:<br/>";
                foreach ($this as $clave => $valor) {
                     echo $clave." - ".$valor."<br/>";
                }
            }

        }
        $clase=new MiClase();
        foreach($clase as $clave=>$valor){
            echo $clave." - ".$valor."<br/>";
        }
        $clase->iterateVisible();
        
        ?>

Rasgos (traits)

  <?php

        //Rasgos (traits)

        trait Educado {

            function saludo() {
                echo "Hola";
            }

            function despedida() {
                echo "adios";
            }

        }

        trait HTML {

            function cabecera() {
                echo "<h1>$this->nombre</h1>";
            }

        }

        class Pepe {

            use Educado;
        }

        class Juan {
            public $nombre;
            use Educado,
                HTML;
        }

        $obj = new Pepe;
        $obj->despedida();

        $obj2 = new Juan();
        $obj2->nombre="Juan";
        $obj2->despedida();
        $obj2->cabecera();
        ?>

Interfaces

 <?php

        //Interfaces
        
        interface webHTML{
            public function dibujaTabla();
            public function dibujaCabecera($nombre);
        }
        
        class miTabla implements webHTML{
            public function dibujaTabla() {
                echo "<table><tr><td></td></tr></table>";
            }
            public function dibujaCabecera($nombre) {
                echo "<h1>$nombre</h1>";
            }
            public function saludo(){
                echo "hola";
            }
        }
        class OtraTabla implements webHTML{
            public function dibujaTabla() {
                echo "hola";
            }
            public function dibujaCabecera($nombre) {
                echo $nombre;
            }
        }
        
        ?>

Clases Abstractas

 <?php

        //Clases abstractas
        //No se puede instanciar
        abstract class ClaseAbstracta {

            public $nombre;

            function saludo() {
                echo "Hola";
            }

            abstract function despedida();
        }

        class ClaseConcreta extends ClaseAbstracta {
            //Obligado a implementar despedida
            function despedida() {
                echo "adios";
            }

        }
        //Da error porque no implementamos despedida
        class OtraClase extends ClaseAbstracta{
            
        }
        $fallo=new ClaseAbstracta(); //ERROR
        
        $obj = new ClaseConcreta();
        $obj->nombre = "Juan";
        $obj->saludo();

Ejemplo conexión BD

<?php

class BD {

    static $server = "localhost";
    static $user = "root";
    static $password = "";
    static $database = "sakila";
    private $table;
    static private $conn;
    public function __construct($table) {
        $this->table = $table;
        self::conectar();
    }
    static function conectar() {
        try {
            self::$conn = new PDO("mysql:host=" . self::$server . ";dbname=" . self::$database, 
                    self::$user, self::$password, [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"]);
            self::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (Exception $ex) {
            echo $ex->getMessage();
        }
    }
    function getAll(){
        $res=self::$conn->query("select * from ".$this->table);
        return $res->fetchAll();
    }
}
$actores=new BD("actor");
print_r($actores->getAll());

$paises=new BD("country");

print_r($paises->getAll());

Sobreescritura

<?php 
        class A {
            public $nombre;
            public function __construct($nombre) {
                $this->nombre=$nombre;
            }
            
            function saludo(){
                echo "Hola ".$this->nombre;
            }
        }
        class B extends A{
            public $apellidos;
            public function __construct($nombre,$apellidos) {
                parent::__construct($nombre);
                $this->apellidos=$apellidos;
            }
            function saludo(){
                echo "Hola ".$this->nombre." ".$this->apellidos;
            }
        }
        $ana=new A("Ana");
        $ana->saludo();
        
        $juan=new B("Juan","Pi");
        $juan->saludo();
        ?>

Valores estáticos

 <?php
        class foo{
            public static $ciudad="Barcelona";
            public $nombre;
            public function __construct($nombre) {
                $this->nombre=$nombre; 
            }
            public static function saludo(){
                       echo "Hola estoy en ".self::$ciudad;
         
            }
             public static function otroSaludo(){
                echo "Hola ".$this->nombre; //Esto da un error por ser estático
            }
        }
        $ana=new foo("Ana");
        $juan=new foo("Juan");
        
        print_r($ana);
        print_r($juan);
        
        echo foo::$ciudad;
        echo $ana::$ciudad;
        echo $juan::$ciudad;
        
        foo::$ciudad="Turruncún";
        echo foo::$ciudad;
        echo $ana::$ciudad;
        echo $juan::$ciudad;
        
        $juan::saludo();
        $ana::saludo();
        ?>

Constructores

 <?php

        class A {

            public $elementos = [];

            public function __construct() {
                for ($i = 0; $i < 10; $i++) {
                    $this->elementos[] = $i;
                }
            }
          

        }

        class B {

            public $elementos = [];

            public function __construct($num=10) {
                for ($i = 0; $i < $num; $i++) {
                    $this->elementos[] = $i;
                }
            }

        }

        $a = new A();
        $b = new A();


        $c = new B(3);
        $d = new B(9);
        $e = new B();

        print_r($c->elementos);
        print_r($d->elementos);
        print_r($e->elementos);
        ?>

Herencia y visibilidad

 <?php

        class A {

            public $aa = "aa";
            private $bb = "bb";
            protected $cc = "cc";

        }

        class B extends A {

            public $dd = "dd";
            private $ee = "ee";

            function test() {
                echo $this->aa;
                echo $this->bb; //Esta no la imprime
                echo $this->cc;
                echo $this->dd;
                echo $this->ee;
            }

        }

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

        echo $obj->aa;
        echo $obj->bb;//Esta no la imprime
        echo $obj->cc;//Esta no la imprime
        echo $obj->dd;
        echo $obj->ee;//Esta no la imprime

Ejercicio alumnos

class Alumno {

            private $nombre;
            private $nota;
            private $apellidos;

            //Set y get para todas las propiedades. La nota enter 0 y 10
            //El resto no vacíos
            //Función aprobado que nos devuelva true si la nota es >=5
            //Función nombre completo que nos devuelva el nombre y el apellido
            //¿Sería posible hacerlo como propiedad y no como función?
            //Functión mágica toString que nos devuelva nombre completo y nota

            function __set($name, $value) {
                if (property_exists($this, $name)) {
                    if ($name == 'nota') {
                        if ($value >= 0 && $value <= 10) {
                            $this->nota = $value;
                        } else {
                            throw new Exception("La nota debe estar entre 0 y 10");
                        }
                    } else {
                        if (!empty($value)) {
                            $this->$name = $value;
                        }
                    }
                }
            }

            function aprobado() {
                return $this->nota >= 5;
            }

            function __get($name) {
                if (property_exists($this, $name)) {
                    return $this->$name;
                } else {
                    if ($name == "nombreCompleto") {
                        return $this->nombreCompleto();
                    }
                }
            }

            function nombreCompleto() {
                return $this->nombre . " " . $this->apellidos;
            }

            public function __toString() {
                return $this->nombreCompleto." - ".$this->nota;
            }

        }

        $ana = new Alumno();
        $ana->nombre="Ana";
        $ana->apellidos="Pi";
        $ana->nota=7;
        echo $ana->nombreCompleto."<br/>";
        echo $ana;
        ?>