|

PHP

PHP está diseñado para ser fácil de aprender y potente en su aplicación, lo que lo convierte en una opción popular para desarrolladores de todos los niveles. Aquí tienes algunos aspectos básicos:

  • Etiquetas de PHP: Un script de PHP se puede colocar en cualquier parte de un documento. Este script comienza con <?php y termina con ?>. Por ejemplo:
<?php
// Código PHP va aquí
?>
$nombre = "Juan";
echo "Hola, " . $nombre . "!";

Comentarios: Puedes agregar comentarios en tu código PHP para hacerlo más legible. Los comentarios de una sola línea comienzan con //, mientras que los comentarios de varias líneas se encierran entre /* y */:

// Esto es un comentario de una sola línea

/*
Esto es un comentario
de varias líneas
*/

En PHP, los tipos de datos se utilizan para representar diferentes tipos de valores que se pueden manipular en un programa. A continuación, describiré los tipos de datos más comunes en PHP:

Entero (int): Representa números enteros sin parte decimal. Puede ser positivo o negativo. Por ejemplo:

$edad = 30;

Flotante o doble (float o double): Representa números con punto flotante (decimales). Por ejemplo:

$precio = 19.99;

Cadena de caracteres (string): Representa texto. Puede estar entre comillas simples o dobles. Por ejemplo:

$nombre = "Juan";

Booleano (bool): Representa valores verdaderos (true) o falsos (false). Se utiliza en pruebas condicionales. Por ejemplo:

$activo = true;

Arreglo (array): Almacena múltiples valores en una sola variable. Por ejemplo:

$colores = array("rojo", "verde", "azul");
$colores = ["rojo", "verde", "azul"];

Objeto: Las clases y objetos son fundamentales en la programación orientada a objetos. Un objeto es una instancia de una clase. Por ejemplo:

class Coche {
    public $marca;
    public function __construct($marca) {
        $this->marca = $marca;
    }
}
$miCoche = new Coche("Toyota");

Recuerda que PHP no requiere (ni soporta) la definición explícita de tipos en la declaración de variables; el tipo de la variable se determina por el contexto en el cual se emplea la variable

En PHP, los arrays son estructuras de datos que nos permiten almacenar múltiples valores en una sola variable. Existen dos tipos principales de arrays: arrays indexados y arrays asociativos. Vamos a explorar ambos:

Arrays Indexados:

  • Los arrays indexados utilizan índices numéricos para acceder a sus elementos. Cada elemento se almacena en una posición específica del array, comenzando desde el índice 0.
  • Ejemplo de un array indexado:
$colores = array("rojo", "verde", "azul");

En este caso, $colores[0] es “rojo”, $colores[1] es “verde” y $colores[2] es “azul”.

Arrays Asociativos:

  • Los arrays asociativos utilizan claves personalizadas en lugar de índices numéricos. Cada elemento se asocia con una clave específica.
  • Ejemplo de un array asociativo:
$persona = array(
    "nombre" => "Juan",
    "edad" => 30,
    "ciudad" => "Madrid"
);

En este caso, $persona["nombre"] es “Juan”, $persona["edad"] es 30 y $persona["ciudad"] es “Madrid”.

  1. Diferencias clave:
    • En los arrays indexados, los índices son automáticamente asignados (0, 1, 2, …).
    • En los arrays asociativos, tú eliges las claves (pueden ser strings o números).
  2. Ventajas de los Arrays Asociativos:
    • Puedes asignar significado a cada elemento mediante claves descriptivas.
    • Son útiles para almacenar información estructurada, como datos de una persona o configuraciones de una aplicación.

En resumen, los arrays indexados son ideales cuando necesitas una lista simple de elementos, mientras que los arrays asociativos son más apropiados cuando deseas relacionar datos con claves personalizadas

Puedes crear arrays tanto indexados como asociativos utilizando la notación de corchetes [] de forma abreviada. Permíteme mostrarte cómo:

  • Array Indexado (abreviado):
$colores = ["rojo", "verde", "azul"];
  • Array Asociativo (abreviado):
$persona = [
    "nombre" => "Juan",
    "edad" => 30,
    "ciudad" => "Madrid"
];

Aquí, $persona["nombre"] es “Juan”, $persona["edad"] es 30 y $persona["ciudad"] es “Madrid”.

La notación de corchetes [] es una forma concisa y legible de definir arrays en PHP. 

Clases y Objetos

La programación orientada a objetos (POO) se basa en la creación de clases y objetos para encapsular datos y comportamientos. En PHP, las clases y los objetos son los elementos fundamentales de la POO, y se utilizan para crear soluciones escalables y eficientes1. Aquí tienes algunos conceptos clave sobre clases y objetos en PHP:

  1. Clases:
    • Una clase es una plantilla o un plano que define la estructura y el comportamiento de los objetos.
    • Define propiedades (variables) y métodos (funciones) que los objetos pueden tener.
    • Puedes pensar en una clase como un “molde” para crear objetos.
    • Para definir una clase en PHP, utilizamos la palabra clave class.
  2. Objetos:
  3. Propiedades y Métodos:
    • Las propiedades son variables dentro de una clase que almacenan datos específicos para cada objeto.
    • Los métodos son funciones dentro de una clase que definen el comportamiento de los objetos.
    • Puedes acceder a las propiedades y métodos de un objeto utilizando la notación de punto ($objeto->propiedad o $objeto->metodo()).
  4. Visibilidad:
    • Las propiedades y métodos pueden tener diferentes niveles de visibilidad: publicprotected o private.
    • public: Accesible desde cualquier lugar.
    • protected: Accesible solo dentro de la clase y sus subclases.
    • private: Accesible solo dentro de la clase.
  5. Constructores y Destructores:
    • El constructor es un método especial que se ejecuta automáticamente al crear un objeto.
    • El destructor se ejecuta cuando el objeto se destruye o se elimina.
  6. Herencia:
    • Permite crear una nueva clase basada en una clase existente (clase padre).
    • La nueva clase (clase hija) hereda propiedades y métodos de la clase padre.
  7. Abstracción, Interfaces y Rasgos (Traits):
    • La abstracción permite definir una clase base con métodos abstractos que deben ser implementados por las clases derivadas.
    • Las interfaces definen un conjunto de métodos que las clases deben implementar.
    • Los rasgos son fragmentos de código reutilizables que se pueden incluir en múltiples clases.

En resumen, las clases y objetos en PHP te permiten organizar y estructurar tu código de manera más eficiente, facilitando la reutilización y la modularidad.

A continuación, te proporciono ejemplos prácticos para cada uno de los conceptos mencionados sobre clases y objetos en PHP:

Clases:

<?php
class Persona {
    public $nombre;
    public $edad;

    public function saludar() {
        echo "¡Hola, mi nombre es {$this->nombre}!";
    }
}

// Crear un objeto de la clase Persona
$persona1 = new Persona();
$persona1->nombre = "Juan";
$persona1->edad = 30;
$persona1->saludar();
?>

En este ejemplo, hemos definido una clase Persona con propiedades nombre y edad, así como un método saludar() que muestra un saludo personalizado.

Objetos:

<?php
// Crear otro objeto de la clase Persona
$persona2 = new Persona();
$persona2->nombre = "María";
$persona2->edad = 25;
$persona2->saludar();
?>

Aquí creamos un segundo objeto Persona con diferentes valores para las propiedades.

Visibilidad:

<?php
class Coche {
    private $marca;

    public function setMarca($nuevaMarca) {
        $this->marca = $nuevaMarca;
    }

    public function getMarca() {
        return $this->marca;
    }
}

$miCoche = new Coche();
$miCoche->setMarca("Toyota");
echo "Marca del coche: " . $miCoche->getMarca();
?>

En este ejemplo, la propiedad $marca es privada, pero podemos acceder a ella a través de los métodos setMarca() y getMarca().

Constructores y Destructores:

<?php
class Producto {
    public $nombre;

    public function __construct($nombre) {
        $this->nombre = $nombre;
        echo "Se creó un nuevo producto: {$this->nombre}";
    }

    public function __destruct() {
        echo "El producto {$this->nombre} se ha eliminado.";
    }
}

$producto1 = new Producto("Laptop");
// ... más código ...
unset($producto1); // Elimina el objeto
?>

Aquí utilizamos el constructor __construct() y el destructor __destruct() para manejar la creación y eliminación de objetos.

Herencia:

<?php
class Empleado extends Persona {
    public $puesto;

    public function trabajar() {
        echo "{$this->nombre} está trabajando como {$this->puesto}.";
    }
}

$empleado1 = new Empleado();
$empleado1->nombre = "Pedro";
$empleado1->puesto = "Desarrollador";
$empleado1->trabajar();
?>
  • Aquí creamos una clase Empleado que hereda de la clase Persona.
  • Abstracción, Interfaces y Rasgos (Traits):
    • La abstracción se logra mediante la definición de métodos abstractos en una clase base.
    • Las interfaces se definen con la palabra clave interface.
    • Los rasgos se crean con la palabra clave trait.

Vamos a explorar los conceptos de variablesconstantesexpresiones y operadores en PHP. 😊

  • Variables:
    • En PHP, las variables se declaran utilizando el símbolo de $ seguido del nombre de la variable.
    • No es necesario especificar el tipo de dato al declarar una variable, ya que PHP es un lenguaje de programación con variables de tipado dinámico.
    • Ejemplo:
$nombre = "Juan";
$edad = 25;
$precio = 10.5;
$esEstudiante = true;

Constantes:

  • Las constantes son valores que no cambian durante la ejecución del programa.
  • Se definen utilizando la función define() o la palabra clave const.
  • Ejemplo:
define("PI", 3.14159);
const IVA = 0.21;

Expresiones:

  • Las expresiones son combinaciones de valores, variables, operadores y funciones que devuelven un valor.
  • Casi todo en PHP es una expresión.
  • Ejemplo:
$resultado = ($edad * 2) + 10;
  • Operadores:
    • Los operadores son símbolos que realizan operaciones en expresiones.
    • Algunos operadores comunes en PHP son:
      • Aritméticos+-*/%
      • Asignación=+=-=*=/=
      • Comparación==!=<><=>=
      • Lógicos&&||!
      • Concatenación de strings.
      • Incremento/Decremento++--
      • Operadores ternarios? :

