Saltar al contenido principal

Tutorial básico de PHP

Documento escrito por: Oussama Osman

Puedes ver todos los documentos de este autor aquí.

Empezar php

Para usar php, necesitamos crear un archivo .php. Una vez eso, escribiremos las etiquetas php:

<?php
// el código aquí
?>

Como trabaja PHP

Primero de todo, PHP corre en el servidor con lo cual, para hacerlo funcionar necesitaremos un servidor. Recomiendo para principiantes el iniciar con XAMPP, que instalará todo lo que necesitamos : web de xampp

Cuando entramos a una página, el navegador manda una petición al servidor, entonces es cuando el código PHP es procesado (el navegador no entiende ni procesa el código php), depués de eso, el servidor envía el html correcto de vuelta al navegador y es entonces cuando el usuario ve y puede interactuar con la página.

Comentarios

  • comentarios de una sola línea: //comentarios en línea

  • comentarios de multiples líneas:

    /*
    Este es un comentario
    multilínea en php
    */

¿Los puntos y comas (;) al final de la línea son vitales!

Salida

echo

Puede renderizar cadenas de texto, números, html, etc....

echo 123, 'Hola', 10.5; //123Hola10.5

print

Parecido a echo pero solo pudiendo renderizar un elemento.

print 123; // 123

Es una función y es usada sobre todo para renderizar arrays y valores únicos.

print_r([1,2,3]);
// Array ( [0] => 1 [1] => 2 [2] => 3 )

var_dump()

Una función que devuelve más información (tipo de dato y longitud).

var_dump('Hola'); // string(4) "Hola"

var_dump([1,2,3]);
// array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

var_export()

Similar al var_dump() pero esto devuelve una string representation of a variable.

var_export('Hola'); // 'Hola'

var_export([1,2,3]);
// array ( 0 => 1, 1 => 2, 2 => 3, )

Variables

Tipos

  • String : Una serie de caracteres rodeados por comillas o comillas dobles
  • Integer : Número entero
  • Float : Número decimal
  • Boolean : Verdadero o falso
  • Array : Esta es una variable especial, la cual puede tener más de un valor
  • Object : Una clase
  • NULL : Variable vacía
  • Resource : Variable special que tiene un recurso

Reglas

  • Las variables deben tener como prefijo $.
  • Las variables deben empezar con una letra o barra baja ( _ ).
  • Las variables no pueden empezar con un número.
  • Las variables solo pueden contener caracteres alfanuméricos y barras bajas :
    • A-z
    • 0-9
    • _
  • Las variables distinguen entre mayúsculas y minúsculas ($nombre no es igual que $NOMBRE o $Nombre).

DEclarando variables

$nombre = 'Federico'; // String
$edad = 25; //Number
$dinero_en_el_banco = 763.83; // Float
$tiene_hijos = false; // Boolean

Texto con variables

Para renderizar el valor de una variable en una cadena de texto, la puedes concatenar :

echo $nombre . ' tiene ' . $edad . ' años';
// Federico tiene 25 años

o, con comillas dobles :

echo "$nombre tiene $edad años";
// Federico tiene 25 años

también, como en javascript, puedes añadir {} a las variables :

echo "${nombre} tiene ${edad} años";
// Federico tiene 25 años

Operaciones

echo 10 + 5; // 15
echo '10' + '5'; // 15
echo 10 - 5; // 5
echo 10 * 5 ; // 50
echo 10 / 5; // 2
echo 10 % 5; // 0

Constantes

Una constante es un dato o valor que nunca va a cambiar a lo largo de nuestra aplicación (base de datos, credenciales, hosts, etc...)

Para crear una constante tienes que usar lo función define() :

define('HOST','localhost');
define('PUERTO','3000');

echo HOST; // localhost
var_dump(PUERTO); // int(3000)

Arrays

Los arrays son tipos o estructuras de datos que tienen o albergan multiples valores.

Hay principalmente, dos formas distintas de crearlos :

  • $numeros = [15,22,36,41];
  • $frutas = array('manzana','naranja','pera');

Para renderizar los valores del array, podemos usar los métodos específicos mencionados en la sección de salida :

print_r($numeros);
// Array ( [0] => 15 [1] => 22 [2] => 36 [3] => 41 )

var_dump($numeros);
// array(4) { [0]=> int(15) [1]=> int(22) [2]=> int(36) [3]=> int(41) }

var_export($numeros)
// array ( 0 => 15, 1 => 22, 2 => 36, 3 => 41, )

Si queremos acceder a un valor concreto, podemos hacerlo con su índice, pero, ten cuidado, porque el índice de los arrays empieza en 0, por lo tanto, el primer valor guardado está en la posición 0:

echo $frutas[0] // manzana
echo $frutas[1] // naranja

Array asociativo

El array asociativo es una forma de crear un array y personalizar el índice.

