Достъп до базата данни от езика за програмиране PHP
В тази последна статия от поредицата за Използване на уеб сървър за съхраняване на данни от устройства, свързани към Интернет на нещата, обяснява как да записвате в база данни MySQL информацията, която IoT възлите изпращат до сървъра, правейки HTTP POST заявки. Читателите на тази статия, на целия блог, може да не са особено запознати с програмирането в PHP език но със сигурност да с програмирането на микроконтролери на езици C o C + + така че, с изключение на някои подробности, като например предшестване на знака за долар ($) към променливите, вие ще можете да следвате примерите без нужда от допълнителни обяснения, тъй като те са направени след много неутрален стил на програмиране, неспецифичен за PHP.
Съхранявайте информация в базата данни
Както е обяснено в статията за IoT съхранение на данни чрез отправяне на HTTP POST заявки към уеб сървър, в края на заглавките, тялото на POST заявката съдържа данните, които се изпращат до сървъра. Най-често срещаният начин за изпращане на тази информация до сървъра е в обикновен текстов формат, защото е по-лесно да се анализира дори „ръчно“. Когато данните, изпратени до сървъра, са сложни, със сигурност ще бъде удобно да ги структурирате, като използвате например формата XML o JSON. При обичайното използване на уеб сървър за управление на информация от устройства, свързани към Интернет на нещата, не е обичайно да се нуждаете от структура от данни, така че е нормално да ги изпращате в обикновен текст във формат variable=valor
.
В HTTP POST заявката от следния пример, ресурсът (обикновено уеб страница) /iot/grabar_temperatura се изисква от сървъра polaridad.es и се изпращат три променливи: ne, tp и cr, които съответно съдържат стойностите " 12", "10.26 » и «2.18» Също така е важно да запомните, че има празен ред за разделяне на заглавките от данните.
1
2
3
4
|
POST /iot/grabar_temperatura HTTP/1.1
Host: polaridad.es
ne=12&tp=10.26&cr=2.18
|
Крайната цел на следния код PHP ще изпрати до сървъра на базата данни MySQL редът 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
);
|
С който ще бъде създаден нов запис (INSERT
)
в базата данни за отопление (INTO
)calefacciones
присвояване на полета (numero_estancia,temperatura,corriente)
стойностите, съответстващи на HTTP POST заявката VALUES (12, 10.26, 2.18)
Връзката с базата данни се осъществява с функцията mysqli_connect
според формата: mysqli_connect($servidor,$usuario,$clave,$base_datos)
който връща указател към обекта за връзка и който използва променливите, които дефинират достъпа (като потребителско име, парола...) и които са били предварително присвоени за бъдещи хипотетични употреби в скрипта.
За да се установи дали връзката е била успешна, се използва функцията mysqli_connect_errno()
който връща номера на грешката, която може да е възникнала, или нула (false), ако връзката е установена правилно. За да уведоми за грешки, приложението, което прави HTTP заявката, получава отговор със стойност нула, в този случай програмата, която се изпълнява в µC на IoT възела.
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;
|
Преди да добавите към текст, който се съхранява в $consulta_sql
с които е съставена заповедта SQL която се изпраща на сървъра на базата данни, информацията, която е пристигнала в променливите на POST заявка, се обработва предварително, като минимум, за да се избегне атака от SQL инжекция. В предишния пример преобразуването към съответния тип данни е принудително (int)
(цяло число) или (float)
(десетичен знак с плаваща запетая), което би било достатъчно, за да елиминира възможния злонамерен код, добавен към данните на заявката от servidor web.
Както се вижда, в PHP език Символът за точка (.) се използва за свързване на текстовете, които формират реда SQL или операторът за точка и знак за равенство (.=) за добавяне на текст отдясно на този, който вече съхранява променлива, а единичните кавички (‘) също се използват за ограждане на текстови константи, а не само на знаци. Въпреки че в този случай могат да се използват и двойни кавички («), в PHP език се използват за обработка на съдържанието, например, включително променливи в текста във формата $texto="Me llamo $nombre";
като алтернатива на формата $texto='Me llamo '.$nombre;
също така ви позволява да включвате кавички от един тип в друг, без да се налага да използвате знаци за избягване, когато двойните се редуват в единични или единични в двойни, както е в заданието $texto='esto no hay que "escaparlo" en PHP';
.
За да изпълните заявката към сървъра MySQL се използва функцията mysqli_query
с формата mysqli_query($conexion,$consulta_sql)
който приема като параметри обекта-връзка към базата данни и текста с поръчката SQL който е съставен.
Функцията mysqli_query($conexion,$consulta_sql)
връща обект-курсор, който може да се използва за обхождане на върнатите данни, ако е приложимо, или, както в примера по-горе, за получаване на информация за операцията, по-специално за познаване на индекса, присвоен на новия запис, който операцията е създала в таблицата " нагреватели" с функцията mysqli_insert_id($conexion)
Стойността, върната от mysqli_query($conexion,$consulta_sql)
може да изчисли false в булева операция, за да определи дали е възникнала грешка. В предишния пример се използва за връщане, както в случая на грешка при свързване, на нула към приложението, което прави POST заявката. По този начин програмата ще върне число, по-голямо от нула, което представлява индекса на новия запис, ако операцията е правилна, или нула, ако операцията доведе до грешка.
За да освободите ресурсите, които са били присвоени на връзката към базата данни, тя се „затваря“ с помощта на функцията mysqli_close($conexion)
Прочетете информация от базата данни
Освен в архитектурите за изчисления за мъгла Повечето IoT възли се ограничават до изпращане на информацията, уловена от техните сензори, към сървъра, т.е. servidor web Той само комуникира с тях, за да съхранява информацията, така че с предишния пример голяма част от случаите, които ще възникнат в това приложение, вече са решени. Следващата стъпка може да бъде създаването на уебсайт, който показва данните, наблюдавани от устройства, свързани с Интернет на нещата, дело на интерфейса което е извън това, което се обсъжда в тази поредица от уроци.
Това, което може да се случи, е, че IoT възел има определена интерактивност и се държи по различен начин въз основа на исторически данни или предвижда възможността за промяна на поведението му според конфигурация, която идва от сървър или дори възелът е екран, който показва графика с данните, които са били наблюдавани наскоро в сравнение с тези, получени на предишни дати. За всички тези ситуации също е интересно да можете да четете данни от сървъра MySQL чрез servidor web както е илюстрирано в следния пример, който симулира получаване на списък с датите на алармените състояния, определени от моментите, в които температурата надвишава 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);
}
|
В примера по-горе, за запитване до базата данни се използва командата SQL SELECT
според основния формат SELECT campos FROM tabla WHERE condición ORDER BY campo DESC
с единствената особеност на добавяне на функциите към полето за дата DAY
, MONTH
, YEAR
y TIME
за да получите отделно деня, номера на месеца, годината и часа. Наложеното условие е температурата да е по-висока от 40.0 и да е подредена с помощта на полето за дата от най-високата (най-актуалната) до най-ниската (най-старата), като я указва с клаузата DESC
За да преминете през стойностите, върнати от заявката от цикъл for
с известна размерност се използва функцията mysqli_num_rows($resultado)
което показва броя на намерените записи. С функцията mysqli_data_seek($resultado,$numero_resultado)
курсорът на резултатите може да бъде преместен до определена позиция, изразена от брояча на цикъла for
, $numero_resultado
, в примера.
За съхраняване във вектор на полетата на записа, към който сочи курсорът на резултата, се използва функцията mysqli_fetch_row($resultado)
който е присвоен на променливата $registro
които по-късно ще бъдат използвани за образуване на фраза с различните стойности, достъпвайки ги чрез техните индекси.
След като всички стойности бъдат преминати, ресурсите, присвоени на резултата от заявката, се освобождават SQL с функция mysqli_free_result($resultado)
Обработка на информация от базата данни. Сравнете стойностите.
В някои случаи е удобно обработката на информацията да бъде централизирана на сървъра, дори ако е възможно да се направи в IoT възлите в стила изчисления за мъгла. В следващия пример причините, които са симулирани за това, са сигурност; Възелът има информация за своя ключ (заключване) и за заявка (ключ), но не знае дали е подходящо да даде път на комбинацията от двете, така че трябва да се консултира със сървъра, който е този, който взема решението и информира възела, като отговаря нула (за да посочи неуспешно сравнение) или единица (за да покаже, че сравнението е било успешно) въз основа на резултата от заявка към вашата база данни.
С това извинение можете да видите пример, в който се получават данни от устройството, свързано към Интернет на нещата (ключов код и код за заключване), връща се резултат (едно или нула в зависимост от това дали резултатът е верен или неверен) и извършва се малка обработка на информацията, състояща се в сравняване на резултатите, получени при справка с базата данни с тези, изпратени от IoT възела.
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;
|
В предишния пример функцията hexdec се използва за получаване на десетично число от текст, който представлява шестнадесетично число и е този, изпратен от IoT устройството. Допълнителното предимство на използването на тази функция е да се избегне, както беше обяснено по-горе, атака чрез добавяне на код SQL злонамерени към данните на POST заявката.
Публикувай коментар