Recuerda que las expresiones y operadores son fundamentales para construir programas en PHP.

Variables Superglobales

En PHP, las superglobales son variables internas que están disponibles en todos los ámbitos a lo largo del script. No es necesario emplear global $variable; para acceder a ellas dentro de las funciones o métodos. Las principales superglobales son:

  1. $GLOBALS: Contiene todas las variables globales.
  2. $_SERVER: Proporciona información sobre el servidor y la solicitud HTTP.
  3. $_GET: Almacena los parámetros pasados en la URL.  (por ejemplo, example.com/index.php?param1=value1&param2=value2).
  4. $_POST: Contiene datos enviados mediante formularios POST.
  5. $_FILES: Utilizado para manejar archivos subidos por el usuario.
  6. $_COOKIE: Almacena cookies del cliente.
  7. $_SESSION: Mantiene información de sesión.
  8. $_REQUEST: Combina datos de $_GET$_POST y $_COOKIE.
  9. $_ENV: Contiene variables de entorno.

Aquí tienes un ejemplo de un formulario HTML que envía datos al servidor mediante el método POST y cómo se procesan esos datos en un script PHP:

<html>
<head>
    <title>Formulario de Registro</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <h2>Formulario de Registro</h2>
    <form action="registration_form.php" method="POST">
        First name: <input type="text" name="firstname"><br>
        Last name: <input type="text" name="lastname">
        <input type="hidden" name="form_submitted" value="1" />
        <input type="submit" value="Submit">
    </form>
</body>
</html>

En este ejemplo:

  • El formulario se envía al script “registration_form.php” mediante el método POST.
  • Los datos recopilados (nombre y apellido) se guardan en las variables $firstname y $lastname utilizando la variable $_POST.
  • El valor oculto <input type="hidden" name="form_submitted" value="1" /> se utiliza para comprobar si el formulario se ha enviado o no.
  • Cuando se hace clic en el botón “Submit”, los datos se envían al servidor para su procesamiento.

el archivo registration_form.php que procesa los datos enviados desde el formulario de registro y cómo mostrar esos datos:

<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    // Obtener los valores enviados desde el formulario
    $firstname = $_POST["firstname"];
    $lastname = $_POST["lastname"];

    // Procesar los datos (puedes guardarlos en una base de datos, enviar un correo, etc.)
    // En este ejemplo, simplemente los mostraremos en la página
    echo "¡Gracias por registrarte!<br>";
    echo "Nombre: " . $firstname . "<br>";
    echo "Apellido: " . $lastname;
} else {
    // Si el formulario no se ha enviado, muestra un mensaje
    echo "Por favor, completa el formulario.";
}
?>

En este código:

  • Verificamos si el método de solicitud es POST ($_SERVER["REQUEST_METHOD"] == "POST").
  • Recuperamos los valores enviados desde el formulario utilizando $_POST.
  • Procesamos los datos (en este caso, solo los mostramos en la página).
  • Si el formulario no se ha enviado, mostramos un mensaje para completarlo.

Estructuras de control en php

Un script PHP está contruido a partir de sentencias. Una sentencia puede ser una asignación, una llamada a una función, un loop, una sentencia condicional o una sentencia vacía. Las sentencias normalmente finalizan con un punto y coma.

Las estructuras de control son sentencias que permiten controlar cómo el código fluye en nuestro script basándose en ciertos factores. Por ejemplo, cuando queremos realizar una acción sólo si cierta variable está definida, o cuando queremos mostrar un array de datos a través de un loop.

Las estructuras de control son mayoritariamente condicionales (if, switch, etc) o loops (for, foreach, etc).

Indice de contenido

1. if9. continue
2. else10. switch
3. elseif/else if11. declare
4. while12. return
5. do-while13. include/include_once
6. for14. require/require_once
7. foreach15. goto
8. break16. Sintaxis alternativas

1. if

La estructura de control if permite la ejecución condicional de fragmentos de código.

<?php
if ($x > $y) {
    echo "$x es mayor que $y";
}

Las sentencias if se pueden incluir unas dentro de otras indefinidamente.

2. else

Sirve para ejecutar una sentencia cuando otra no se cumple. else extiende una sentencia if, y se ejecuta cuando ésta es false. Siguiendo el ejemplo anterior:

<?php
if ($x > $y) {
    echo "$x es mayor que $y";
} else {
    echo "$y es mayor que $x";
}

3. elseif/else if

Es una combinación entre if y else. Se ejecuta cuando if es false, pero sólo si la expresión condicional del elseif es true.

<?php
if ($x > $y) {
    echo "$x es mayor que $y";
} elseif ($x == $y) {
    echo "$x es igual que $y";
} else {
    echo "$y es mayor que $x";
}

Puede haber varios elseif dentro de una sentencia if (aunque en ese caso suele ser más recomendable usar switch). No hay diferencias de comportamiento entre elseif y else if.

elseif sólo se ejecuta si el if precedente o cualquier elseif anterior son evaluadas como false.

4. while

Es el tipo más sencillo de loop en PHP. Se ejecutan las sentencias dentro del while siempre y cuando se evalúen como true. El valor de la expresión se comprueba cada vez al inicio del loop, y la ejecución no se detendrá hasta que finalice la iteración (cada vez que PHP ejecuta las sentencias en un loop es una iteración). Si la expresión while se evalúa como false, las sentencias no se ejecutarán ni siquiera una vez.

También es posible agrupar varias instrucciones while dentro de una.

<?php
$i = 1;
while($i <= 10){
    echo $i;
    $i++;
}

5. do-while

Muy similares a los loops while, simplemente aquí la expresión para el loop se verifica al final en lugar de al principio, esto garantiza que el código se ejecute por lo menos la primera vez.

<?php
$i = 0;
do {
    echo $i;
} while ($i > 0);

Este loop se ejecutaría sólo una vez, ya que después no cumple la condición.

6. for

Los loops for son los más complejos en PHP.

<?php
for ($i = 1; $i <= 10; $i++) {
    echo $i;
} // Devuelve 123456789
  • Las expresiones o conjunto de expresiones van separadas por punto y coma ; y sólo hay 3.
  • La primera expresión, $i = 1, se ejecuta una vez incondicionalmente al comienzo del bucle.
  • La segunda expresión, $i <= 10, es una condición, si es true, se ejecutará la tercera expresión.
  • La tercera expresión, $i++, es la acción a realizar si se cumple la segunda expresión.

Cada una de las expresiones pueden estar vacías o contener múltiples expresiones, lo que resulta útil en ciertas ocasiones. Si la expresión 2 está vacía, el loop será definido como true.

<?php
// Todos los siguientes ejemplos son válidos y devuelven lo mismo, 123456789
// EJEMPLO 1
for($i = 1; $i <= 10; $i++) {
    echo $i;
}

// EJEMPLO 2
for ($i = 1; ; $i++){
    if($i > 10) {
        break;
    }
    echo $i;
}

// EJEMPLO 3
$i = 1;
for( ; ; ){
    if($i > 10){
        break;
    }
    echo $i;
    $i++;
}

// EJEMPLO 4
for ($i = 1, $j = 0; $i <= 10; $j += $i, print $i, $i++);

Dependiendo de donde se coloque el operador incremento o decremento, dará un resultado distinto:

for ($i = 1; $i <= 10; print $i++); // 12345678910
for ($i = 1; $i <= 10; print ++$i); // 234567891011

Se pueden hacer iteraciones por medio de arrays:

$gente = array(
    array('nombre' => 'Carlos', 'salt' => 123),
    array('nombre' => 'Maria', 'salt' => 124));
// Numero de gente
$size = count($gente);
// Loop que da un salt de 4 dígitos aleatorio
for ($i=0; $i < $size; ++$i) {
    $gente[$i]['salt'] = mt_rand(0000, 9999);
}
var_dump($gente);
/*
* array (size=2)
  0 =>
    array (size=2)
      'nombre' => string 'Carlos' (length=6)
      'salt' => int 2029
  1 =>
    array (size=2)
      'nombre' => string 'Maria' (length=5)
      'salt' => int 9724
*/

7. foreach

foreach permite una forma fácil de iterar sobre arrays u objetos.

Cuando foreach inicia su ejecución, el puntero apunta directamente al primer elemento del array, por lo que no es necesario llamar a la función reset() antes que un loop foreach. Es recomendable no cambiar el puntero dentro del loop.

Se puede iterar de las siguientes dos formas:

<?php
// Devuelve directamente el value de cada key, comenzando desde el primero
foreach ($array as $value) {
    // Lo que se desee mostrar
}
// Devuelve cada key con cada value, para poder trabajar con cualquiera de los dos
foreach ($array as $key => $value){
    // Lo que se desee mostrar
}

Se pueden modificar los elementos del array dentro del loop, anteponiendo & a $value (asignándolo por referencia).

<?php
$array = array(1, 2, 3, 4);
foreach ($array as &$value){
    $value = $value * 2;
}
// cada valor del array vale ahora : 2, 4, 6, 8
unset($value);

La función unset() elimina la referencia del último elemento, pero el array sigue valiendo 2, 4, 6, 8. Es recomendable hacer unset() porque la referencia del $valor y el último elemento del array permanecen aún después del loop foreach.

foreach y list pueden devolver los mismos resultados de la siguiente forma:

<?php
$array = array("uno", "dos", "tres");
reset($array);
while (list($clave, $valor) = each($array)){
    echo "Clave: $clave; Valor: $valor </br>";
}

foreach ($array as $clave => $valor){
    echo "Clave: $clave; Valor: $valor </br>";
}

La función list() coge un array y lo convierte en variables individuales.

each() coge un array y devuelve el key y value actuales, es decir, donde está apuntando el cursor en el array. Es necesario hacer un reset() del array para asegurarse que el cursor comienza desde el principio (cosa que no es necesaria con el foreach).

Suele ser más óptimo y legible utilizar el foreach para iterar, aunque ambos se utilizan más o menos con la misma frecuencia.

Con arrays multidimensionales se puede hacer un doble foreach:

<?php
$x = array();
$x[0][0] = "a";
$x[0][1] = "b";
$x[1][0] = "y";
$x[1][1] = "z";