Las keys (índices) pueden ser números o texto

  1. Con Números :
  •   $colores = [
    1 => 'rojo',
    2 => 'azul',
    3 => 'verde',
    5 => 'morado',
    7 => 'gris',
    11 => 'marrón'
    ];
  • print_r($colores);
    // Array ( [1] => rojo [2] => azul [3] => verde [5] => morado [7] => gris [11] => marrón )

    var_dump($colores);
    // array(6) { [1]=> string(3) "rojo" [2]=> string(4) "azul" [3]=> string(5) "verde" [5]=> string(6) "morado" [7]=> string(4) "gris" [11]=> string(5) "marrón" }

    var_export($colores);
    // array ( 1 => 'rojo', 2 => 'azul', 3 => 'verde', 5 => 'morado', 7 => 'gris', 11 => 'marrón', )

    echo $colores[1]; // rojo
  1. Con texto:
  •   $hex = [
    'rojo'=>'#f00',
    'verde'=>'#0f0',
    'azul'=>'#00f',
    'negro'=>'#000',
    'blanco'=>'#fff'
    ];
  •   print_r($hex);
    // Array ( [rojo] => #f00 [verde] => #0f0 [azul] => #00f [negro] => #000 [blanco] => #fff )

    var_dump($hex);
    // array(5) { ["rojo"]=> string(4) "#f00" ["verde"]=> string(4) "#0f0" ["azul"]=> string(4) "#00f" ["negro"]=> string(4) "#000" ["blanco"]=> string(4) "#fff" }

    var_export($hex);
    // array ( 'rojo' => '#f00', 'verde' => '#0f0', 'azul' => '#00f', 'negro' => '#000', 'blanco' => '#fff', )

    echo $hex['rojo']; // #f00

    Esta forma es parecida a los objetos en javascript o los diccionarios de python

Array Multidimensional

Este tipo de arrays son los que incluyen un array dentro (un array dentro de otro array).

$personas = [
[
'primer_nombre' => 'Federico',
'primer_apellido' => 'Valverde',
'email' => 'fedevalverde@gmail.com'
],
[
'primer_nombre' => 'Toni',
'primer_apellido' => 'Kross',
'email' => 'tonikross@gmail.com'
],
[
'primer_nombre' => 'Luka',
'primer_apellido' => 'Modric',
'email' => 'modric.luka@gmail.com'
]
];

Y para conseguir algún valor específico usamos, al igual que antes, el índice:

echo $personas[1]['email']; // tonikross@gmail.com

Como este tipo de array es similar al formato json, podemos hacer que devuelva los valores en ese formato usando la función json_encode:

print_r(json_encode($personas));
/* [
{
"primer_nombre":"Federico",
"primer_apellido":"Valverde",
"email":"fedevalverde@gmail.com"
},
{
"primer_nombre":"Toni",
"primer_apellido":"Kross",
"email":"tonikross@gmail.com"
},
{
"primer_nombre":"Luka",
"primer_apellido":"Modric",
"email":"modric.luka@gmail.com"
}
]
*/

Operadores

  • < : Menor que
  • > : Mayor que
  • <= : Menor o igual a
  • >= : Mayor o igual a
  • == : Igual a
  • === : Idéntico a
  • != : No igual a
  • !== : No idéntico a

Condicionales

if

La sintaxis del if es así :

if (condition) {
// código a ejecutar si la condición es verdadera
}

Un ejemplo :

$edad = 19;
if ($edad >= 18) {
echo 'Eres mayor de edad';
}
// Eres mayor de edad

Como la edad es igual o mayor que 18 (19) devolverá lo que hay en el interior del if ya que la condición se cumple.

else

Pero, ¿y si quisiéramos devolver otro valor si la condición no se cumple, es decir, el if es false? Este caso lo podemos manejar usando un else:

if (condition) {
// código a ejecutar si la condición es verdadera
} else {
// si el código anterior no es true, se ejecuta este código
}

Un ejemplo :

$edad = 19;
if ($edad >= 18) {
echo 'Eres mayor de edad';
} else {
echo 'Aún eres menor de edad';
}
// Aún eres menor de edad

Si todas las condiciones anteriores no son verdaderas (true), el código del else se ejecutará, pero si alguna de las condiciones anteriores se cumple, PHP nunca llegará hasta el else.

elseif

Ahora tenemos hasta 2 condiciones: si una se cumple (true), será ejecutada, pero si no,el else será el que se ejecute. ¿Pero que ocurre si necesitamos más de 2 condiciones?

Es en este caso donde necesitamos la sentencia elseif:

if (condition1) {
// código a ejecutar si la condición es verdadera
} elseif (condition2) {
// código a ejecutar si la condition2 es verdadera
} else {
// si ninguna de las anteriores condiciones se cumple,
// se ejecuta esto
}

Un ejemplo :

$hora = 16;

if ($hora < 12) {
echo 'Buenos días';
} elseif ($hora < 17) {
echo 'Buenas tardes';
} else {
echo 'Buenas noches';
}

Ahora, con la sentencia elseif(), se pueden comprobar tantas condiciones necesitemos!

Sin embargo, puedes comprobar más cosas aparte de si algo es mayor, menor o igual a otra cosa, vamos a ver algunos ejemplos que no usen estos operadores:

  • Verdadero (true) o Falso (false):

       $clasificado = true;

    if ($clasificado) {
    echo 'Enhorabuena, estás ¡clasificado!';
    } else {
    echo 'Vaya, no estas clasificado :(';
    }
    // Enhorabuena, ¡estás clasificado!
  • Vacío o no:

    $usuarios_activos = ['Felipe','Juan','Toni'];

    if (!empty($usuarios_activos)) {
    echo "Hay algunos usuarios activos, como $usuarios_activos[0]";
    } else {
    echo 'No hay usuarios activos';
    }
    // Hay algunos usuarios activos, como Felipe

