Få åtkomst till databasen från programmeringsspråket PHP
I den här sista artikeln i serien om Använda en webbserver för att lagra data från enheter anslutna till Internet of Things, förklarar hur man spelar in i en databas MySQL informationen som IoT-noder skickar till servern som gör HTTP POST-förfrågningar. Läsare av denna artikel, av hela bloggen, kanske inte är särskilt bekanta med programmering i PHP-språk men visst ja med programmeringen av mikrokontroller i språk C o C + + så, förutom vissa detaljer, som att föregå dollartecknet ($) till variablerna, kommer du att kunna följa exemplen utan att behöva ytterligare förklaringar eftersom de har gjorts enligt en mycket neutral programmeringsstil, inte specifik för PHP.
Lagra information i databasen
Som förklaras i artikeln om IoT-datalagring genom att göra HTTP POST-förfrågningar till en webbserver, i slutet av rubrikerna innehåller brödtexten i POST-begäran de data som skickas till servern. Det vanligaste sättet att skicka denna information till servern är i vanlig textformat eftersom det är lättare att analysera den även "manuellt". När data som skickas till servern är komplex kommer det säkert att vara bekvämt att strukturera den med hjälp av till exempel formatet XML o JSON. I den vanliga användningen av en webbserver för att hantera information från enheter anslutna till Internet of Things är det inte vanligt att behöva en datastruktur, så det är normalt att skicka dem i vanlig text i formatet variable=valor
.
I HTTP POST-begäran i följande exempel begärs resursen (normalt en webbsida) /iot/grabar_temperatura från polaridad.es-servern och tre variabler skickas: ne, tp och cr, som innehåller respektive värden" 12", "10.26" och «2.18» Det är också viktigt att komma ihåg att det finns en tom rad för att separera rubrikerna från data.
1
2
3
4
|
POST /iot/grabar_temperatura HTTP/1.1
Host: polaridad.es
ne=12&tp=10.26&cr=2.18
|
Det slutliga målet för följande kod PHP kommer att skickas till databasservern MySQL beställningen SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
INSERT
INTO `calefacciones`
(
numero_estancia,
temperatura,
corriente
)
VALUES
(
12,
10.26,
2.18
);
|
Med vilken en ny post kommer att skapas (INSERT
)
i värmedatabasen (INTO
)calefacciones
tilldela fält (numero_estancia,temperatura,corriente)
värdena som motsvarar HTTP POST-begäran VALUES (12, 10.26, 2.18)
Kopplingen till databasen görs med funktionen mysqli_connect
enligt formatet: mysqli_connect($servidor,$usuario,$clave,$base_datos)
som returnerar en pekare till anslutningsobjektet och som använder variablerna som definierar åtkomst (som användare, lösenord...) och som tidigare har tilldelats för framtida hypotetisk användning i skriptet.
För att upptäcka om anslutningen har lyckats används funktionen mysqli_connect_errno()
som returnerar felnumret som kan ha inträffat eller noll (falskt) om anslutningen upprättades korrekt. För att meddela fel besvaras applikationen som gör HTTP-begäran med värdet noll, i detta fall programmet som körs i µC av IoT-noden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
$fin_linea=PHP_EOL;
$servidor=‘localhost’;
$usuario=‘pelaez’;
$clave=‘1234’;
$base_datos=‘base_datos_temperaturas’;
$conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
if(mysqli_connect_errno())
{
echo 0; // Devolver el valor 0 para indicar que se ha producido un error
}
else
{
$numero_estancia=(int)$_POST[‘ne’];
$temperatura=(float)$_POST[‘tp’];
$corriente=(float)$_POST[‘cr’];
$consulta_sql =‘INSERT INTO calefacciones (numero_estancia,temperatura,corriente) ‘;
$consulta_sql.=‘VALUES (‘.$numero_estancia.‘,’.$temperatura.‘,’.$corriente.‘);’;
$resultado=mysqli_query($conexion,$consulta_sql);
if($resultado) // Si no se ha producido un error al realizar la consulta…
{
echo mysqli_insert_id($conexion); // Devolver el índice del nuevo registro (¡>0!)
}
else
{
echo 0; // Devolver el valor 0 para indicar que se ha producido un error
}
mysqli_close($conexion);
}
echo $fin_linea;
|
Innan du lägger till text som är lagrad i $consulta_sql
med vilken ordern är sammansatt SQL som skickas till databasservern förbearbetas informationen som har anlänt i POST-förfrågningsvariablerna, åtminstone för att undvika en attack av SQL-injektion. I det föregående exemplet framtvingas konverteringen till motsvarande datatyp (int)
(heltal) eller (float)
(flytande kommadecimal) vilket skulle vara tillräckligt för att eliminera eventuell skadlig kod som läggs till förfrågningsdata av webbserver.
Som kan ses, i PHP-språk Periodsymbolen (.) används för att sammanfoga de texter som bildar ordningen SQL eller operatorn period och likhetstecken (.=) för att lägga till text till höger om den som redan lagrar en variabel och det enkla citattecken (‘) används också för att omsluta textkonstanter, inte bara tecken. Även om dubbla citattecken («) i det här fallet också kan användas, i PHP-språk används för att bearbeta innehållet, till exempel, inklusive variabler i texten i formatet $texto="Me llamo $nombre";
som ett alternativ till formatet $texto='Me llamo '.$nombre;
ger dig också möjlighet att inkludera citat av en typ i en annan utan att behöva använda flykttecken när dubblar alterneras inom singel eller singel inom dubbel som i uppgiften $texto='esto no hay que "escaparlo" en PHP';
.
För att köra frågan till servern MySQL funktionen används mysqli_query
med formatet mysqli_query($conexion,$consulta_sql)
som tar som parametrar objektkopplingen till databasen och texten med ordningen SQL som har komponerats.
Funktionen mysqli_query($conexion,$consulta_sql)
returnerar ett markörobjekt som kan användas för att gå igenom de returnerade data om tillämpligt eller, som i exemplet ovan, för att få information om operationen, specifikt för att känna till indexet som tilldelats den nya posten som operationen har skapat i tabellen " värmare" med funktionen mysqli_insert_id($conexion)
Värdet som returneras av mysqli_query($conexion,$consulta_sql)
kan utvärderas till falskt i en boolesk operation för att fastställa att ett fel har inträffat. I det föregående exemplet används den för att returnera, som i fallet med anslutningsfelet, en nolla till applikationen som gör POST-begäran. På detta sätt kommer programmet att returnera ett tal större än noll som representerar indexet för den nya posten om operationen är korrekt eller en noll om operationen ger ett fel.
För att frigöra resurserna som har tilldelats databasanslutningen "stängs" den med funktionen mysqli_close($conexion)
Läs information från databasen
Förutom i arkitekturer för dimmaberäkning De flesta IoT-noder begränsar sig till att skicka informationen som fångas av deras sensorer till servern, det vill säga webbserver Den kommunicerar bara med dem för att lagra informationen, så med det föregående exemplet har en stor del av de fall som kommer att uppstå i denna ansökan redan lösts. Nästa steg kan vara att skapa en webbplats som visar data som övervakas av enheter anslutna till Internet of Things, ett verk av frontend som ligger utanför det som tas upp i den här serien av tutorials.
Vad som kan hända är att en IoT-nod har en viss interaktivitet och beter sig annorlunda baserat på en historisk data eller förutser möjligheten att ändra dess beteende enligt en konfiguration som kommer till den från en server eller till och med noden är en skärm som visar en graf med den data som nyligen har övervakats jämfört med den som inhämtats vid tidigare datum. För alla dessa situationer är det också intressant att kunna läsa data från servern MySQL genom webbserver som illustreras i följande exempel som simulerar att få en lista över datumen för larmtillstånden bestämt av de ögonblick då temperaturen översteg 40°C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
$fin_linea=PHP_EOL; // Fin de línea. Usar <br> para HTML si se va a mostrar la salida en algún tipo de pantalla o consola no es necesario
$servidor=‘localhost’;
$usuario=‘pelaez’;
$clave=‘1234’;
$base_datos=‘base_datos_temperaturas’;
$conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
if(mysqli_connect_errno())
{
echo ‘Error al conectar a la base de datos: ‘ . mysqli_connect_error();
}
else
{
$consulta_sql=‘SELECT ‘;
$consulta_sql.=‘estancia, temperatura, DAY(fecha), MONTH(fecha), YEAR(fecha), TIME(fecha) ‘;
$consulta_sql.=‘FROM valor_temperaturas ‘;
$consulta_sql.=‘WHERE temperatura>40.0 ‘;
$consulta_sql.=‘ORDER BY fecha DESC;’;
$resultado=mysqli_query($conexion,$consulta_sql); // El tercer parámetro de mysqli_query, no usado, es el modo MYSQLI_STORE_RESULT por defecto o MYSQLI_USE_RESULT para grandes cantidades de datos
if($resultado) // Si no se ha producido un error al realizar la consulta
{
$total_resultado=mysqli_num_rows($resultado);
if($total_resultado) // Si se ha encontrado algún resultado
{
echo ‘Se han encontrado ‘.$total_resultado.‘ estados de alarma:’.$fin_linea;
for($numero_resultado=0;$numero_resultado<$total_resultado) // Recorrer los resultados
{
mysqli_data_seek($resultado,$numero_resultado); // Mover el cursor al registro correspondiente (no tendría por qué ser consecutivo)
$registro=mysqli_fetch_row($resultado); // Almacenar en un vector los datos del registro
echo ‘El ‘.$registro[2]; // Tercer campo de la consulta (día)
echo ‘ del ‘.$registro[3]; // Cuarto campo de la consulta (mes)
echo ‘ de ‘.$registro[4]; // Quinto campo de la consulta (año)
echo ‘ a las ‘.$registro[5]; // Sexto campo de la consulta (hora)
echo ‘ en la estancia “‘.$registro[0].‘”‘; // Primer campo de la consulta (estancia)
echo ‘ la temperatura superó el máximo de 40°C (‘.$registro[1].‘)’; // Segundo campo de la consulta (temperatura)
echo $fin_linea;
}
}
else
{
echo ‘No se ha encontrado ningún estado de alarma’.$fin_linea;
}
mysqli_free_result($resultado);
}
mysqli_close($conexion);
}
|
I exemplet ovan används kommandot för att fråga databasen SQL SELECT
enligt grundformatet SELECT campos FROM tabla WHERE condición ORDER BY campo DESC
med den enda egenheten att lägga till funktionerna i datumfältet DAY
, MONTH
, YEAR
y TIME
för att få fram dag, månadsnummer, år och tid separat. Villkoret är att temperaturen är högre än 40.0 och ordnas med datumfältet från högsta (mest aktuella) till lägsta (äldsta) vilket anger det med klausulen DESC
För att gå igenom de värden som returneras av frågan från en loop for
med en känd dimension används funktionen mysqli_num_rows($resultado)
som anger antalet poster som har hittats. Med funktionen mysqli_data_seek($resultado,$numero_resultado)
resultatmarkören kan flyttas till en specifik position uttryckt av loopräknaren for
, $numero_resultado
, i exemplet.
För att lagra de fält i posten som resultatmarkören pekar på i en vektor, används funktionen mysqli_fetch_row($resultado)
som tilldelas variabeln $registro
som senare kommer att användas för att bilda en fras med de olika värdena, som kommer åt dem genom deras index.
När alla värden har passerats släpps resurserna som tilldelats frågeresultatet SQL med funktion mysqli_free_result($resultado)
Bearbeta information från databasen. Jämför värden.
Vid vissa tillfällen är det bekvämt att informationsbehandlingen centraliseras på servern även om det skulle vara möjligt att göra det i IoT-noderna i stil dimmaberäkning. I följande exempel är skälen som simuleras för att göra det säkerhet; Noden har information om sin nyckel (lås) och om en begäran (nyckel) men vet inte om det är lämpligt att ge vika för kombinationen av båda, så den måste konsultera servern som är den som fattar beslutet och informerar noden genom att svara noll (för att indikera en misslyckad jämförelse) eller en (för att indikera att jämförelsen lyckades) baserat på resultatet av en fråga till din databas.
Med denna ursäkt kan du se ett exempel där data tas emot från enheten som är ansluten till Internet of Things (en nyckelkod och en låskod), ett resultat returneras (ett eller noll beroende på att resultatet är sant eller falskt) och en mindre bearbetning av informationen genomförs som består i att jämföra resultaten som erhålls vid konsultation av databasen med de som skickas av IoT-noden.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
$fin_linea=PHP_EOL;
$servidor=‘localhost’;
$usuario=‘pelaez’;
$clave=‘1234’;
$base_datos=‘base_datos_puertas’;
$conexion=mysqli_connect($servidor,$usuario,$clave,$base_datos);
if(mysqli_connect_errno())
{
echo 0; // Devolver el valor 0 para indicar que la comparación no es válida o que se ha producido un error (en este caso es un error)
}
else
{
$cerradura=hexdec($_POST[“c”]);
$llave=hexdec($_POST[“l”]);
$consulta_sql=‘SELECT llave FROM cerraduras WHERE cerradura=”.$cerradura.“;’;
$resultado=mysqli_query($conexion,$consulta_sql);
if($resultado) // Si no se ha producido un error al realizar la consulta
{
$total_resultado=mysqli_num_rows($resultado);
if($total_resultado) // Si se ha encontrado algún resultado
{
$numero_resultado=0;
$buscando_cerradura=TRUE;
while($buscando_cerradura&&$numero_resultado<$total_resultado)
{
mysqli_data_seek($resultado,$numero_resultado);
$registro=mysqli_fetch_row($resultado);
if($registro[0]==$llave)
{
$buscando_cerradura=FALSE;
}
else
{
$numero_resultado++;
}
}
// echo !$buscando_cerradura;
if($buscando_cerradura)
{
echo 0; // Devolver el valor 0 para indicar que la comparación no es válida (o que se ha producido un error; y aquuí no es el caso)
}
else
{
echo 1; // Devolver el valor 1 para indicar que la comparación SÍ es válida
}
}
else
{
echo 0; // Devolver el valor 0 para indicar que la comparación no es válida o que se ha producido un error
}
}
else
{
echo 0; // Devolver el valor 0 para indicar que la comparación no es válida o que se ha producido un error
}
mysqli_close($conexion);
}
echo $fin_linea;
|
I det föregående exemplet används hexdec-funktionen för att få ett decimaltal från en text som representerar ett hexadecimalt tal och är den som skickas av IoT-enheten. Den extra fördelen med att använda denna funktion är att undvika, som förklarats tidigare, en attack genom att lägga till kod SQL skadlig mot uppgifterna i POST-begäran.
Post kommentar