foreach ($x as $primero){
    foreach ($primero as $segundo){
        echo "$segundo" . "</br>";
        }
    }

En el ejemplo anterior, si no se hace doble foreach con $x y se hace sólo un foreach surgirá un Notice: Array to string conversion.

Desde PHP 5.5 se puede recorrer un array de arrays y utilizar el segundo array para asignar variables:

<?php
$array = array(
    array('azul', 'rojo'),
    array('verde', 'amarillo')
    );

foreach ($array as list($a, $b)) {
    echo "A: $a; B: $b" . "</br>";
}
// Devuelve: 

8. break

break termina la ejecución de las siguientes estructuras: forforeachwhiledo-while y switch.

Se puede añadir un argumento numérico opcional que indica de cuántas estructuras debe salir. El valor por defecto es 1:

// Ejemplo sin valor numérico
$array = array('uno', 'dos', 'parar', 'tres');
while(list(, $valor) = each($array)){
    if($valor == 'parar'){
        break;
    }
    echo "$valor</br>";
}
// Ejemplo con valor numérico
$i = 0;
while (++$i){
    switch($i){
        case 5:
            echo "He llegado a 5 </br>";
            break 1; // Aquí sólo saldría del switch
        case 10:
            echo "He llegado a 10 </br>";
            break 2; // Sale del switch y del while
        default:
            break;
    }
}

9. continue

Se utiliza dentro de las estructuras iterativas para saltar el resto de la iteración actual del loop y continuar a la siguiente iteración para su ejecución:

<?php
for ($i=0; $i < 10; $i++) {
    if($i % 2 == 0)
        continue;
    print "$i ";
} // Devuelve 1 3 5 7 9

El código anterior hace que cuando el número sea par, continue se ejecute y no muestre el print de después, sino que vuelva a empezar con la siguiente iteración. print sólo se ejecutará cuando $i sea impar.

Al igual que con break, se puede añadir un número a continue que indica el número de niveles de loops debe saltar:

<?php
$i = 0;
while ($i++ < 5){
    echo "Uno </br>";
    while (1) {
        echo "Dos </br>";
        while (1) {
            echo "Tres </br></br>";
            continue 3;
        }
        echo "Esto no aparece.";
    }
    echo "Esto tampoco aparece.";
}

En este ejemplo, cuando llega a continue 3, comienza de nuevo la iteración, y se comprueba otra vez la condición ($i++ < 5). Si se pone, por ejemplo, continue 2, salta al segundo while, cuya condición siempre se cumple, y se produce un loop infinito que imprime «Dos Tres» continuamente.

10. switch

switch es como una serie de sentencias if. Es útil para comparar una misma variable o expresión con valores direrentes y ejecutar un código diferente a otro dependiendo de esos valores.

<?php
switch ($i) {
    case "perro":
        echo "\$i es un perro";
        break;
    case "gato":
        echo "\$i es un gato";
        break;
    case "avestruz":
        echo "\$i es un avestruz";
        break;
}

Cuando una sentencia case coincide con el valor de la sentencia switch, PHP ejecuta el código dentro del case. PHP sigue ejecutando las sentencias hasta el final o hasta que choca con un break, que entonces finaliza la iteración. Si se omite break, swith ejecutará todos los cases restantes cuando encuentra uno que cumpla con la condición:

<?php
switch ($i) {
    case 0:
        echo "i es igual a 0";
    case 1:
        echo "i es igual a 1";
    case 2:
        echo "i es igual a 2";
}

En el ejemplo anterior, si se define a $i como 0, se mostrarán todos los echo restantes porque no hay ningún break. Si se define a $i como 1, se mostrarán los echo del case 1 y case 2. Si se define a $i como 2, sólo se mostrará el case 2.

Con switch la condición sólo se evalúa una vez, y su valor es comparado con cada uno de los case, a diferencia de lo que ocurre con elseif, que la condión se va evaluando continuamente con el loop.

case puede no ejecutar ningún código, pero hace que se activen los cases posteriores hasta que se encuentre con un break:

<?php
switch ($i) {
case 0:
case 1:
case 2:
    echo "i es menor que 3 no negativo";
    break;
case 3:
    echo "i es 3";
}

En caso de que no haya ningún case válido, puede utilizarse default, para ejecutar algo cuando no se cumplen los case:

<?php
switch($i) {
    case 0:
        echo "i es igual a 0";
        break;
    case 1:
        echo "i es igual a 1";
        break;
    default:
        echo "i no es ni 0 ni 1";
}
  • En los cases sólo se permiten tipos simplesintfloat y string. Los arrays y objetos pueden utilizarse si se muestran como un tipo simple.
  • Es posible escribir punto y coma «;» en lugar de dos puntos «:» después de un case.

11. declare

declare sirve para fijar directivas de ejecución para un bloque de código.

declare (directive)
    statement

La sección directive permite configurar el comportamiento de declare. Sólo hay dos directivas: ticks y encoding.

  • No se pueden emplear variables ni constantes para las directivas.

Se pueden usar corchetes para fijar el statement o si no se aplican afecta a todo el archivo:

<?php
declare(ticks=1){
   // Código afectado
}

declare(ticks=1);
// Código afectado

En este segundo ejemplo si el archivo con el declare ha sido incluído, no afectará al archivo padre.

Ticks

La ejecución de un script PHP puede representarse como una ejecución de muchas sentencias. La mayoría de las sentencias provocan un tick (aunque no todas). Por ejemplo en el siguiente ejemplo habría 3 ticks:

<?php
$x = 1;
$y = 2;
$z = 3;

Con declare(ticks=N) y _register_tick_function()_ se puede ejecutar código entre los ticks. La función _register_tickfunction especifica la función a llamar cuando un tick ocurre. declare establece cuantos ticks han de pasar hasta que un evento tick se ejecuta.

  • Con declare(ticks=1) y _register_tickfunction(‘miFuncion’); llamará a miFuncion() después de cada tick.
  • Con declare(ticks=3), miFuncion() se ejecutará cada 3 ticks.
<?php
function handler(){
    echo "Hola";
}

register_tick_function("handler");
$i = 0;
declare(ticks = 3) {
    while($i < 9)
        echo ++$i;
} // Devuelve 123Hola456Hola789Hola

Encoding

La codificación puede ser especificada para cada script con encoding:

<?php
declare(encoding='ISO-8859-1');
// Código a ejecutar

12. return

return devuelve el control del programa al módulo que lo invoca. La ejecución vuelve a la siguiente declaración después del módulo que lo invoca.

  • Si se usa en una función, return hace que la función termine, devolviendo los argumentos que le sigan como valor de la llamada a la función.
  • Si se llama globalmente, finaliza la ejecución del script actual.
  • Si el archivo actual fue incluido o requerido, el control regresa al archivo que llama al include o require.
  • Si el archivo está incluído con include, los argumentos del return se devolverán como valor de la llamada include.
  • Si return se usa en el archivo principal del script, termina la ejecución del script.
  • También termina la ejecución de una sentencia eval().

Es recomendable no usar paréntesis después de return.

13. include/include_once

include incluye y ejecuta un archivo.

Los archivos se incluyen en base a la ruta de acceso dada, y si no se proporciona ninguna, se utiliza el include_path. Si el archivo tampoco se encuentra en el include_path se mirará en el propio directorio desde donde se hace la llamada, antes de devolver un mensaje warning. Es en el tipo de mensaje donde difiere con require, que devuelve un error fatal.

  • Si se define una ruta absoluta (en Linux comenzando por /) o relativa al directorio actual (comenzando con . o ..) el include_path será ignorado.

Las variables del archivo del include estarán disponibles en el archivo desde el que se solicita:

<?php
// archivo1.php
$color = 'azul';
// archivo2.php
echo $color; // Devuelve un Notice: Undefined variable: color
include 'archivo1.php';
echo $color; // Devuelve azul
  • Si la inclusión se hace dentro de una función, el contenido del archivo es como si estuviera dentro de esa función, por tanto su contenido tendrá el mismo ámbito.
  • Cuando se incluye un archivo, el intérprete abandona el modo PHP e ingresa al modo HTML al comienzo del archivo incluído, y se reanuda de nuevo al final. Es por ello que cualquier código que tenga que ser interpretado como PHP debe incluir las etiquetas válidas de comienzo y terminación (<?php ?>).

Si están activadas las envolturas URL include, se puede incluir un archivo a través de una URL (mediante HTTP u otro protocolo). Si el servidor objetivo interpreta el archivo como PHP, las variables se pueden pasar al archivo usando un string de petición como con HTTP GET. El resultado no es lo mismo que en local, pues el archivo se ejecuta en el servidor remoto y el resultado se incluye en el local.

<?php
include 'http://www.ejemplo.com/archivo.php?var=1';
$var = 1;

Por seguridad es mejor que el archivo remoto se procese en el servidor remoto y se reciba sólo la salida, con readfile().

Es posible devolver valores desde los archivos include mediante return:

// archivo1.php con return
<?php
$var = 'PHP';
return $bar;
?>
// archivo2.php sin return
<?php
$var = 'PHP';
?>
//archivo3.php
<?php
$foo = include 'archivo1.php';
echo $foo; // devuelve PHP

$bar = include 'archivo2.php';
echo $bar; // Devuelve 1 porque el include ha sido exitoso, pero no tiene valor return. Si no hubiera funcionado devolvería false y un E_WARNING.

También se pueden incluir archivos PHP en variables con un buffering de salida:

<?php
$string = get_include_contents('archivo.php');

function get_include_contents($filename) {
    if(is_file($filename)) {
        ob_start();
        include $filename;
        return ob_get_clean();
    }
    return false;
}

Para incluir archivos automáticamente en scripts ver auto_preprend_file y auto_append_file de php.ini.

_include_once_ incluye el archivo especificado sólo una vez, si se incluye más veces tan sólo devuelve true. Es útil en casos donde el mismo fichero se podría incluir y evaluar más de una vez, para evitar así redefinir funciones o reasignar valores a variables.

14. require/require_once

require hace lo mismo que include pero en caso de fallar devuelve un error fatal de nivel E_COMPILE_ERROR, por lo que no puede continuar el script. include sólo emite un E_WARNING que permite continuar el script.