Ternary operators

La sentencia if completa ocupa bastante espacio, la manera más simple ya ocupa 3 líneas. Esto se puede resolver usando un operador ternario:

echo condition ? /*si es true */ : /*si es false*/;

Un ejemplo :

$usuarios_activos = ['Felipe','Juan','Toni'];

echo !empty($usuarios_activos) ? 'Hay algunos usuarios activos' : 'No hay usuarios activos';
// Hay algunos usuarios activos

También podemos usar estos operadores ternarios para asignar un valor a una condición.

Un ejemplo:

$usuarios_activos = ['Felipe','Juan','Toni'];

$primer_usuario_activo = !empty($usuarios_activos) ? $usuarios_activos[0] : 'No hay usuarios activos';

echo $primer_usuario_activo;
// Felipe

Pero, ¿y si no quisiéramos que la variable tenga un valor si el if no se cumple?. ¿Qué pasaría si no queremos la sentencia else?

para esto existen dos posibles soluciones:

  •   $usuarios_activos = ['Felipe','Juan','Toni'];

    $primer_usuario_activo = !empty($usuarios_activos) ? $usuarios_activos[0] : null ;
    echo $primer_usuario_activo; // Felipe
  •   $usuarios_activos = ['Felipe','Juan','Toni'];

    $primer_usuario_activo = $usuarios_activos[0] ?? null;
    echo $primer_usuario_activo; // Felipe

Ambas indican lo mismo, pero la última es más corta.

switch

Este tipo de condicional es bastante útil cuando tenemos varias condiciones, lo que ayuda a tener un código más limpio, sin tantos elseif.

switch (variable) {
case valor :
// código a ejecutar
break;
case otro_valor :
// código a ejecutar
break;
// más condiciones
default:
// si ninguna de las anteriores es verdadera
}

Un ejemplo :

$color_favorito = 'amarillo';

switch ($color_favorito) {
case 'azul':
echo 'Tu color favorito es el azul';
break;
case 'rojo':
echo 'Tu color favorito es el rojo';
break;
case 'verde':
echo 'Tu color favorito es el verde';
break;
default:
echo 'Tu color favorito no es el rojo, azul o verde'
}
// Tu color favorito no es el not rojo, azul o verde

Vamos a explicar que ha ocurrido aquí. Cada case funciona como una condición elseif, pero, si todas son falsas (false), ejecutará el default, que es como un else.

Bucles

Los bucles son usados para ejecutar un bloque de código mientras se cumple una condición específica y se seguirá ejecutando hasta que se deje de cumplir dicha condición.

Hay distintos tipos de bucles en PHP:

for

for (initialize; condition; increment) {
// código a ejecutar mientras la condición es true
}

Un ejemplo :

for ($x = 0; $x < 10; $x++) {
echo $x;
}
// 0123456789

while

while (condition) {
// código a ejecutar
}

Un ejemplo :

$x = 0;

while ($X < 10) {
echo $x;
$x++;
}
// 0123456789

do...while

do {
// código a ejecutar
} while (condition);

Un ejemplo :

$x = 1;

do {
echo $x;
$x++;
} while ($x < 10);
// 0123456789

Ten cuidado: do...while siempre se ejecuta primero y hace la comprobación después:

$x = 50;

do {
echo $x;
$x++;
} while ($x < 10);
// 50

foreach

Este bucle se suele usar para arrays

foreach ($array as $value) {
// código a ejecutar
}

Un ejemplo :

$posts = ['primero','segundo','tercero','cuarto'];

foreach ($posts as $post) {
echo $post . ' ';
}
// primero segundo tercero cuarto

Además, con el foreach podemos obtener el índice de los valores del array:

$posts = ['primero','segundo','tercero','cuarto'];

foreach ($posts as $indice => $post) {
echo $indice . '-' . $post . ' ';
}
// 0-first 1-second 2-third 3-fourth

Como hemos dicho, hay distintos tipos de arrays así que vamos a probar el bucle foreachcon un array asociativo

$hex = [
'rojo'=>'#f00',
'verde'=>'#0f0',
'azul'=>'#00f',
'negro'=>'#000',
'blanco'=>'#fff'
];

foreach($hex as $key => $color) {
echo "$key is $color <br/>";
}
/*rojo is #f00
verde is #0f0
azul is #00f
negro is #000
blanco is #fff
*/

Funciones

Las funciones son bloques de código que puedes nombrar y ejecutar donde sea.

Para crear funciones se usa la palabra reservada function seguida del nombre de la función.

function nombre () {
// bloque de código que se ejecute
}

Un ejemplo :

function saludar () {
echo 'Hola!';
}

Lo que hemos hecho ahí es declarar la función y ahora mismo no ejecutará el código que lleva dentro. Para que se ejecute, tenemos que llamarla:

function saludar () {
echo 'Hola!';
}

saludar(); // Hola!

Scope

Como en otros lenguajes, las funciones en php tienen su propio scope o alcance.

¿Qué significa exactamente esto? Esto quiere decir que si declaramos cualquier variable solamente dentro de la función, fuera de ella no existirá.

Un ejemplo :

function saludar () {
$hola = 'Hola!';
echo $hola;
}

saludar(); // Hola!

