Categoría: PHP

Como trabajar con fechas en php

Para trabajar con fechas en php tenemos varias opciones, desde usar la función date a trabajar con timestamp. En este artículo vamos usar el objeto DateTime por la potencia que ofrece. Y para agregarle funcionalidades vamos agregar la librería Carbon.

La clase DateTime

La clase nativa que PHP nos proporciona para trabar con fechas.

Obtener la fecha actual

$fecha = new DateTime();

Ahora $fecha contiene la fecha en la que se ejecuta el código, si hacemos var_dump a este objeto obtendremos algo como esto:

var_dump del objeto DateTime

El constructor de la clase acepta dos parámetros opcionales, el primero una fecha y el segundo un objeto DateTimeZone. Si no pasamos el primer parámetro como en el ejemplo anterior se recoge la fecha actual.

Trabajar con una fecha concreta

Tenemos una fecha guardada en base de datos que queremos transformar al objeto DateTime para trabajar con ella, lo que tenemos que hacer es pasarsela como string al constructor de la clase DateTime como primer parámetro, por ejemplo:

$fecha = new DateTime('2008-08-07 18:11:31');

Ojo con esto, para que la fecha se inicie correctamente la fecha debe de estar en un formato especifico. Por ejemplo el formato que usamos en España «dia/mes/año» no nos sirve. Si creamos un objeto DateTime a partir de la fecha «01/02/2020» no vamos a crear el día uno de febrero de 2020, vamos a crear el día dos de Enero de 2020, esto es por que php espera la fecha en formato americano, mucho cuidado con esto. Puedes ver que formatos están admitidos en este enlace: https://www.php.net/manual/es/datetime.formats.php.

Yo recomiendo trabajar con el formato de MySQL por que es uno de los más extendidos y nos facilita el trabajo al usar esta base de datos. El formato de MySQL es «Año-mes-día hora:minuto:segundo» por ejemplo «2008-08-07 18:11:31».

Fechas con formato no admitido

¿Que pasa cuando queremos inicializar la clase DateTime a partir de una fecha con un formato que no admite el constructor o no es el que espera?

Vamos con el ejemplo anterior, tenemos la fecha «01/02/2020», si creamos un objeto DateTime como hemos dicho se va a crear el día dos de Enero de 2020, y queremos crear la fecha uno de Febrero de 2020 para esto tenemos que indicarle al objeto DateTime el formato en el que tenemos la fecha con su método estático createFromFormat, vamos a ver un ejemplo:

$fechaA = new DateTime('01/02/2020'); // Dos de Enero de 2020
$fechaB = DateTime::createFromFormat('d/m/Y', '01/02/2020'); // Uno de Febrero del 2020

De esta forma especificando el formato podemos iniciar cualquier fecha con el objeto DateTime, podemos ver como construir el formato en el siguiente enlace https://www.php.net/manual/es/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters

La librería Carbon