_require_once es igual que require_ pero PHP comprobará si el archivo ya ha sido incluído, y si es así no se incluirá otra vez.

15. goto

goto se utiliza para saltar a otra sección del script. La etiqueta de destino debe estar dentro del mismo fichero y ámbito.

<?php
goto x;
echo 'Hola!';

x:
echo 'Adios!';  // sólo se imprimirá Adios!

También puede utilizarse en un loop en lugar de break:

<?php
for($i=0, $j=50; $i<100; $i++) {
    while($j--) {
        if($j==17) goto end;
        }
    }
echo "i = $i";
end:
echo 'j llegó a 17';

16. Sintaxis alternativas

PHP ofrece una sintaxis alternativa para ifwhileforforeach y switch. Se cambia el corchete de apertura por dos puntos «:» y el corchete de cierre por endifendwhileendforendforeach, o endswitch.

<?php if ($x == 3): ?>
X es 3
<?php endif; ?>

«X es 3» es un bloque HTML que se mostraría sólo si se cumple la condición.

Con else y elseif:

<?php
if($x == 3):
    echo "x igual a 3";
elseif ($x == 4):
    echo "x igual a 4";
else:
    echo "x no es ni 3 ni 4";
endif;

Funciones

Cuando utilizamos en multiples ocasiones un mismo fragmento de código debemos usar funciones (functions). Una herramienta para encapsular y ejecutar un mismo código. Entre sus ventajas veremos que nos ayuda a que los ficheros tengan un menor tamaño y sea más fácil de mantener.

// Declarar
function nombre_de_funcion(tipo_de_parametro $parametros): tipo_return
{
    ...
    return ...;
}

// Llamar
nombre_de_funcion($parametros);

En el ejemplo inferior tenemos una función clásica, con sintáxis moderna, donde es declarada y ejecutada seguido de un echo para ver el resultado. Lo único que hace es devolver un texto cuando es llamado.

/**
 * Función con educación
 * @return {string}
 */
function saludar_ahora(): string
{
    return 'Hola, soy una función';
}
echo saludar_ahora();
// Hola, soy una función

La receta par hacer una función rica y con fundamento:

  • Las 4 primeras líneas es el formato de comentarios. Una función, por mucha prisa que tengas, debe estar comentada con el formato del ejemplo.
  • La palabra function esta reservada. A continuación el nombre, que debe estar en minúsculas con guiones bajos en lugar de espacios. Después unos paréntesis con los argumentos. Si no tiene, se dejan vacíos pero siempre presentes. Luego dos puntos. Por último el tipo de valor resultante. Más abajo te he dejado una tabla con tipos admitidos.
  • Llaves para envolver tu código {}.
  • Y dentro la palabra reservada return seguido del valor a devolver.

Parámetros

Nuestras funciones serán más interesantes si les damos algunos parámetros. Al darle variables podemos usar siempre el mismo código pero con algunas variaciones.

/**
 * Corta un texto a 10 letras y añade puntos suspensivos al final
 * @param {string} $text - Texto a tratar
 * @return {string}
 */
function resumen(string $text): string
{
    return substr($text, 0, 20) . '...';
}

echo resumen('Cuanto te vi me enamoré y tu sonreíste porque lo sabías');
echo resumen('La vida es una historia contada por un idiota, una historia llena de estruendo y furia, que nada significa');
// Cuanto te vi me enam...
// La vida es una histo...

Si no se cumple los tipos en PHP 5 produce un error que para la ejecución. En cambio, en PHP 7, se lanza una excepción TypeError pero continua.

Nuestros parámetros de entrada pueden tener un valor por defecto.

/**
 * Saluda a una persona
 * @param {string} - Nombre
 * @return {string}
 */
function saludar(string $nombre = 'Anónimo'): string
{
    return 'Hola, persona llamada ' . $nombre .'. Por lo que veo tu nombre mide ' . strlen($nombre) . ' carácteres.';
}
echo saludar();
// Hola, persona llamada Anónimo. Por lo que veo tu nombre mide 8 carácteres.
echo saludar('Picasso');
// Hola, persona llamada Picasso. Por lo que veo tu nombre mide 7 carácteres.

Y, por supuesto, podemos añadir varios parámetros.

/**
 * Saluda a una persona
 * @param {string} - Nombre
 * @param {string} - Profesión
 * @return {string}
 */
function saludar(string $nombre = 'Anónimo', string $profesion = 'ninguna'): string
{
    return 'Hola, persona llamada ' . $nombre .'. Por lo que veo tu nombre mide ' . strlen($nombre) . ' carácteres. De profesión ' . $profesion . '.';
}
echo saludar();
// Hola, persona llamada Anónimo. Por lo que veo tu nombre mide 8 carácteres. De profesión ninguna.
echo saludar('Espartaco');
// Hola, persona llamada Espartaco. Por lo que veo tu nombre mide 9 carácteres. De profesión ninguna.
echo saludar('Picasso', 'pintor');
// Hola, persona llamada Picasso. Por lo que veo tu nombre mide 7 carácteres. De profesión pintor.

Tipos admitidos

TipoDescripciónVersión mínima
stringEl parámetro debe ser un string.PHP 7.0.0
intEl parámetro debe ser un valor de tipo integer.PHP 7.0.0
floatEl parámetro debe ser un número de tipo float.PHP 7.0.0
boolEl parámetro debe ser un valor de tipo boolean.PHP 7.0.0
arrayEl parámetro debe ser un array.PHP 5.1.0
callableEl parámetro debe ser un callable válido.PHP 5.4.0
selfEl parámetro debe ser una instanceof de la misma clase donde está definido el método. Esto solamente se puede utilizar en clases y métodos de instancia.PHP 5.0.0
nombre de clase/interfazEl parámetro debe ser una instanceof del nombre de la clase o interfaz dada.PHP 5.0.0

Más información

De forma automática PHP arreglará las incompatibilidades de tipos.

function incrementar(int $num): int
{
    return $num + 1;
}

echo incrementar(4.5);
// 5

Pero si quieres ser estricto deberás desactivar esta ayuda. En otras palabras, que si encuentra algún problema de tipos muestre un error y no aplique una mágica solución.

declare(strict_types=1);

function incrementar(int $num): int
{
    return $num + 1;
}

echo incrementar(4.5);
// PHP Fatal error:  Uncaught TypeError: Argument 1 passed to incrementar() must be of the type int, float given

Return con tipos alternativos

A partir de la versión 7.1 de PHP disponemos de la posibilidad de indicar si un return devuelve un tipo concreto o un null. Para ello solo habrá que añadir un interrogante en su inicio.

function nombre(): ?string
{
 
}

En el siguiente ejemplo podremos devolver un string o un null. Dependiendo de si el ganador esta entre los 3 primeros o no.

/**
 * Método que indica el tipo de metal que debe tener una medalla a partir del resultado
 * @param {int} $posicion - Posición
 * @return {string|null} - Tipo de metal
 */
function tipoDeMedalla(int $posicion): ?string
{
    switch ($posicion) {
        case 1:
            return 'Oro';
        case 2:
            return 'Plata';
        case 3:
            return 'Bronce';
        default:
            return null;
    }
}

echo tipoDeMedalla(2);
// Plata

echo tipoDeMedalla(34);
// null

Tal vez fue añadido esta característica por lo práctico que resulta al realizar testing.

Y de la versión PHP 8 se enriquece más las posibilidades ya que es posible indicar 2 tipos diferentes.

function nombre(): int|string
{
 
}

Nos puede ayudar en casos como, por ejemplo, dar un resultado alternativo o de seguridad.

/**
 * Método que duplica un número en positivo
 * @param {int} $numero - Número a duplicar
 * @return {float|string} - Resultado o mensaje de ayuda
 */
function duplicarPositivo(float $numero): float|string
{
    if ($numero > 0) {
        return $numero * 2;
    } else {
        return 'No puedes usar número en negativo o cero';
    }
}

echo duplicarPositivo(12.1);
// 24.2

echo duplicarPositivo(-45);
// 'No puedes usar número en negativo o cero'

Anónimas

Las funciones anónimas son cerradas y pueden ser declaradas sin ningún nombre. Son obligatorias cuando tengamos que pasar una función como un parámetro de otra.

function () {
    return 'Soy anónima';
}

En el siguiente ejemplo incrementamos en 1 cada número del array.

$numeros = [10, 20, 30, 40];
$numerosIncrementados = array_map(function ($numero) {
    return $numero + 1;
}, $numeros);

var_dump($numerosIncrementados);

/*
array(4) {
  [0]=>
  int(11)
  [1]=>
  int(21)
  [2]=>
  int(31)
  [3]=>
  int(41)
}
*/

Usar variables externas

Si vas a usar variables que están presentes en tu código, puedes enriquecer el contenido de la función usando use.

$tienda = 'pescadería';

function () use ($tienda) {
    return "Estoy en la $tienda";
}

Paradigma Funcional

Las funciones esenciales para iterar y gestionar un array son: array_walkarray_filterarray_map y array_reduce.

array_walk (Iterar)

Recorre un array, similar a un foreach.

array_walk({array}, {función});

En este ejemplo vamos a imprimir todas las ciudades.

<?php

// Diccionario
$apartamentos = [
    [
        'precio/noche' => 40,
        'ciudad' => 'Valencia',
        'wifi' => True,
        'pagina web' => 'https://hotel.com'
    ],
    [
        'precio/noche' => 87,
        'ciudad' => 'Calpe',
        'wifi' => True,
        'pagina web' => 'https://calpe.com'
    ],
    [
        'precio/noche' => 67,
        'ciudad' => 'Valencia',
        'wifi' => False,
        'pagina web' => 'https://denia.com'
    ],
    [
        'precio/noche' => 105,
        'ciudad' => 'Benidorm',
        'wifi' => False,
        'pagina web' => 'https://benidorm.com'
    ]
];

array_walk($apartamentos, function ($apartamento, $posicion) {
    echo $apartamento['ciudad'] . PHP_EOL;
});

/*
Valencia
Calpe
Valencia
Benidorm
*/

array_filter (filtrar)

Obtenemos un array a otro más pequeño.

array_filter({array}, {función});

En este ejemplo filtraremos $apartamentos para quedarnos con los que están en Valencia.