Como hemos declarado la función $hola dentro de la función saludar, tendrá acceso a su valor, pero, si intentamos acceder a esta misma variable desde fuera de la función, nos dará un error:

function saludar () {
$hola = 'Hola!';
echo $hola;
}

saludar(); // Hola!

echo $hola; // Warning: Undefined variable $hola

Nos da ese error porque $hola solo está en el scope de la función y estamos intentando acceder a su valor como si fuera una variable en el scope global.

Lo mismo ocurre si intentamos leer una variable global dentro de una función:

  $hola = 'Hola!';
function saludar () {
echo $hola;
}

saludar(); // Warning: Undefined variable $hola

echo $hola; // Hola!

Pero, ¿cómo podemos leer una variable global dentro de una función? Para esto se usa global :

  $hola = 'Hola!';
function saludar () {
global $hola;
echo $hola;
}

saludar(); // Hola!

echo $hola; // Hola!

Argumentos

Los argumentos definen que va dentro de la función y los parámetros son pasados a la función dentro de () cuándo es llamada.

function name ($argumento) {
// código a ejecutar
}

name(parameter);

Un ejemplo :

function saludar ($hora_del_dia) {
echo "Hola!, son las $hora_del_dia";
}

saludar("12"); //Hola!, son las 12

Valores por defecto

Si declaramos una función con argumentos, pero no le pasamos ningún parámetro cuando la llamamos, nos dará un error. Para evitar esto, tenemos los valores por defecto:

function saludar ($hora_del_dia = '3') {
echo "Hola!, son las $hora_del_dia";
}

saludar(); //Hola!, son las 3

Salida

En los ejemplos anteriores, siempre estamos haciendo algún echo dentro de la función, pero hay una forma distinta de tener el valor y es devolver el valor con un return:

function nombre() {
return // código a devolver
}

nombre();

Pero si probamos esto, nada se muestra en el navegador.

Esto se debe a que necesitamos un echo explícito para mostrar el valor devuelto:

Un ejemplo:

function suma ($n1,$n2) {
return $n1 + $n2;
}

echo suma(1,5); // 6

Además, podemos asignar el valor devuelto por una función a una variable:

function suma ($n1,$n2) {
return $n1 + $n2;
}

$result = suma(1,5);

echo $result; // 6

Funciones anónimas

También podemos tener funciones sin un nombre, estas son llamadas funciones anónimas, y son así:

$variable = function() {
return // código a devolver
};

Funcionan como una función normal, pudiendo tener argumentos y todas las capacidades de una función.

Un ejemplo:

$suma = function ($n1,$n2) {
return $n1 + $n2;
};
echo $suma(1,5); // 6

Funciones de flecha

Las funciones tiene su propia sintaxis corta, que es así:

$variable = fn($argumento) => argumento;

Cuando hablamos de return de una sola línea, podemos desechar las llaves ({}) y el propio return. También podemos cambiar la palabra reservada function por fn, que es más corta y fácil.

Un ejemplo :

$suma = fn($n1,$n2) => $n1 + $n2;

echo $suma(1,5); // 6

Cuidado : Se el return no es de una sola línea, hay que usar las llaves ({}) y también la palabra reservada return.

Funciones de array

Este tipo de funciones son útiles para obtener información sobre un array o para manipular y trabajar con sus valores.

Para los siguientes ejemplos usaremos los siguientes arrays :

$frutas = ['manzana','naranja','pera'];

Conseguir longitud

Para obtener la longitud de un array usaremos la función count():

echo count($frutas); // 3

Buscar en un array

Buscar por un valor específico dentro de un array.

Para ello, usamos la función in_array(), que devuelve true o false, true si cualquiera de los valores cumple la condición, y false si no.

echo in_array('naranja',$frutas); // 1

Nos devuelve 1 porque el echo de un valor true muestra 1, mientras que si el valor fuera false no mostraría nada.

Añadir a un array

Si queremos añadir cierto valor a un array, hay algunas formas de hacerlo:

Añadir al final:

  • $frutas[] = 'uva';

    print_r($frutas);
    // Array ( [0] => manzana [1] => naranja [2] => pera [3] => uva )
  •   array_push($frutas,'uva','cereza');

    print_r($frutas);
    // Array ( [0] => manzana [1] => naranja [2] => pera [3] => uva [4] => cereza )

    Añadir al inicio:

  • array_unshift($frutas,'uva');

    print_r($frutas);
    // Array ( [0] => uva [1] => manzana [2] => naranja [3] => pera )

Eliminar de un array

Eliminar del final:

array_pop($frutas);

print_r($frutas);
// Array ( [0] => manzana [1] => naranja )

Eliminar del inicio:

array_shift($frutas);

print_r($frutas);
// Array ( [0] => naranja [1] => pera )

Eliminar un elemento específico:

unset($frutas[1]);

print_r($frutas);
// Array ( [0] => manzana [2] => pera )

Dividir un array

Para este ejemplo, dividiremos el array en dos partes, pero se pude hacer en cuantas partes se quiera y pueda.

$array_dividido = array_chunk($frutas,2);

print_r($array_dividido);
// Array ( [0] => Array ( [0] => manzana [1] => naranja ) [1] => Array ( [0] => pera ) )

Concatenar arrays

Para este ejemplo usaremos estos nuevos arrays:

