Acceder a la base de datos desde el lenguaje de programación PHP

Acceder a la base de datos desde el lenguaje de programación PHP

Acceder a la base de datos desde el lenguaje de programación PHP

Tabla de contenidos

    Servidor web IoTHTTP POST Servidor web IoTBase Datos MySQL. Servidor web IoTLenguaje PHP Servidor web IoT

    En este último artículo de la serie sobre el uso de un servidor web para almacenar los datos de los dispositivos conectados a la Internet de las cosas, se explica como grabar en una base de datos MySQL la información que los nodos IoT envían al servidor haciendo peticiones HTTP POST. Los lectores de este artículo, de todo el blog, puede que no estén especialmente familiarizados con la programación en el lenguaje PHP pero seguramente sí con la programación de microcontroladores en los lenguajes C o C++ así que, salvo algunos detalles, como preceder del signo dólar ($) a las variables, podrán seguir los ejemplos sin necesidad de mayores explicaciones ya que se han hecho siguiendo un estilo de programación muy neutro, no específico de PHP.

    Almacenar información en la base de datos

    Como se explicaba en el artículo sobre el almacenamiento de datos de la IoT haciendo peticiones HTTP POST a un servidor web, al final de las cabeceras, el cuerpo de la petición POST contiene los datos que se envían al servidor. La forma más común de enviar esa información al servidor es en formato de texto plano porque es más sencillo analizarla incluso «manualmente». Cuando los datos que se envían al servidor son complejos seguramente será conveniente estructurarlos usando, por ejemplo el formato XML o JSON. En el uso habitual de un servidor web para gestionar la información de dispositivos conectados a la Internet de las cosas no es frecuente necesitar una estructura de datos por lo que lo normal es enviarlos en texto plano en el formato variable=valor.

    En la petición HTTP POST del siguiente ejemplo se solicita al servidor polaridad.es el recurso (normalmente una página web) /iot/grabar_temperatura y se le envían tres variables: ne, tp y cr que contienen respectivamente los valores «12», «10.26» y «2.18» También es importante recordar que hay una línea en blanco para separar las cabeceras de los datos.

    El objetivo final del siguiente código PHP será enviar al servidor de bases de datos MySQL la orden SQL:

    Con la que se creará un nuevo registro (INSERT)
    en la base de datos calefacciones (INTO calefacciones)
    asignando a los campos (numero_estancia,temperatura,corriente)
    los valores correspondientes a la petición HTTP POST VALUES (12, 10.26, 2.18)

    La conexión a la base de datos se realiza con la función mysqli_connect conforme al formato: mysqli_connect($servidor,$usuario,$clave,$base_datos) que devuelve un puntero al objeto-conexión y que usa la variables que definen el acceso (como usuario, clave…) y que han sido previamente asignadas para futuros hipotéticos usos en el script.

    Para detectar si la conexión ha tenido éxito se utiliza la función mysqli_connect_errno() que devuelve el número de error que se pueda haber producido o cero (false) si la conexión se ha establecido correctamente. Para avisar de los errores se responde con el valor cero a la aplicación que realiza la petición HTTP, en este caso el programa que se ejecuta en el µC del nodo IoT.

    Antes de incorporar al texto que se almacena en $consulta_sql con el que se compone la orden SQL que se envía al servidor de bases de datos la información que ha llegado en las variables de la petición POST se preprocesan, como mínimo, para evitar un ataque por inyección de código SQL. En el ejemplo anterior se fuerza la conversión al tipo de dato correspondiente (int) (entero) o (float) (decimal en coma flotante) lo que sería suficiente para eliminar posible código malicioso añadido a los datos de la petición al servidor web.

    Como puede verse, en el lenguaje PHP se utiliza el símbolo del punto (.) para concatenar los textos que forman la orden SQL o el operador punto y signo igual (.=) para añadir un texto a la derecha del que ya almacene una variable y se utiliza la comilla simple (‘) también para encerrar constantes de texto, no sólo caracteres. Aunque en este caso pueden utilizarse también comillas dobles («), en lenguaje PHP se utilizan para procesar el contenido, por ejemplo, incluyendo variables dentro del texto en el formato $texto="Me llamo $nombre"; como alternativa al formato $texto='Me llamo '.$nombre; permitiendo, además, incluir comillas de un tipo en otro sin necesidad de usar signos de escape siempre que se alternen dobles dentro de simples o simples dentro de dobles como en la asignación $texto='esto no hay que "escaparlo" en PHP';.

    Para ejecutar la consulta al servidor MySQL se utiliza la función mysqli_query con el formato mysqli_query($conexion,$consulta_sql) que toma como parámetros el objeto-conexión a la base de datos y el texto con la orden SQL que se ha compuesto.

    La función mysqli_query($conexion,$consulta_sql) devuelve un objeto-cursor que puede usarse para recorrer los datos devueltos en su caso o, como ocurre en el ejemplo de arriba, para obtener información sobre la operación, concretamente para conocer el índice asignado al nuevo registro que la operación ha creado en la tabla «calefacciones» con la función mysqli_insert_id($conexion)

    El valor devuelto por mysqli_query($conexion,$consulta_sql) puede evaluarse como falso en una operación booleana para determinar que se ha producido un error. En el ejemplo anterior se usa para devolver, al igual que en el caso del error de conexión, un cero a la aplicación que hace la petición POST. De esta forma, el programa devolverá un número mayor que cero que representa el índice del nuevo registro si la operación es correcta o un cero si la operación produce algún error.

    Para liberar los recursos que se han asignado a la conexión a la base de datos se «cierra» usando la función mysqli_close($conexion)

    Leer información de la base de datos

    Salvo en arquitecturas para fog computing la mayoría de los nodos IoT se limitan a enviar al servidor la información que captan sus sensores, es decir, el servidor web sólo comunica con ellos para almacenar la información por lo que, con el ejemplo anterior ya se han resuelto buena parte de los casos que se plantearán en esta aplicación. El siguiente paso podría ser crear una web que mostrara los datos monitorizados por los dispositivos conectados a la Internet de las cosas, un trabajo de frontend que queda fuera de lo que se está tratando en esta serie de tutoriales.

    Lo que sí puede ocurrir es que un nodo IoT tenga cierta interactividad y se comporte de forma diferente en función de un histórico de datos o prevea la posibilidad de alterar su comportamiento conforme a una configuración que le llegue de un servidor o incluso el nodo sea una pantalla que muestre una gráfica con los datos que se han monitorizado recientemente en comparación con los adquiridos en fechas anteriores. Para todas estas situaciones es interesante también poder leer datos del servidor MySQL a través del servidor web como se ilustra en el siguiente ejemplo en el que se simula la obtención de una lista de las fechas de los estados de alarma determinados por los momentos en los que la temperatura superó los 40°C

    En el ejemplo de arriba, para consultar la base de datos se usa la orden SQL SELECT conforme al formato básico SELECT campos FROM tabla WHERE condición ORDER BY campo DESC con la única peculiaridad de añadir al campo fecha las funciones DAY, MONTH, YEAR y TIME al objeto de obtener de la misma el día, el número del mes el año y la hora por separado. La condición impuesta es que la temperatura sea mayor que 40.0 y se ordena usando el campo fecha de mayor (más actual) a menor (más antiguo) indicándolo con la cláusula DESC

    Para recorrer los valores devueltos por la consulta desde un bucle for con una dimensión conocida se utiliza la función mysqli_num_rows($resultado) que indica el número de registros que se han encontrado. Con la función mysqli_data_seek($resultado,$numero_resultado) se puede mover el cursor de los resultados a una posición concreta expresada por el contador del bucle for, $numero_resultado, en el ejemplo.

    Para almacenar en un vector los campos del registro que apunta el cursor del resultado se utiliza la función mysqli_fetch_row($resultado) que se asigna a la variable $registro que después se usará formando una frase con los diferentes valores accediendo a ellos por sus índices.

    Una vez que se han recorrido todos los valores se liberan los recursos asignados al resultado de la consulta SQL con la función mysqli_free_result($resultado)

    Procesar información de la base de datos. Comparar valores.

    En algunas ocasiones conviene que el procesado de la información se centralice en el servidor incluso aunque fuera posible realizarla en los nodos IoT al estilo fog computing. En el siguiente ejemplo las razones que se simulan para hacerlo son de seguridad; el nodo tiene información sobre su clave (cerradura) y sobre una solicitud (llave) pero no sabe si corresponde dar paso a la combinación de ambas así que debe consultarlo al servidor que es el que toma la decisión e informa al nodo respondiendo cero (para indicar una comparación incorrecta) o uno (para indicar que la comparación tuvo éxito) según el resultado de una consulta a su base de datos.

    Con esta excusa se puede ver un ejemplo en el que se reciben datos del dispositivo conectado a la Internet de las cosas (un código de llave y otro de cerradura), se devuelve un resultado (uno o cero según el resultado sea verdadero o falso) y se realiza un pequeño procesado de la información consistente en comparar los resultados obtenidos al consultar la base de datos con los enviados por el nodo IoT.

    En el ejemplo anterior se utiliza la función hexdec para obtener un número decimal desde un texto que representa uno hexadecimal y que es el enviado por el dispositivo IoT. la ventaja añadida de usar está función es evitar, como se explicó antes, un ataque añadiendo código SQL malicioso a los datos de la petición POST.

    Publicar comentario

    Puede que te hayas perdido