<?php

// Diccionario
$apartamentos = [
    [
        'precio/noche' => 40,
        'ciudad' => 'Valencia',
        'wifi' => True,
        'pagina web' => 'https://hotel.com'
    ],
    [
        'precio/noche' => 87,
        'ciudad' => 'Calpe',
        'wifi' => True,
        'pagina web' => 'https://calpe.com'
    ],
    [
        'precio/noche' => 67,
        'ciudad' => 'Valencia',
        'wifi' => False,
        'pagina web' => 'https://denia.com'
    ],
    [
        'precio/noche' => 105,
        'ciudad' => 'Benidorm',
        'wifi' => False,
        'pagina web' => 'https://benidorm.com'
    ]
];


$todosLosApartamentosValencia = array_filter($apartamentos, function ($apartamento) {
    return $apartamento['ciudad'] === 'Valencia';
});

var_dump($todosLosApartamentosValencia);

/*
array(2) {                                                                  
  [0]=>                                                                     
  array(4) {                                                                
    ["precio/noche"]=>   
    int(40)
    ["ciudad"]=>
    string(8) "Valencia"
    ["wifi"]=>
    bool(true)
    ["pagina web"]=>
    string(17) "https://hotel.com"
  }
  [2]=>
  array(4) {
    ["precio/noche"]=>
    int(67)
    ["ciudad"]=>
    string(8) "Valencia"
    ["wifi"]=>
    bool(false)
    ["pagina web"]=>
    string(17) "https://denia.com"
  }
}
*/

array_map (modificar)

Transforma el contenido de un array pero mantiene el número de elementos.

array_map({función}, {array});

En este ejemplo vamos a reducir el precio por noche en 1.

<?php

// Diccionario
$apartamentos = [
    [
        'precio/noche' => 40,
        'ciudad' => 'Valencia',
        'wifi' => True,
        'pagina web' => 'https://hotel.com'
    ],
    [
        'precio/noche' => 87,
        'ciudad' => 'Calpe',
        'wifi' => True,
        'pagina web' => 'https://calpe.com'
    ],
    [
        'precio/noche' => 67,
        'ciudad' => 'Valencia',
        'wifi' => False,
        'pagina web' => 'https://denia.com'
    ],
    [
        'precio/noche' => 105,
        'ciudad' => 'Benidorm',
        'wifi' => False,
        'pagina web' => 'https://benidorm.com'
    ]
];

$apartamentosMasBaratos = array_map(function ($apartamento) {
    return array_merge($apartamento, ['precio/noche' => $apartamento['precio/noche'] - 1]);
}, $apartamentos);

var_dump($apartamentosMasBaratos);
/*
array(4) {
  [0]=>
  array(4) {
    ["precio/noche"]=>
    int(39)
    ["ciudad"]=>
    string(8) "Valencia"
    ["wifi"]=>
    bool(true)
    ["pagina web"]=>
    string(17) "https://hotel.com"
  }
  [1]=>
  array(4) {
    ["precio/noche"]=>
    int(86)
    ["ciudad"]=>
    string(5) "Calpe"
    ["wifi"]=>
    bool(true)
    ["pagina web"]=>
    string(17) "https://calpe.com"
  }
  [2]=>
  array(4) {
    ["precio/noche"]=>
    int(66)
    ["ciudad"]=>
    string(8) "Valencia"
    ["wifi"]=>
    bool(false)
    ["pagina web"]=>
    string(17) "https://denia.com"
  }
  [3]=>
  array(4) {
    ["precio/noche"]=>
    int(104)
    ["ciudad"]=>
    string(8) "Benidorm"
    ["wifi"]=>
    bool(false)
    ["pagina web"]=>
    string(20) "https://benidorm.com"
  }
}
*/

array_reduce (calcular)

Obtiene un resultado a partir de un array.

array_reduce({array}, {función}, {inicial});

En este ejemplo vamos calcular cual es la media del precio por noche.

<?php

// Diccionario
$apartamentos = [
    [
        'precio/noche' => 40,
        'ciudad' => 'Valencia',
        'wifi' => True,
        'pagina web' => 'https://hotel.com'
    ],
    [
        'precio/noche' => 87,
        'ciudad' => 'Calpe',
        'wifi' => True,
        'pagina web' => 'https://calpe.com'
    ],
    [
        'precio/noche' => 67,
        'ciudad' => 'Valencia',
        'wifi' => False,
        'pagina web' => 'https://denia.com'
    ],
    [
        'precio/noche' => 105,
        'ciudad' => 'Benidorm',
        'wifi' => False,
        'pagina web' => 'https://benidorm.com'
    ]
];

$media = array_reduce($apartamentos, function ($acumulador, $apartamento) {
    return $apartamento['precio/noche'] + $acumulador;
}, 0) / count($apartamentos);

echo $media;
// 74.75

Formulario

Los formularios es la única manera de que el usuario nos transmita información, y tenemos una gran cantidad de posibilidades para recoger: textosnúmerosarchivoschecks

Para construir nuestro formulario necesitaremos la etiqueta <form> y dentro todos los <input>s que necesitemos.

<html>
    <body>
        <form>
            <?php
                var_dump($_REQUEST);
            ?>
            <input type="text" name="nombre">
            <input type="submit">
        </form>
    </body>
</html>

Utiliza var_dump($_REQUEST) para saber que variables te llegan de un formulario.

$_REQUEST es un array que contiene todas las variables que recibimos, lo cual nos simplifica a la hora de extraer cada elemento.

<html>
    <body>
        <?php if (isset($_REQUEST['nombre'])): ?>
            <p>¿De verdad te llamas <?php echo $_REQUEST['nombre']; ?>? Qué nombre más bonito.</p>
        <?php endif; ?>
        <form>
            <input type="text" name="nombre">
            <input type="submit">
        </form>
    </body>
</html>

La función isset() te indica si existe cualquier tipo de variable: local, global o dentro de un array.

Métodos de petición

Existe una gran cantidad de verbos HTTP, o métodos de petición, dentro del desarrollo web:

  • GET
  • POST
  • PUT
  • DELETE
  • HEAD
  • CONNECT
  • OPTIONS
  • TRACE
  • PATH

Todos ellos son como etiquetas que le damos a los datos para marcar su uso. Piensa en ellos como diferentes caminos para llegar al mismo sitio. Imagina que tienes que enviar 2 lámparas a una misma dirección y decides usar 2 compañias de mensajería diferentes: SEUR y CORREOS. Pero le avisas al destinatario que la lámpara que reciba por SEUR es para el salón y la otra tiene una bombilla rota que debe cambiar. Pasado el tiempo, cuando reciba los paquetes, tratará cada lámpara de forma especial. De esta manera puedes enviar varios datos en caminos diferentes para que el destinatario los use de forma distinta.

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    echo 'Llega algo por POST';
}

Método GET

Por defecto un formulario es enviado con el método, verbo, GET. Tiene una particularidad que no tiene el resto. Pongamos el siguiente código. Yo lo relleno con el nombre “Buda” y la edad “30”. A continuación pulso el botón de enviar.

<html>
    <body>
        <form method="get">
            <input type="text" name="nombre">
            <input type="number" name="edad">
            <input type="submit">
        </form>
    </body>
</html>

Si te fijas en la dirección, la URL, verás una ruta parecida a la siguiente.

http://localhost/?nombre=Buda&edad=30

GET nos permite ver en la barra del URL los datos dándonos la posibilidad de modificarlos.

Cualquier persona observadora podrá ver y modificar los datos. Ten mucho cuidado. Úsalo para información que no comprometa tu sitio: paginadores, mensajes, marcador de idioma…

Para recoger será usando siempre isset() con $_REQUEST.

$nombre = isset($_REQUEST['nombre']) ? $_REQUEST['nombre'] : '';
$edad = isset($_REQUEST['edad']) ? $_REQUEST['edad'] : '';

5-1

Método POST

El método POST será invisible al ojo del usuario. Recomendable cuando modificamos variables o una base de datos.

<html>
    <body>
        <form method="post">
            <input type="text" name="nombre">
            <input type="number" name="edad">
            <input type="submit">
        </form>
    </body>
</html>

5-25-3

Para obtener una varaible get también dispones de $_GET['nombre'] y para post $_POST['nombre'], pero $_REQUEST['nombre'] simplifica al unificar cualquier elemento que recibamos.

Action

Si no indicas lo contrario, la información se enviará a la misma página donde estemos. Con action podremos decirle al formulario que lleve los datos a otra URL.

<html>
    <body>
        <form method="post" action="login.php">
            <input type="text" name="nombre">
            <input type="number" name="edad">
            <input type="submit">
        </form>
    </body>
</html>

Evitar que se borren los campos

Cada vez que pulsas en un submit la página se refresca (se realiza una petición) y con ello se reinicia el formulario. ¿Qué pasa si me he equivocado en algún campo? Se pierde como lágrimas en la lluvia. El usuario tendría que volver a rellenarlo. Un truco para solucionarlo sería comprobar si existe el dato, y si es así rellenar su value.

<html>
    <body>
        <form>
            <input type="text" placeholder="Nombre" name="nombre"<?php if (isset($_REQUEST['nombre']) && $_REQUEST['nombre'] != ''): ?> value="<?php echo $_REQUEST['nombre']; ?>"<?php endif; ?>>
            <input type="number" placeholder="Edad" name="edad"<?php if (isset($_REQUEST['edad']) && $_REQUEST['edad'] != ''): ?> value="<?php echo $_REQUEST['edad']; ?>"<?php endif; ?>>
            <input type="submit">
        </form>
    </body>
</html>

5-4

Campos ocultos

En ciertas ocasiones necesitaremos enviar por el formulario una información que no sea visible por el usuario: id, token, un histórico, un cálculo, etc. Para ello disponemos de un input especial con el tipo hidden.

<html>
    <body>
        <form>
            <input type="hidden" name="maquina-enigma" value="149">
            
            <input type="submit">
        </form>
    </body>
</html>

En este caso, el visitante solo visualizará un botón pero al enviarse llegará la data maquina-enigma con el valor 149.

$codigoSecreto = isset($_REQUEST['maquina-enigma']) ? $_REQUEST['maquina-enigma'] : '';
echo $codigoSecreto;