$arr1 = [1,2,3];
$arr2 = [4,5,6];

para concatenar los arrays podemos usar la función array_merge():

$arr3 = array_merge($arr1,$arr2);

print_r($arr3);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

También podemos usar el spread operator como en JavaScript :

$arr3 = [...$arr1, ...$arr2];

print_r($arr3);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 )

Combinar arrays

Para este ejemplo usaremos this example we will use this new arrays:

$a = ['rojo','verde','azul'];
$b = ['aguacate','manzana','plátano'];

Para combinar estos dos arrays, usamos la función array_combine():

$c = array_combine($a,$b);

print_r($c);
// Array ( [rojo] => aguacate [verde] => manzana [azul] => plátano )

¿Qué ha pasado? El array $a es escogido como índice y el array $b representa los valores, así que, el primer valor de $a es el índice del primer valor del array $b

Ahora, como tenemos un array combinado ($c), podemos divertirnos con el:

Crear un array de las keys: Esto devolverá el array $a

$keys = array_keys($c);

print_r($keys);
// Array ( [0] => rojo [1] => verde [2] => azul )

Voltear el array

$volteado = array_flip($c);

print_r($volteado);
// Array ( [aguacate] => rojo [manzana] => verde [plátano] => azul )

Array con rango numérico

Muchas veces vamos a querer tener un array con números del 1 al 9, O de un número a otro y con la función range() eso es posible. Esta función tiene algunos argumentos como el inicio y el final del rango:

$nums = range(1,9);

print_r($nums)
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

Mapear un array

$newNums = array_map(function($num){
return "Number {$num}";
},$nums);

Pero como ya hemos aprendido, el return por si solo no muestra nada, necesitamos visualizarlo de manera explícita:

print_r($newNums);
// Array ( [0] => Number 1 [1] => Number 2 [2] => Number 3 [3] => Number 4 [4] => Number 5 [5] => Number 6 [6] => Number 7 [7] => Number 8 [8] => Number 9 )

Filtrar un array

$menosde10 = array_filter($nums,fn($num)=> $num < 10);

print_r($menosde10);
// Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

Reducir un array

¿Y si queremos sumar, multiplicar, dividir o lo que sea con todos los valores de un array? Para ello, tenemos la función array_reduce().

Este función tiene 2 argumentos, rl primerio es el array que queremos reducir, y el segundo una función que coge otros dos argumentos , el primero es el $carry que lleva el valor de la iteración previa, y el segundo es el nombre de los valores.

$reducir = array_reduce(
$array,
function ($carry, $arr) {
return $carry + $arr;
}
);

Un ejemplo :

$sum_nums = array_reduce($nums, fn($carry, $num)=> $carry + $num);

echo $sum_nums
// 45

Funciones para Strings

Para estas funciones de cadena, trabajaremos con la cadena Hola Mundo string.

$cadena = 'Hola Mundo';

Longitud de una cadena

echo strlen($cadena); // 10

Índice de una subcadena

  • Primera ocurrencia :
    echo strpos('a'); // 3
  • Última ocurrencia :
    echo strrpos('o'); // 9

Voltear una cadena

echo strrev($cadena); // odnuM aloH

Convertir caracteres de una cadena

  • Todos a minúsculas :
    echo strtolower($cadena); // hola mundo
  • Todos a mayúsculas :
    echo strtoupper($cadena); // HOLA MUNDO
  • La primera mayúscula :
    echo ucwords($cadena); // Hola mundo

Reemplazar una subcadena

echo str_replace('Mundo','A Todos',$cadena); // Hola A Todos

Porción de una cadena

echo substr($cadena, 0, 3); // Hola

echo substr($cadena, 4); // Mundo

Empieza o acaba con

  • Empieza con :
    var_dump(str_starts_with($cadena,'Hola'));
    // bool(true)
  • Acaba con :
    var_dump(str_ends_with($cadena,'do'));
    // bool(true)

Visualizar cadena formateada

Si tenemos texto que tuviera una parte fija y otra que cambia dependiendo del dato, podemos usar la función printf() , que podemos usar con una subcadena :

printf('A %s le gusta %s','Juan','zonabit');
// A Juan le gusta zonabit

El %s es la sustitución de la cadena. Ahora, veamos un ejemplo con números:

printf('1+1=%d',1+2);
// 1+1=3

En este caso, el %d reemplaza el número pasado como argumento.

Manejar cadenas de html

Si hacemos un echo de cualquier etiqueta html, como h1 o hr, se visualizará como html normal ya que no se 'parsea'.

Esto, en términos de seguridad, teniendo un formulario o algo parecido pude ser muy peligroso, ya que si hacemos lo siguiente:

echo '<script>alert(1)</script>';

El script se ejecutará como si fuera una etiqueta script normal.

A primera vista puede parecer un gran problema, pero si tenemos algún input como hemos dicho anteriormente, y hacemos un echo del valor dado por el usuario en ese input, si pone su nombre, el resultado sería algo como esto:

$valor_input = 'Felipe';

echo $valor_input;// Felipe

Pero, si ponemos un script en el campo del field, se interpretará como html normal.

$valor_input = '<script>alert(10)</script>';

echo $valor_input;
// esto dará una alerta en el navegador

Imagina que todos los usuarios pueden ejecutar cualquier JavaScript y cambiar la funcionalidad de tu web, e incluso peor, !cambiar o borrar información importante como la guardada en tu base de datos!