Carbon (https://carbon.nesbot.com/) es una extensión de la clase DateTime que nos aporta montón de funcionalidades extra para trabajar con fechas.

Instalación

Usamos composer para instalar carbon.

composer require nesbot/carbon

Como usamos esta librería

Carbon es una clase que extiende de la case nativa DateTime, por lo tanto la usamos de la misma forma que usamos el objeto DateTime.

<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
$fecha = new Carbon();

La potencia de carbon

Carbon, añade al objeto DateTime múltiples métodos que agregan nuevas funcionalidades y facilitan otras. Podemos verlas en la documentación oficial https://carbon.nesbot.com/docs/

Algunos de los métodos que nos proporciona carbon:

$fecha->addMonth(); // Añade un mes a la fecha
$fecha->subMonth(); // Quita un mes a la fecha
$fecha->startOfYear(); // Setea la fecha al primer día del año con tiempo 00:00:00
$fecha->endOfDay(); // Setea la fecha último día del año con tiempo 23:59:59.999999
$fecha->diffForHumans($fecha2) // Devuelve la diferencia de dos fechas en texto por ejemplo "2 segundos antes" (para que el texto este en castellano hay que especificar la localización $fecha->locale('es');)

Aún más potencia

Si creamos una nueva clase que llamemos por ejemplo Fecha y la extendemos de Carbon tendremos toda la potencia de carbon con el objeto nativo DateTime y nuestros métodos personalizados, todo en la misma clase:

<?php

use Carbon\Carbon;

class Fecha extends Carbon
{
    function miMetodoPersonalizado() {
        
    }
}

Caracteres extraños en acentos o símbolos

La solución universal para este tipo de problema es tener todo con codificación utf8. Este articulo repasa cinco puntos que debes de tener en cuenta para no tener problemas de codificación.

Los archivos con codificación uf8 sin bom

Todos los archivos que componen el proyecto tienen que tener codificación utf8 sin bom.

¿Como sabemos la codificación de un archivo? Hay muchas formas pero una de ella es abriendo el archivo con el notepad++ en la barra inferior podemos ver la codificación, tiene que salir UTF-8

Las páginas que genera la aplicación con charset utf8

Todas las páginas que genera la aplicación tienen que tener charset utf8 en el head.

Para ver si el charset esta correcto solo tenemos que inspeccionar el código fuente. Se suele indicar al inicio de la etiqueta head en documento html como en el siguiente ejemplo:

<!DOCTYPE html>
<html id="html" lang="es">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Mi web</title>

La conexión a base de datos con charset utf8

Si tu aplicación usa base de datos para guardar la conexión a esta se debe de configurar con el charset utf8. Hay varias formas de iniciar una conexión y cada una tiene su forma de configurar, voy a poner ejemplos de las 2 mas usadas, mysqli y pdo:

<?php
$mysqli = new mysqli("localhost", "mi_usuario", "mi_contraseña", "test");
// Justo después de abrir la conexión establecemos el charset a utf8
$mysqli->set_charset("utf8")
?>

Los esquemas con charset en utf8mb4 y collate en utf8mb4_unicode_ci

Podemos saber estos valores con la siguiente consulta:

SELECT * FROM information_schema.SCHEMATA WHERE schema_name = "nombre_esquema" 

Las tablas de cada esquema con collation utf8mb4_unicode_ci

Podemos consultar el cotejamiento de cada tabla desde phpmyadmin:

Como instalar xdebug en windows

En este artículo vamos a ver como instalar xdebug en windows, para comprobar la instalación de xdebug vamos a utilizar el siguiente código de ejemplo:

<?php
$array = [
    'string' => 'string',
    'int' => 1,
    'true' => true
];
var_dump($array)
?>

Si nuestro servidor no tiene xdebug instalado el código de ejemplo se verá de la siguiente forma:

Instalación

xdebug es una librería (un archivo con extensión .dll). Lo primero que tenemos que hacer es descargar este archivo .dll pero xdebug tiene muchas versiones y opciones.

Por ejemplo para la última versión de xdebug compatible con php 7.3
(en el momento de escribir este articulo es la 2.7.2) tenemos 4 opciones disponibles:

¿Entonces cual descargamos? xdebug tiene un asistente que nos va a solucionar este problema. Lo primero que tenemos que hacer es ejecutar phpinfo(), esta función va a imprimir por pantalla una serie de datos que tenemos que copiar íntegros, lo copiamos todo (control + a)

Accedemos a la web https://xdebug.org/wizard.php y pegamos la información proporcionada por phpinfo() en el textarea:

Una vez copiado, hacemos click en «Analyse my phpinfo() output»

Se nos muestra una nueva página con información de nuestro sistema y las instrucciones para instalar xDebug:

En el punto uno tenemos un enlace a la librería exacta que es compatible con nuestro sistema. Descargamos este archivo y lo movemos a la dirección que nos muestra el punto dos. Modificamos el archivo php.ini, tenemos su ruta en el punto tres y añadimos una nueva linea, la que nos indica el punto tres (zend_extension = …). Por último reiniciamos apache.

Una vez finalizada la instalación el código de ejemplo se verá de la siguiente forma:

PHP Warning: Xdebug MUST be loaded as a Zend extension

ERROR

PHP Warning: Xdebug MUST be loaded as a Zend extension

Este error lo podemos ver en varias situaciones:

  • Ejecutando php por CLI
  • Instalando composer
  • Actualizando composer

CAUSA

Tenemos xdebug cargado como sin zend_extension

SOLUCIÓN

Cargar la extensión xdebug como zend_extension

1) Abrimos el php.ini
2) Localizamos la siguiente linea donde cargamos la extensión xdebug, en mi caso es la siguiente:

extension=php_xdebug.dll

3) Sustituimos la palabra «extension» por «zend_extension» quedando en mi caso, de las siguiente forma:

zend_extension=php_xdebug.dll

4) Reiniciamos el apache


Como instalar composer en windows

En este artículo veremos como instalar composer en windows, como usarlo y finalmente descargaremos un framework php con composer, ¿pero que es composer?