// 149

También puede ser utilizado para enviar arrays. Tan solo debemos repetir el name dejando presente [].

<html>
    <body>
        <form>
            <input type="hidden" name="filtros[]" value="precio">
            <input type="hidden" name="filtros[]" value="valoracion">
            <input type="hidden" name="filtros[]" value="fecha">

            <input type="submit">
        </form>
    </body>
</html>
$misFiltros = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : [];
var_dump($misFiltros);

// ['precio', 'valoracion', 'fecha']

Aunque también nos podemos apoyar en las funciones serialize() y unserialize(). Nos convertirá los arrays en texto o texto en arrays.

echo serialize(['mañana', 'tarde', 'noche']);
// a:3:{i:0;s:7:"mañana";i:1;s:5:"tarde";i:2;s:5:"noche";}

var_dump(unserialize('a:3:{i:0;s:7:"mañana";i:1;s:5:"tarde";i:2;s:5:"noche";}'));
// ['mañana', 'tarde', 'noche']

Estas funciones nos permiten mantener estructuras avanzadas como los diccionarios.

echo serialize(['id' => 234, 'nombre' => 'Sauron']);
// a:2:{s:2:"id";i:234;s:6:"nombre";s:6:"Sauron";}

var_dump(unserialize('a:2:{s:2:"id";i:234;s:6:"nombre";s:6:"Sauron";}'));
// ['id' => 234, 'nombre' => 'Sauron']

Si volvemos al ejemplo anterior, deberemos tener cuidado con las comillas dobles que entrarán en conflicto con las propias de atributo HTML. En su lugar envuelve con comillas simples.

<?php
$filtros = ['precio', 'valoracion', 'fecha'];
?>

<html>
    <body>
        <form>
            <input type="hidden" name="filtros" value='<?= serialize($filtros); ?>'>

            <input type="submit">
        </form>
    </body>
</html>
$filtroSerializados = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : '';
$filtroDeserializados = unserialize($filtroSerializados);
var_dump($filtroDeserializados);

// ['precio', 'valoracion', 'fecha']

Es inseguro serializar un string proviene de un cliente. Se práctica porque es cómodo y rápido para recuperar array u objetos, aunque lamentablemente debes evitarlo ya que es posible manipular el texto recibido para inyectar código malicioso en el backend. En su lugar recibe un JSON, ya que sus campos son muy limitados, y construye manualmente todos los elementos. Conoce todos los detalles al respecto en PortSwigger.

Una última opción, la cual es actualmente un estándar cuando hablamos de una estructura de datos, es trabajar con JSON.

echo json_encode(['id' => 234, 'nombre' => 'Sauron']);
// {"id":234,"nombre":"Sauron"}

var_dump(json_decode('{"id":234,"nombre":"Sauron"}'));
// ['id' => 234, 'nombre' => 'Sauron']

Si utilizamos el ejemplo anterior quedaría tal que así.

<?php
$filtros = ['precio', 'valoracion', 'fecha'];
?>

<html>
    <body>
        <form>
            <input type="hidden" name="filtros" value='<?= json_encode($filtros); ?>'>

            <input type="submit">
        </form>
    </body>
</html>
$filtroEnJSON = isset($_REQUEST['filtros']) ? $_REQUEST['filtros'] : '';
$filtro = json_decode($filtroEnJSON);
var_dump($filtro);

// ['precio', 'valoracion', 'fecha']

Una de las tareas más laboriosas es validar una información que llega de un formulario. Es peligroso meter cualquier cosa que llegue a nuestra Base de Datos. El usuario es torpe o malintencionado.

  • Introducir e-mails sin sentidos.
  • Letras en lugar de números (por ejemplo al pedir la edad).
  • Dejar campos vacíos cuando deben ser obligatorios.
  • Dar malos formatos. (por ejemplo en un número de teléfono).
  • Una longitud muy corta o muy larga de un texto.
  • Código mal intencionado.
  • Y largo etcétera.

No existe una única manera de validar, cada programador tiene su método. Pero lo que siempre hay que realizar son unos pasos estrictos:

  1. Enviar datos desde nuestro formulario.
  2. Recoger los datos.
  3. Validar cada campo.
  4. Mostrar al usuario los errores con un mensaje.
  5. Si existen errores, mantenerse en la página.
  6. Si no existen errores, generar la acción que busques e informar al usuario del éxito.

Aunque valides en Javascript (frontend) debemos validar con PHP (backend). Los datos pueden ser alterados desde el navegador. ¡Nunca te fíes del usuario!

Nativamente PHP nos proporciona una función llamada filter_var.

filter_var('correo@ejemplo.com', FILTER_VALIDATE_EMAIL);
// True

Solo podemos validar el formato, no que sea un correo real. Para ello existen servicios de terceros como Mailgun.

Las diferentes validaciones disponibles puedes consultarlo en tipos de filtros.

A continuación puedes ver analizar un ejemplo completo y real donde se ha validado cada campo y se informa al usuario en caso de encontrarse cualquier problema.

<html>
    <body>
        <?php
            //======================================================================
            // PROCESAR FORMULARIO 
            //======================================================================
            // Comprobamos si nos llega los datos por POST
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                //-----------------------------------------------------
                // Funciones Para Validar
                //-----------------------------------------------------

                /**
                 * Método que valida si un texto no esta vacío
                 * @param {string} - Texto a validar
                 * @return {boolean}
                 */
                function validar_requerido(string $texto): bool
                {
                    return !(trim($texto) == '');
                }

                /**
                 * Método que valida si es un número entero 
                 * @param {string} - Número a validar
                 * @return {bool}
                 */
                function validar_entero(string $numero): bool
                {
                    return filter_var($numero, FILTER_VALIDATE_INT);
                }

                /**
                 * Método que valida si el texto tiene un formato válido de E-Mail
                 * @param {string} - Email
                 * @return {bool}
                 */
                function validar_email(string $texto): bool
                {
                    return filter_var($texto, FILTER_VALIDATE_EMAIL);
                }

                //-----------------------------------------------------
                // Variables
                //-----------------------------------------------------
                $errores = [];
                $nombre = isset($_REQUEST['nombre']) ? $_REQUEST['nombre'] : null;
                $edad = isset($_REQUEST['edad']) ? $_REQUEST['edad'] : null;
                $email = isset($_REQUEST['email']) ? $_REQUEST['email'] : null;

                //-----------------------------------------------------
                // Validaciones
                //-----------------------------------------------------
                // Nombre
                if (!validar_requerido($nombre)) {
                    $errores[] = 'El campo Nombre es obligatorio.';
                }
                // Edad
                if (!validar_entero($edad)) {
                    $errores[] = 'El campo de Edad debe ser un número.';
                }
                // Email
                if (!validar_email($email)) {
                    $errores[] = 'El campo de Email tiene un formato no válido.';
                }

                //-----------------------------------------------------
                // Lógica
                //-----------------------------------------------------
                if (!isset($errores)) {
                    // Enviamos el correo
                }
            }
        ?>
        <!-- Mostramos errores por HTML -->
        <?php if (isset($errores)): ?>
        <ul class="errores">
            <?php foreach ($errores as $error): ?>
                <li><?= $error ?></li>;
            <?php endforeach; ?> 
        </ul>
        <?php endif; ?>
        <!-- Formulario -->
        <form method="post">
            <p>
                <!-- Campo nombre -->
                <input type="text" name="nombre" placeholder="Nombre">
            </p>
            <p>
                <!-- Campo edad -->
                <input type="text" name="edad" placeholder="Edad">
            </p>
            <p>
                <!-- Campo Email -->
                <input type="text" name="email" placeholder="Email">
            </p>
            <p>
                <!-- Botón submit -->
                <input type="submit" value="Enviar">
            </p>
        </form>
    </body>
</html>

Puedes utilizarlo como una base para futuros trabajos.

Ficheros

Es posible importar o llamar el código desde otro archivo con PHP. De esta manera conseguiremos dividir nuestras página dinámicas en fragmentos más pequeños y fáciles de gestionar evitando el famoso código Spaghetti (escribir todo nuestro código en un solo fichero con un interminable número de líneas). Para esta buena práctica disponemos en nuestro bat-cinturón de hasta 4 herramientas diferentes.

FunciónDescripciónCaso de errorEjemplo
include ''Incluye el fichero en cada ocasión.Da una advertenia, pero continua la ejecución.include 'tu_archivo.php'
include_once ''Incluye el fichero en una ocasión.Da una advertenia, pero continua la ejecución.include_once 'tu_archivo.php'
require ''Incluye el fichero en cada ocasión.Para la ejecución (Error fatal).require 'tu_archivo.php'
require_once ''Incluye el fichero en una ocasión.Para la ejecución (Error fatal).require_once 'tu_archivo.php'

Veamos con un ejemplo como funciona. Voy a tener un archivo llamado header.php con el siguiente contenido.

<html>
    <head>
    </head>
    <body>

Otro con el nombre footer.php.

        <footer>Soy yo</footer>
    </body>
</html>

Ahora creo un fichero nuevo.

<?php include 'header.php'; ?>
<h1>Inicio</h1>
<?php include 'footer.php'; ?>

Me daria el siguiente HTML.

<html>
    <head>
    </head>
    <body>
        <h1>Inicio</h1>
        <footer>Soy yo</footer>
    </body>
</html>

Potente, ¿verdad? Evitaremos repartir partes de nuestro código que sean muy reiterativas.

En esta ocasión voy a repetir el include de footer.

Ahora creo un fichero nuevo.

<?php include 'header.php'; ?>
<h1>Inicio</h1>
<?php include 'footer.php'; ?>
<?php include 'footer.php'; ?>

Lo que me generaría un pie duplicado.

<html>
    <head>
    </head>
    <body>
        <h1>Inicio</h1>
        <footer>Soy yo</footer>
    </body>
</html>
        <footer>Soy yo</footer>
    </body>
</html>

Lo podemos prevenir con include_once.

<?php include 'header.php'; ?>
<h1>Inicio</h1>
<?php include_once 'footer.php'; ?>
<?php include_once 'footer.php'; ?>

Si ya ha sido llamado, lo ingora.