Para este problema tenemos vamos a ver dos formas de arreglarlo:

  • Caracteres especiales de Html (Html Special Chars) :
    echo htmlspecialchars($valor_input);
    // <script>alert(1)</script>
  • Entidades Html (Html Entities) :
    echo htmlentities($valor_input);
    // <script>alert(1)</script>

Superglobales

Ya hemos visto que en php hay algunas funciones incorporadas por defecto ('built in'), pero también hay variables por defecto, que son variables que están disponibles en cualquier ámbito o scope (dentro y fuera de una función). Normalmente empiezan con $_ todas con arrays :

  • $_GET : Contiene información sobre variables pasadas por URL o por un formulario con el método 'get'.
  • $_POST : Contiene información sobre variables pasadas por un formulario con el método 'post'.
  • $_COOKIE : Contiene información sobre variables pasadas por cookies.
  • $_SESSION : Contiene información sobre variables pasadas por sesiones.
  • $_SERVER : Contiene información sobre el entorno del servidor.
  • $_ENV : Contiene información sobre las variables de entorno.
  • $_FILES : Contiene información sobre archivos subidos al script.
  • $_REQUEST : Contiene información sobre variables pasadas por un formulario o URL.

GET y POST

En la sección de manejar cadenas de html hemos hablado de 'inputs' y recoger datos que le usuario escribe. Para hacer eso necesitaremos los superglobales.

Podemos pasar datos a través de las urls ($_GET) y formularios ($_GET, $_POST) usando estos superglobales.

GET

$_GET puede leer datos desde un formulario y una url.

Si tenemos algún argumento que queremos pasar a través de páginas, podemos añadirlo al atributo href de la etiqueta <a> así:

<a href="/perfil.php?nombre=Oliver">Pulsa</a>

En esa pieza de código, estamos diciendo que queremos ir a esta url:

/perfil.php?nombre=Oliver

Si echamos un vistazo, tenemos un atributo nombre que es igualado a Oliver, que es el atributo que se leerá en el $_GET. Y como es una url válida, irá a esa página.

Ahora, en el archivo perfil.php, tenemos el $_GET preparado, escuchando por el atributo nombre:

<?php
echo $_GET['nombre'];
// Oliver
?>

El $_GET lee el atributo nombre desde la url.

Si queremos añadir más datos, podemos usar el & :

<a href="/perfil.php?nombre=Oliver&activo=true">Pulsa</a>

Y, en el archivo perfil.php :

<?php
echo $_GET['nombre'];
echo $_GET['activo'] ? 'está activo' : 'no está activo';
?>
// Oliver está activo

Ahora, intentemos esto con formularios.

Primero, necesitaremos construir nuestro formulario:

<form>
<label>Nombre :</label>
<input type="text" />
<br />
<label>Edad</label>
<input type="number" />
<br />
<input type="submit" />
</form>

Este es un formulario normal, pero como estamos trabajando con PHP, necesitamos añadir ciertos atributos al formulario:

<form action="/perfil.php" method="GET">
<label>Nombre :</label>
<input type="text" name="nombre" />
<br />
<label>Edad</label>
<input type="number" name="edad" />
<br />
<input type="submit" name="submit" />
</form>

Hemos añadido unas cuantas cosas :

  • name : para permitir a $_POST y $_GET leer el valor cuando se envié.
  • method : para especificar si lo queremos con POST o GET cuando se envié (por defecto es GET).
  • action : esto especifica el archivo php al que se le enviarán los datos (con '/' envía la información a si mismo).

Ahora, si pulsamos el botón de enviar, seremos redirigidos al archivo perfil.php, y se le pasarán los datos :

<?php
echo $_GET['nombre'];
echo '<br/>';
echo $_GET['edad'];
?>
// Oliver
// 30

La edad y nombre vienen del atributo name de cada input.

Pero, si miramos a la url del perfil.php, veremos algo como esto :

/perfil.php?nombre=Oliver&edad=30&submit=Submit

Esto no queda muy limpio, es por ello por lo que usamos el método POST y el $_POST para obtener los datos de forma más limpia y amigable con la url.

POST

$_POST solo es usado con formularios ya que no tiene acceso a los parámetros de la url.

Para usarlo, solo cambiamos el atributo method en la función que envía los datos :

<form action="perfil.php" method="POST">
<label>Nombre :</label>
<input type="text" name="nombre" />
<br />
<label>Edad</label>
<input type="number" name="edad" />
<br />
<input type="submit" name="submit" />
</form>

Y, tenemos que cambiar el $_GET del archivo perfil.php por el $_POST donde aparezca :

<?php
echo $_POST['nombre'];
echo '<br/>';
echo $_POST['edad'];
?>
// Oliver
// 30

Ahora, tenemos el mismo resultado que antes, pero con una url mucho más limpia.

Problema del 'Undefined array key'

Si probamos los métodos GET y POST en nuestro propio archivo, o intentamos acceder a ellos directamente desde la url del archivo perfil.php, veremos este error :

Warning: Undefined array key "nombre" in /var/www/html/perfil.php on line 14

Esto ocurre porque a la hora de hacer la primera petición al servidor, no hay ningún parámetro nombre ni tampoco ningún atributo por url, así que es indefinido ('undefined').