Composer es un gestor de paquetes a nivel de aplicación para el lenguaje de programación PHP que proporciona un formato estándar para gestionar las dependencias del software PHP y las bibliotecas requeridas
https://en.wikipedia.org/wiki/Composer_(software)

Composer es una herramienta para la administración de dependencias en PHP. Te permite declarar las bibliotecas de las que depende su proyecto y administrarlas, composer las instalará y las actualizará. https://getcomposer.org/doc/00-intro.md

Podemos usar composer de dos formas, de forma global instalándolo en nuestro pc con el instalador Composer-Setup.exe o de forma local descargandonos un archivo llamado composer.phar. En este articulo vamos a ver como usar composer de forma local con composer.phar. Nos vamos a https://getcomposer.org/download/ y en la sección Manual Dowload nos descargamos la ultima versión de archivo composer.phar, en el momento de escribir este articulo la 1.6.5

Creamos una carpeta en el escritorio y ponemos el archivo composer.phar descargado:

Composer.phar se ejecuta con php, para esto necesitamos tener el php.exe como variable de entorno, abrimos la consola, escribimos php:

Si la consola se nos queda esperando que escribamos algo todo va bien, en cambio si nos dice:

«php» no se reconoce como un cmomando interno o externo, programa o archivo por lotes ejecutable

No podemos seguir y tenemos que configurar nuestras variables de entorno.

Ahora (estando en el directorio donde tenemos el archivo composer.phar) ejecutamos el comando: php composer.phar

Si nos sale esta pantalla es que todo va bien. Ahora solo tenemos que ejecutar el comando composer que queramos, por ejemplo vamos a descargar slim framework (https://www.slimframework.com) con composer, y ejecutamos:

php composer.phar require slim/slim "^3.0"

Composer comenzará a descargar slim framework

Como conectarse a mysql desde php

Php nos da varias opciones para poder conectarnos a mysql, son las siguientes:

  • La extensión MySQL, obsoleta en PHP 5.5.0 y eliminada en PHP 7.0.0 (no usar)
  • La extensión MySQLi (la que usaremos en este ejemplo)
  • PDO (capa abstracta que permite realizar conexiones a varias bases de datos)
  • Otras: DBA, dbx, ODBC.

ATENCIÓN: Si utilizas la función mysql_connect() para conectarte a mysql estas usando código obsoleto, intenta en la medida de lo posible actualizarte

En este ejemplo vamos a utilizar la extensión MySQLi, ahora debemos escoger si utilizamos el estilo orientado a objetos o el estilo por procedimientos, dos formas de hacer lo mismo pero con pequeñas diferencias de sintaxis.

$mysqli = new mysqli('localhost', 'mi_usuario', 'mi_contraseña', 'mi_bd'); // Estilo orientado a objetos
$enlace = mysqli_connect('localhost', 'mi_usuario', 'mi_contraseña', 'mi_bd'); // Estilo por procedimientos

Por potencia y comodidad recomiendo el estilo orientado a objetos que va a ser la forma que seguiremos en este artículo.

A continuación un código de ejemplo para realizar la conexión a una base de datos mysql explicado con comentarios.

$host = 'localhost'; // La dirección de la base de datos, puede ser o un nombre de host o una dirección IP
$username = 'root'; // El usuario de la base de datos
$passwd = 'root'; // La contraseña del usuario
$dbname = 'demo'; // El esquema predeterminado para realizar las consultas

// Realizamos la conexión
$conexion = new mysqli($host, $username, $passwd, $dbname);
// Controlamos que la conexión no tenga errores
if($conexion->connect_error) { 
   error_log("Error de conexion a mysql: nº: $conexion->connect_errno, Error: $conexion->connect_error");
   throw new ErrorException("Error de conexion a mysql: nº: $conexion->connect_errno, Error: $conexion->connect_error");
}
// Especificamos el charset de la conexión, muy importante para que se vean correctamente todos los caracteres 
$conexion->set_charset("utf8");

// Ejecutamos una select en la base de datos
$resultadoSelect = $conexion->query("SELECT * FROM usuarios");
// Recorremos las filas 
while ($fila = $resultadoSelect->fetch_assoc()) {
   var_dump($fila); // Pintamos una fila
}

Warning: mysqli::mysqli(): Access denied for user

ERROR

Warning: mysqli::mysqli(): (HY000/1045): Access denied for user ‘admin’@’localhost’ (using password: YES) in C:\xampp\htdocs\mysql\index.php on line 2

CAUSA

El usuario no existe en la base de datos, o la contraseña del usuario indicado es incorrecta.

SOLUCIÓN

Especificar correctamente el username y el passwd en el constructor de la clase mysqli