<html>
    <head>
    </head>
    <body>
        <h1>Inicio</h1>
        <footer>Soy yo</footer>
    </body>
</html>

Subir un archivo

Un fichero es un elemento en binario que no es ni un número o ni un texto: imagen, video, música, doc, iso… Nosotros somos incapaces de leerlo a no ser que tengamos un ojo biónico y un chip en el cerebro. Si careces de estos dos requisitos solo podrás subirlo, por medio de un formulario, y almacenarlo en una carpeta.

Se debe tratar de una forma especial. Necesitaremos usar siempre el method POST y añadir enctype=”multipart/form-data”. Por último usar el input de tipo archivo (file).

<!-- Formulario -->
<form method="post" enctype="multipart/form-data">
    <p>
        <!-- Campo imagen -->
        <input type="file" name="fichero_usuario">
    </p>
    <p>
        <!-- Botón submit -->
        <input type="submit" value="Enviar">
    </p>
</form>

Cuando nuestro formulario sea enviado el archivo estará almacenado en una variable llamada $_FILES. La cual es un array con toda la información que vas a necesitar.

NombreEjemplo de contenidoDescripción
$_FILES[‘fichero_usuario’][‘name’]‘foto_en_la_playa.jpg’Nombre del archivo
$_FILES[‘fichero_usuario’][‘type’]‘image/png’MIME (formato del archivo)
$_FILES[‘fichero_usuario’][‘size’]3232424Tamaño en bytes (5MB -> 5 x 1024 x 1024 bytes)
$_FILES[‘fichero_usuario’][‘error’]0Código de error. El 0 es que todo ha ido bien, los otros puedes encontrarlos aquí
$_FILES[‘fichero_usuario’][‘tmp_name’]213Nombre temporal

Ahora solo tendremos que moverlo de la carpeta temporal a la definitiva, usando el método move_uploaded_file().

move_uploaded_file($_FILES['fichero_usuario']['tmp_name'], $fichero_subido);

Aquí puedes ver un ejemplo completo.

<html>
    <body>
        <?php
            //======================================================================
            // PROCESAR IMAGEN 
            //======================================================================
            // Comprobamos si nos llega los datos por POST
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                // Definir directorio donde se guardará
                $dir_subida = './subidos/';
                // Definir la ruta final del archivo
                $fichero_subido = $dir_subida . basename($_FILES['fichero_usuario']['name']);
                // Mueve el archivo de la carpeta temporal a la ruta definida
                if (move_uploaded_file($_FILES['fichero_usuario']['tmp_name'], $fichero_subido)) {
                    // Mensaje de confirmación donde todo ha ido bien
                    echo '<p>Se subió perfectamente.</p>';
                    // Muestra la imagen que acaba de ser subida
                    echo '<p><img width="500" src="' . $fichero_subido . '"></p>';
                } else {
                    // Mensaje de error: ¿Límite de tamaño? ¿Ataque?
                    echo '<p>¡Ups! Algo ha pasado.</p>';
                }
            }
        ?>
        <!-- Formulario -->
        <form method="post" enctype="multipart/form-data">
            <p>
                <!-- Campo imagen -->
                <input type="file" name="fichero_usuario">
            </p>
            <p>
                <!-- Botón submit -->
                <input type="submit" value="Enviar">
            </p>
        </form>
    </body>
</html>

Multiarchivo (subir varios archivos)

Es posible subir varios archivos bajo el mismo nombre. Solo habrá que añadir unos corchetes ([]) después del name como si fuera un array.

<!-- Formulario -->
<form method="post" enctype="multipart/form-data">
    <p>
        <!-- Campos de imágenes -->
        <input type="file" name="imagen[]">
        <input type="file" name="imagen[]">
        <input type="file" name="imagen[]">
    </p>
    <p>
        <!-- Botón submit -->
        <input type="submit" value="Enviar">
    </p>
</form>

Al recibir los datos tendremos que iterar la variable, igual que un array. Es recomendable comprobar en cada caso que el archivo se ha subido correctamente.

// Comprobamos si nos llega los datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    // Iteramos todos los archivos
    foreach ($_FILES["imagen"]["error"] as $posicion => $error) {
        // Comprobamos si se ha subido correctamente
        if ($error == UPLOAD_ERR_OK) {
            // Definir directorio donde se guardará
            $dir_subida = './subidos/';
            // Definir la ruta final del archivo
            $fichero_subido = $dir_subida . basename($_FILES['imagen']['name'][$posicion]);
            // Mueve el archivo de la carpeta temporal a la ruta definida
            if (move_uploaded_file($_FILES['imagen']['tmp_name'][$posicion], $fichero_subido)) {
                // Mensaje de confirmación donde todo ha ido bien
                echo '<p>Se subió perfectamente' . $_FILES['imagen']['name'][$posicion] . '.</p>';
                // Muestra la imagen que acaba de ser subida
                echo '<p><img width="500" src="' . $fichero_subido . '"></p>';
            } else {
                // Mensaje de error: ¿Límite de tamaño? ¿Ataque?
                echo '<p>¡Ups! Algo ha pasado.</p>';
            }
        }
    }
}

Junto quedaría de la siguiente forma.

<html>
    <body>
        <?php
            //======================================================================
            // PROCESAR IMAGENES 
            //======================================================================
            // Comprobamos si nos llega los datos por POST
            if ($_SERVER['REQUEST_METHOD'] == 'POST') {
                // Iteramos todos los archivos
                foreach ($_FILES["imagen"]["error"] as $posicion => $error) {
                    // Comprobamos si se ha subido correctamente
                    if ($error == UPLOAD_ERR_OK) {
                        // Definir directorio donde se guardará
                        $dir_subida = './subidos/';
                        // Definir la ruta final del archivo
                        $fichero_subido = $dir_subida . basename($_FILES['imagen']['name'][$posicion]);
                        // Mueve el archivo de la carpeta temporal a la ruta definida
                        if (move_uploaded_file($_FILES['imagen']['tmp_name'][$posicion], $fichero_subido)) {
                            // Mensaje de confirmación donde todo ha ido bien
                            echo '<p>Se subió perfectamente' . $_FILES['imagen']['name'][$posicion] . '.</p>';
                            // Muestra la imagen que acaba de ser subida
                            echo '<p><img width="500" src="' . $fichero_subido . '"></p>';
                        } else {
                            // Mensaje de error: ¿Límite de tamaño? ¿Ataque?
                            echo '<p>¡Ups! Algo ha pasado.</p>';
                        }
                    }
                }
            }
        ?>
        <!-- Formulario -->
        <form method="post" enctype="multipart/form-data">
            <p>
                <!-- Campos de imágenes -->
                <input type="file" name="imagen[]">
                <input type="file" name="imagen[]">
                <input type="file" name="imagen[]">
            </p>
            <p>
                <!-- Botón submit -->
                <input type="submit" value="Enviar">
            </p>
        </form>
    </body>
</html>

Borrar archivos

Para eliminar un archivo debemos usar el método unlink.

unlink('archivo');

Tan solo hay que dar la ruta que deseamos.

unlink('subidos/coche_rojo.jpg');

Evitar que se sobrescriba

¿Qué pasa si subimos dos archivos con el mismo nombre? Pues que el anterior desaparecería, se sobrescribiría por tener el mismo nombre y guardarse en el mismo lugar. Debemos garantiza que el archivo posee un nombre único.

Un truco para solucionarlo generando un hash, o una secuencia alfanumérica única por cada archivo que sustituya al nombre. Un algoritmo muy popular es SHA-1.

En criptografía, SHA-1 (Secure Hash Algorithm 1) es una función hash criptográfica que ha sido rota, pero que sigue siendo ampliamente utilizada para generar un número hexadecimal de 40 dígitos. Su autor fue la Agencia de Seguridad Nacional de Estados Unidos, siendo usando para el procesamiento de información de Estados Unidos.

Si quisiéramos obtener un hash de un texto, deberíamos usar sha1().

echo sha1('texto');
// ea631551f5569f612dd702b900c596c2a99c0dfd

Para archivos disponemos de una función determinada llamada sha1_file().

echo sha1_file($_FILES['fichero_usuario']['tmp_name']);
// 2d68e69c476166978146c4f8e523ba8f87acbbc3

Si tuvieramos un archivo llamado reloj.jpg.

$fichero_subido = $dir_subida . sha1_file($_FILES['fichero_usuario']['tmp_name']) . basename($_FILES['fichero_usuario']['name']);
echo $fichero_subido;
// subidos/2d68e69c476166978146c4f8e523ba8f87acbbc3reloj.jpg

Por muchos archivos reloj.jpg que suban nunca se sobrescribirán, a no ser que a nivel binario sean exactamente iguales (lo cual tampoco sería un problema porque sería el mismo fichero).

Tamaño máximo

Si quieres limitar el tamaño de todos los archivos puedes hacerlo añadiendo un input especial.

<input type="hidden" name="MAX_FILE_SIZE" value="20000" />

El value se mide en bytes.

Si un archivo supera nuestra frontera dará un error, pero nunca llegará a subirse.

Otra forma de cambiarlo, en este caso permanente, es modificando unas variables de PHP en su archivo de configuración.

sudo nano /etc/php/{versión}/cli/php.ini

Edita las siguientes variables si quieres limitarlo a 100Mb.

upload_max_filesize=100Mb
post_max_size=100Mb

Igualmente valida el tamaño con PHP, es fácil manipular el límite dentro del navegador. Recuerda: nunca te fíes del usuario.

Procesamiento de imágenes

PHP no esta solamente limitado a la generación de HTML y mover archivos, también puede procesar imágenes. Existen una multitud de posibilidades.

  • Redimensionar (utilizado para crear miniaturas).
  • Recortar.
  • Aplicar filtros de color.
  • Crear imágenes (como suena).
  • Añadir marcas de agua.
  • Cambiar de formato.

Para crear una minuatura podrías hacerlo usando la libreria nativa Imagick.

Primero tendremos que instalarla en el sistema. Con Ubuntu o Debian es muy sencillo.

sudo apt install php-imagick

Aahora ya puedes trabajar con ella. En el siguiente ejemplo se captura imagen.jpg y se redimensiona a 100px de ancho. Por último se guarda con el nombre de miniatura.jpg.