Pero, ¿Cómo podemos evitar esto?, porqué está claro que la primera vez que cargue la página , no habrá ningún atributo definido.

La forma de solucionar este error es con la función isset() :

<?php
if(isset($_POST['submit'])){
echo $_POST['nombre'];
echo '<br/>';
echo $_POST['edad'];
}
?>

Agregar seguridad

Hemos hablado antes sobre algunos riesgos en la seguridad que pueden conllevar los inputs, así que vamos a profundizar en este tema añadiendo formas para hacer los inputs más seguros.

Aparte del htmlspecilchars o htmlentities podemos usar otra función por defecto llamada filter_input().

Esta función necesitas 3 argumentos:

  1. El tipo, que solo puede ser uno de estos :

    • INPUT_GET
    • INPUT_POST
    • INPUT_COOKIE
    • INPUT_SERVER
    • INPUT_ENV

    Cada uno corresponde a una variable superglobal. En nuestro caso, como tenemos el método POST, usaremos el INPUT_POST.

  2. El nombre de la variable :

    Este es el nombre de la variable, que va dentro de los corchetes ([]) después del $_POST.

    En este caso, como solo vamos a añadir seguridad al input del nombre, el nombre que le pasaremos será nombre.

  3. El filtro :

    En este argument, necesitamos especificar el ID del filtro que aplicar.

    En nuestro caso, usaremos el FILTER_SANITIZE_SPECIAL_CHARS.

Una vez hecho esto, el resultado sería algo como esto :

<?php
if (isset($_POST['submit'])) {
$nombre = filter_input(INPUT_POST, 'nombre', FILTER_SANITIZE_SPECIAL_CHARS);
echo $nombre;
echo '<br/>';
echo $_POST['edad'];
}
?>

Otra forma de añadir seguridad a los inputs es usando la función filter_var(), que es parecida a filter_input(), pero esta puede ser usada con más cosas aparte de inputs.

Un ejemplo :

<?php
if (isset($_POST['submit'])) {
$nombre = filter_var($_POST['nombre'], FILTER_SANITIZE_SPECIAL_CHARS);
echo $nombre;
echo '<br/>';
echo $_POST['edad'];
}
?>

Cookies

Las cookies son un mecanismo para guardar datos en el navegador e identificar de vuelta a los usuarios. Puedes poner datos específicos para que sean guardados en el navegador in the browser, y volver a cogerlos cuando el usuario vuelva a visitar la página.

Para crear una cookie, necesitaremos 3 parámetros:

  • Key : Para referenciar la cookie en un futuro.
  • Valor : El valor que tendrá la cookie.
  • Tiempo de expiración : Cuándo queremos que esa cookie caduque.

Un ejemplo :

setcookie('nombre','Oliver',time()+86400);
// hemos puesto la cookie para un día

Para esto usaremos La variable superglobal $_COOKIE:

if(isset($_COOKIE['nombre'])){
echo $_COOKIE['nombre'];
}

Borrar una cookie es tan simple y lógico como ponerle una fecha de expiración pasada:

setcookie('nombre','',time()-86400);

Sesiones

Las sesiones son una forma de guardar información (en variables) para usarlas a través de multiples páginas.

A diferencia de las cookies, las sesiones son guardadas en el servidor y no en el cliente.

Primero de todo, para poder usar sesiones en cualquier archivo php, necesitamos indicar un "inicializador" :

<?php
session_start();
// código
?>

Crear una sesión

$nombre_usuario = $_POST["nombre_usuario"];
$_SESSION['nombre_usuario'] = $nombre_usuario;

Leer una sesión

$nombre_usuario = $_SESSION['nombre_usuario'];

Borrar una sesión

session_destroy();

// podemos redirigir a otra página
header('Location:/index.php');

Manejo de archivos

El manejo de archivos es la habilidad de leer y escribir archivos en el servidor.

PHP tiene funciones por defecto para leer y escribir archivos.

Primero, necesitamos crear un archivo, que vamos a llamar usuarios.txt, que tendrá el siguiente contenido :

Oliver
Juan
Sara
Esteban
Enrique

También crearemos una variable llamada archivop que contendrá la ruta de usuarios.txt :

$archivop = './usuarios.txt';

¿Existe el archivo?

file_exists($archivop);

Leer el archivo

echo readfile($archivop);
// Oliver Juan Sara Esteban Enrique

Otra forma de leer un archivo es con el fread(), que necesita 2 argumentos : el stream y la longitud (length) :

$handle = fopen($archivop,'r');
// r significa abrir el archivo solo para leer (read)
$contents = fread($handle,filesize($archivop));
fclose($handle);
echo $contents;
// Oliver Juan Sara Esteban Enrique

Escribiendo en un archivo

$handle = fopen($archivop,'w');
// w significa abrir el archivo para escribir (write)
$contents = 'Oliver Juan Miguel';
fwrite($handle,$contents);
fclose($handle);

Si queremos saltos de linea, podemos usar PHP_EOL:

$handle = fopen($archivop,'w');
// w significa abrir el archivo para escribir (write)
$contents = 'Oliver'.PHP_EOL.'Juan'.PHP_EOL.'Miguel';
fwrite($handle,$contents);
fclose($handle);

Subir archivos

Para subir un archivo, primero necesitamos un formulario, así que, vamos a crearlo :

<form action="/" method="POST" enctype="multipart/form-data">
Selecciona una imagen para subir:
<input type="file" name="subida">
<br />
<input type="submit" name="submit" value="Submit" />
</form>

Algo muy importante a la hora de subir archivos es que el atributo enctype debe estar indicado, si no está puesto, no funcionará.

Para la subida de archivos, usaremos uno de los superglobales, el superglobal $_FILES.

En este caso, necesitaremos el directorio objetivo y el directorio temporal (tmp) del archivo. Este último viene por defecto en el $_FILES.

$archivo_nombre = $_FILES['subida']['name']
$dir_objetivo = "subidas/{$archivo_nombre}";
$archivo_tmp = $_FILES['subida']['tmp_name'];

move_uploaded_file($archivo_tmp,$dir_objetivo);

Excepciones

PHP tiene un modelo de excepciones parecido a otros lenguajes de programación. Un excepción puede ser lanzada, y cogida ("cached") dentro de PHP. EL código puede estar rodeado por un bloque try, para facilitar el cacheo ('guardado en cache') de potenciales excepciones. Cada try debe tener al menos un catch o bloque final correspondiente.

Por ejemplo, queremos lanzar un error si intentamos dividir por 0:

function inverso($x) {
if(!$x) {
throw new Exception('División por 0');
}
return 1/$x;
}

echo inverso(10); // 0.1
echo inverso(0);
// Fatal error: Uncaught Exception: División por 0

Pero hagamos algo con la excepción.

Haremos un echo dentro del bloque try...catch y veamos que pasa :

try {
echo inverso(10);
echo inverso(0);
} catch (Exception $e) {
echo ' Excepción ', $e->getMessedad();
}
// 0.1 Excepción División por 0

También tenemos el bloque final (finally), que es agnóstico sobre lo que pase en el bloque try...catch :

try {
echo inverso(10);
echo inverso(0);
} catch (Exception $e) {
echo ' Excepción ', $e->getMessedad();
} finally {
echo ' ¡Finalmente!';
}
// 0.1 Excepción División por 0 ¡Finalmente!

POO

Desde PHP5 en adelante se puede escribir PHP de forma funcional o orientada a objetos. La POO consiste en clases que pueden tener "propiedades" y "métodos".Los Objetos pueden ser creados a partir de clases.

Vamos a crear usuarios con POO:

class Usuario {
public $nombre;
public $email;
public $contra;
}

Esas son propiedades, que son atributos que pertenecen a una clase.

Ahora, podemos instanciar un objeto del usuario :

$usuario1 = new Usuario();

var_dump($usuario1);
// object(Usuario)#1 (3) { ["nombre"]=> NULL ["email"]=> NULL ["contra"]=> NULL }

Todo es NULL (nulo) porque no hemos especificado esos valores, por lo tanto, vamos a crearlos :

$usuario1 = new Usuario();
$usuario1->nombre = 'Federico';
$usuario1->email = 'fedevalverde@gmail.com';
$usuario1->contra = '1234';
print_r($usuario1);
// Usuario Object ( [nombre] => Federico [email] => fedevalverde@gmail.com [contra] => 1234 )

Modificadores de acceso

Hay 3 tipos de modificadores de acceso :

  • Public (público) : puede ser accedido desde cualquier parte.
  • Private (privado) : solo puede ser accedido desde dentro de la clase.
  • Protected (protegidos) : solo puede ser accedido desde dentro de la clase y clases heredadas.

Método

El método ('method') es una función que pertenece a una clase.

class Usuario {
public $nombre;
public $email;
public $contra;
function set_nombre($nombre){
$this->nombre = $nombre;
}
}

Ahora, podemos acceder a esa función desde fuera de la clase :

$usuario2 = new Usuario();

$usuario2->set_nombre('Oliver');

var_dump($usuario2);
// object(Usuario)#2 (3) { ["nombre"]=> string(4) "Oliver" ["email"]=> NULL ["contra"]=> NULL }

Constructor

Un constructor es un método que se ejecuta cuando un objeto es creado.

class Usuario {
public $nombre;
public $email;
public $contra;
public function __construct($nombre,$email,$contra){
$this->nombre = $nombre;
$this->email = $email;
$this->contra = $contra;
}
}

Ahora, gracias al constructor, cuando instanciemos a algún Usuario podemos pasarle esos valores :

$usuario1 = new Usuario('Oliver','oliver@gmail.com','securePassword');
$usuario2 = new Usuario('Federico','fedevalverde@gmail.com','1234');

print_r($usuario1);
// Usuario Object ( [nombre] => Oliver [email] => oliver@gmail.com [contra] => securePassword )
echo '<br/>';
print_r($usuario2);
// Usuario Object ( [nombre] => Federico [email] => fedevalverde@gmail.com [contra] => 1234 )

Herencia

Esto es cuando una clase pertenece a otra clase

class Trabajador extends Usuario{
public function __construct($nombre,$email,$contra,$titulo){
parent::__construct($nombre,$email,$contra);
$this->titulo = $titulo;
}
function get_titulo(){
return $this->titulo;
}
}

Ahora, podemos crear un Trabajador:

$trabajador1 = new Trabajador('Sara', 'sara@gmail.com', '1password','Informática');
echo $trabajador1->get_titulo();// Informática