$imagen = new Imagick('imagen.jpg');

// Si se proporciona 0 como parámetro de ancho o alto,
// se mantiene la proporción de aspecto
$imagen->thumbnailImage(100, 0);

// La guarda
file_put_contents('miniatura.jpg', $imagen);

Dispone de diversas herramientas para manipular formatos tan conocidos como: JPEG, GIF, PNG y WebP (entre otros). Puedes ver más en la documentación.

Ejemplo completo

Puedes ver un ejemplo que recoge todos los casos anteriores.

  • Valida que se ha adjuntado una imagen en el formulario.
  • Valida que sea una imagen en jpg o png.
  • Valida que no supere cierto tamaño. En este caso 2Mb.
  • Crea una miniatura. En este caso de 100px de ancho.
  • Cambia el nombre aleatorio para evitar posibles conflictos con otros archivos.
  • Muestra la miniatura en el HTML.
<?php

//======================================================================
// VARIABLES
//======================================================================
$errorAvatar = 0;
$avatar = null;
$rutaThumbnail = null;

// Definir directorio donde se guardará
define('PATH_AVATAR', './subidos/');
define('PATH_AVATAR_THUMBNAIL', './subidos/thumbnails/');

// Tamanyo max avatar: 2 Mb
define('MAX_SIZE_AVATAR_MB', 2);
define('MAX_SIZE_AVATAR', MAX_SIZE_AVATAR_MB * 1024 * 1024);
// En /etc/php/7.4/cli/php.ini edita las siguientes variables
// upload_max_filesize=100Mb
// post_max_size=100Mb

// Anchura miniatura
define('WIDTH_THUMBNAIL', 100);

//======================================================================
// PROCESAR FORMULARIO
//======================================================================

// Comprobamos si nos llega los datos por POST
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES)) {

    //-----------------------------------------------------
    //  Recoger avatar
    //-----------------------------------------------------

    // Verifica si existe el directorio, y en caso contrario lo crea
    if (!is_dir(PATH_AVATAR_THUMBNAIL)) {
        mkdir(PATH_AVATAR_THUMBNAIL, 0775, true);
    }
    // Definir la ruta final del archivo
    $nombreFoto = sha1_file($_FILES['avatar']['tmp_name']) . basename($_FILES['avatar']['name']);
    $ficheroSubido = PATH_AVATAR . $nombreFoto;

    //-----------------------------------------------------
    //  Control de errores
    //-----------------------------------------------------

    // Tamanyo maximo
    if ($_FILES['avatar']['size'] > MAX_SIZE_AVATAR) {
        $errorAvatar = 1;
    }

    // Solo JPG y PNG
    if ($_FILES['avatar']['type'] !== 'image/png' && $_FILES['avatar']['type'] !== 'image/jpeg') {
        $errorAvatar = 2;
    }

    // Obligatorio
    if ($_FILES['avatar']['size'] === 0) {
        $errorAvatar = 3;
    }

    //-----------------------------------------------------
    //  Procesar imagen
    //-----------------------------------------------------

    if ($errorAvatar === 0) {
        if (move_uploaded_file($_FILES['avatar']['tmp_name'], $ficheroSubido)) {
            // Mueve el archivo de la carpeta temporal a la ruta definida
            $avatar = $ficheroSubido;

            // Creamos una miniatura
            // No olvides instalarlo con: sudo apt install php-imagick
            $imagen = new Imagick($avatar);

            // Si se proporciona 0 como parámetro de ancho o alto,
            // se mantiene la proporción de aspecto
            $imagen->thumbnailImage(WIDTH_THUMBNAIL, 0);
            $rutaThumbnail = PATH_AVATAR_THUMBNAIL . $nombreFoto;
            file_put_contents($rutaThumbnail, $imagen);
        }
    }
}

?>
<!doctype html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Perfil</title>
</head>
<body>
    <?php if (isset($rutaThumbnail)): ?>
        <img src="<?= $rutaThumbnail; ?>" alt="mi avatar" width="<?= WIDTH_THUMBNAIL ?>">
    <?php endif; ?>
    <form method="post" enctype="multipart/form-data">
        <p>
            <label>
                Foto:
                <input type="file" name="avatar">
            </label>
        </p>
        <?php if ($errorAvatar === 1): ?>
        <p style="color: red">
            Tamaño demasiado grande, intente que tenga menos de <?= MAX_SIZE_AVATAR_MB ?>Mb
        </p>
        <?php elseif ($errorAvatar === 2): ?>
        <p style="color: red">
            Solo admitido imagenes en JPG o PNG.
        </p>
        <?php elseif ($errorAvatar === 3): ?>
        <p style="color: red">
            Debes incluir una imagen
        </p>
        <?php endif; ?>
        <p>
            <input type="submit" value="Guardar">
        </p>
    </form>
</body>
</html>

https://programadorwebvalencia.com/cursos

Biografia php

SQL con PHP

Para conectar PHP a una base de datos MySQL, puedes usar dos extensiones principales: MySQLi (MySQL Improved) y PDO (PHP Data Objects). Aquí te muestro cómo hacerlo con ambas:

Usando MySQLi

Estilo Orientado a Objetos

PHP

<?php
$servername = "localhost";
$username = "tu_usuario";
$password = "tu_contraseña";
$dbname = "tu_base_de_datos";

// Crear conexión
$conn = new mysqli($servername, $username, $password, $dbname);

// Verificar conexión
if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}
echo "Conexión exitosa";
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

Estilo Procedural

PHP

<?php
$servername = "localhost";
$username = "tu_usuario";
$password = "tu_contraseña";
$dbname = "tu_base_de_datos";

// Crear conexión
$conn = mysqli_connect($servername, $username, $password, $dbname);

// Verificar conexión
if (!$conn) {
    die("Conexión fallida: " . mysqli_connect_error());
}
echo "Conexión exitosa";
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

Usando PDO

PHP

<?php
$dsn = "mysql:host=localhost;dbname=tu_base_de_datos";
$username = "tu_usuario";
$password = "tu_contraseña";

try {
    $conn = new PDO($dsn, $username, $password);
    // Establecer el modo de error de PDO a excepción
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    echo "Conexión exitosa";
} catch(PDOException $e) {
    echo "Conexión fallida: " . $e->getMessage();
}
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

Explicación

  • MySQLi: Específico para MySQL y ofrece dos interfaces: orientada a objetos y procedural.
  • PDO: Soporta múltiples bases de datos (no solo MySQL) y usa una interfaz orientada a objetos.

Ambos métodos son seguros y eficientes, pero PDO es más flexible si planeas trabajar con diferentes tipos de bases de datos en el futuro

Aquí tienes algunos ejemplos de cómo realizar consultas básicas de SQL desde PHP usando MySQLi y PDO.

Usando MySQLi

Estilo Orientado a Objetos

SELECT (Consultar datos)

PHP

<?php
$servername = "localhost";
$username = "tu_usuario";
$password = "tu_contraseña";
$dbname = "tu_base_de_datos";

// Crear conexión
$conn = new mysqli($servername, $username, $password, $dbname);

// Verificar conexión
if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}

// Realizar consulta
$sql = "SELECT id, nombre, apellido FROM MiTabla";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    // Salida de datos de cada fila
    while($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"]. " - Nombre: " . $row["nombre"]. " " . $row["apellido"]. "<br>";
    }
} else {
    echo "0 resultados";
}
$conn->close();
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

INSERT (Insertar datos)

PHP

<?php
$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}

$sql = "INSERT INTO MiTabla (nombre, apellido, email) VALUES ('John', 'Doe', 'john@example.com')";

if ($conn->query($sql) === TRUE) {
    echo "Nuevo registro creado exitosamente";
} else {
    echo "Error: " . $sql . "<br>" . $conn->error;
}

$conn->close();
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

UPDATE (Actualizar datos)

PHP

<?php
$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}

$sql = "UPDATE MiTabla SET apellido='Smith' WHERE id=1";

if ($conn->query($sql) === TRUE) {
    echo "Registro actualizado exitosamente";
} else {
    echo "Error actualizando registro: " . $conn->error;
}

$conn->close();
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

DELETE (Eliminar datos)

PHP

<?php
$conn = new mysqli($servername, $username, $password, $dbname);

if ($conn->connect_error) {
    die("Conexión fallida: " . $conn->connect_error);
}

$sql = "DELETE FROM MiTabla WHERE id=1";

if ($conn->query($sql) === TRUE) {
    echo "Registro eliminado exitosamente";
} else {
    echo "Error eliminando registro: " . $conn->error;
}

$conn->close();
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

Usando PDO

SELECT (Consultar datos)

PHP

<?php
$dsn = "mysql:host=localhost;dbname=tu_base_de_datos";
$username = "tu_usuario";
$password = "tu_contraseña";

try {
    $conn = new PDO($dsn, $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $conn->prepare("SELECT id, nombre, apellido FROM MiTabla");
    $stmt->execute();

    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

    foreach($result as $row) {
        echo "id: " . $row["id"]. " - Nombre: " . $row["nombre"]. " " . $row["apellido"]. "<br>";
    }
} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

INSERT (Insertar datos)

PHP

<?php
try {
    $conn = new PDO($dsn, $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "INSERT INTO MiTabla (nombre, apellido, email) VALUES ('John', 'Doe', 'john@example.com')";
    $conn->exec($sql);
    echo "Nuevo registro creado exitosamente";
} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

UPDATE (Actualizar datos)

PHP

<?php
try {
    $conn = new PDO($dsn, $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "UPDATE MiTabla SET apellido='Smith' WHERE id=1";
    $stmt = $conn->prepare($sql);
    $stmt->execute();

    echo "Registro actualizado exitosamente";
} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

DELETE (Eliminar datos)

PHP

<?php
try {
    $conn = new PDO($dsn, $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $sql = "DELETE FROM MiTabla WHERE id=1";
    $conn->exec($sql);

    echo "Registro eliminado exitosamente";
} catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

Código generado por IA. Revisar y usar cuidadosamente. Más información sobre preguntas frecuentes.

Estos ejemplos cubren las operaciones básicas de CRUD (Crear, Leer, Actualizar, Eliminar) en PHP usando MySQLi y PDO

Publicaciones Similares

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *