เข้าถึงฐานข้อมูลจากภาษาการเขียนโปรแกรม PHP
ในบทความสุดท้ายของซีรีส์เรื่อง การใช้เว็บเซิร์ฟเวอร์เพื่อจัดเก็บข้อมูลจากอุปกรณ์ที่เชื่อมต่อกับ Internet of Things, อธิบายวิธีการบันทึกลงฐานข้อมูล MySQL ข้อมูลที่โหนด IoT ส่งไปยังเซิร์ฟเวอร์ที่ทำการร้องขอ HTTP POST ผู้อ่านบทความนี้จากทั้งบล็อกอาจไม่คุ้นเคยกับการเขียนโปรแกรมใน ภาษาพีพีพี แต่ใช่แน่นอนกับการเขียนโปรแกรมของ ไมโครคอนโทรลเลอร์ ในภาษา C o C + + ดังนั้น ยกเว้นรายละเอียดบางอย่าง เช่น นำเครื่องหมายดอลลาร์ ($) นำหน้าตัวแปร คุณจะสามารถติดตามตัวอย่างได้โดยไม่จำเป็นต้องอธิบายเพิ่มเติม เนื่องจากได้ทำตามรูปแบบการเขียนโปรแกรมที่เป็นกลางมาก โดยไม่เฉพาะเจาะจงกับ PHP.
เก็บข้อมูลไว้ในฐานข้อมูล
ตามที่อธิบายไว้ในบทความเรื่อง การจัดเก็บข้อมูล IoT โดยส่งคำขอ HTTP POST ไปยังเว็บเซิร์ฟเวอร์ที่ส่วนท้ายของส่วนหัว เนื้อความของคำขอ POST จะมีข้อมูลที่ส่งไปยังเซิร์ฟเวอร์ วิธีทั่วไปในการส่งข้อมูลนี้ไปยังเซิร์ฟเวอร์คือรูปแบบข้อความธรรมดา เนื่องจากง่ายต่อการวิเคราะห์แม้จะ "ด้วยตนเอง" เมื่อข้อมูลที่ส่งไปยังเซิร์ฟเวอร์มีความซับซ้อน จะสะดวกอย่างแน่นอนในการจัดโครงสร้างโดยใช้รูปแบบ เช่น XML o JSON. ในการใช้งานเว็บเซิร์ฟเวอร์ตามปกติเพื่อจัดการข้อมูลจากอุปกรณ์ที่เชื่อมต่อกับ Internet of Things ไม่ใช่เรื่องธรรมดาที่จะต้องมีโครงสร้างข้อมูล ดังนั้นจึงเป็นเรื่องปกติที่จะส่งข้อมูลในรูปแบบข้อความธรรมดาในรูปแบบ 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()
ซึ่งส่งคืนหมายเลขข้อผิดพลาดที่อาจเกิดขึ้นหรือศูนย์ (เท็จ) หากสร้างการเชื่อมต่ออย่างถูกต้อง เพื่อแจ้งข้อผิดพลาด แอปพลิเคชันที่สร้างคำขอ HTTP จะได้รับการตอบสนองด้วยค่าศูนย์ ในกรณีนี้คือโปรแกรมที่รันใน ไมโครซี ของโหนด 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)
(จุดทศนิยมทศนิยม) ซึ่งจะเพียงพอที่จะกำจัดโค้ดอันตรายที่เป็นไปได้ที่เพิ่มลงในข้อมูลคำขอด้วย เว็บเซอร์ด.
อย่างที่เห็นใน ภาษาพีพีพี สัญลักษณ์จุด (.) ใช้เพื่อเชื่อมข้อความที่สร้างลำดับ SQL หรือตัวดำเนินการเครื่องหมายจุดและเท่ากับ (.=) เพื่อเพิ่มข้อความทางด้านขวาของตัวแปรที่เก็บตัวแปรไว้แล้ว และเครื่องหมายคำพูดเดี่ยว (') ยังใช้เพื่อใส่ค่าคงที่ของข้อความ ไม่ใช่แค่อักขระ แม้ว่าในกรณีนี้เครื่องหมายคำพูดคู่ («) ก็สามารถใช้ได้เช่นกัน ภาษาพีพีพี ใช้ในการประมวลผลเนื้อหา เช่น รวมถึงตัวแปรภายในข้อความในรูปแบบ $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)
สามารถประเมินเป็นเท็จในการดำเนินการบูลีนเพื่อพิจารณาว่ามีข้อผิดพลาดเกิดขึ้น ในตัวอย่างก่อนหน้านี้ ใช้เพื่อส่งคืนค่าศูนย์ให้กับแอปพลิเคชันที่สร้างคำขอ POST เช่นในกรณีของข้อผิดพลาดในการเชื่อมต่อ ด้วยวิธีนี้ โปรแกรมจะส่งกลับตัวเลขที่มากกว่าศูนย์ซึ่งแสดงถึงดัชนีของบันทึกใหม่หากการดำเนินการถูกต้อง หรือส่งกลับค่าศูนย์หากการดำเนินการก่อให้เกิดข้อผิดพลาด
หากต้องการเพิ่มทรัพยากรที่กำหนดให้กับการเชื่อมต่อฐานข้อมูล จะถูก "ปิด" โดยใช้ฟังก์ชัน mysqli_close($conexion)
อ่านข้อมูลจากฐานข้อมูล
ยกเว้นในสถาปัตยกรรมสำหรับ คอมพิวเตอร์หมอก โหนด IoT ส่วนใหญ่จำกัดตัวเองให้ส่งข้อมูลที่เซ็นเซอร์จับไปยังเซิร์ฟเวอร์ ซึ่งก็คือ เว็บเซอร์ด โดยจะสื่อสารกับพวกเขาเพื่อจัดเก็บข้อมูลเท่านั้น ดังนั้นด้วยตัวอย่างก่อนหน้านี้ ส่วนที่ดีของกรณีปัญหาที่จะเกิดขึ้นกับแอปพลิเคชันนี้ได้รับการแก้ไขแล้ว ขั้นตอนต่อไปอาจเป็นการสร้างเว็บไซต์ที่แสดงข้อมูลที่ตรวจสอบโดยอุปกรณ์ที่เชื่อมต่อกับ Internet of Things ซึ่งเป็นผลงานของ ส่วนหน้า ซึ่งอยู่นอกเหนือสิ่งที่ถูกกล่าวถึงในบทช่วยสอนชุดนี้
สิ่งที่สามารถเกิดขึ้นได้คือโหนด IoT มีการโต้ตอบบางอย่างและทำงานแตกต่างออกไปตามข้อมูลในอดีตหรือคาดการณ์ถึงความเป็นไปได้ในการเปลี่ยนแปลงพฤติกรรมตามการกำหนดค่าที่มาจากเซิร์ฟเวอร์ หรือแม้แต่โหนดก็เป็นหน้าจอที่แสดงกราฟ ด้วยข้อมูลที่ได้รับการตรวจสอบเมื่อเร็ว ๆ นี้เปรียบเทียบกับที่ได้รับในวันที่ก่อนหน้า สำหรับทุกสถานการณ์เหล่านี้ การอ่านข้อมูลจากเซิร์ฟเวอร์ก็น่าสนใจเช่นกัน MySQL ผ่าน เว็บเซอร์ด ดังแสดงในตัวอย่างต่อไปนี้ซึ่งจำลองการรับรายการวันที่ของสถานะการเตือนซึ่งกำหนดโดยช่วงเวลาที่อุณหภูมิเกิน 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 ในลักษณะนี้ก็ตาม คอมพิวเตอร์หมอก. ในตัวอย่างต่อไปนี้ เหตุผลที่จำลองขึ้นสำหรับการทำเช่นนั้นคือเรื่องความปลอดภัย โหนดมีข้อมูลเกี่ยวกับคีย์ (ล็อค) และคำขอ (คีย์) แต่ไม่รู้ว่าเหมาะสมหรือไม่ที่จะหลีกทางให้ทั้งสองอย่างรวมกัน ดังนั้นจึงต้องปรึกษาเซิร์ฟเวอร์ซึ่งเป็นผู้ตัดสินใจและ แจ้งโหนดโดยการตอบสนองเป็นศูนย์ (เพื่อระบุการเปรียบเทียบที่ล้มเหลว) หรือหนึ่ง (เพื่อระบุว่าการเปรียบเทียบสำเร็จ) ตามผลลัพธ์ของการสืบค้นไปยังฐานข้อมูลของคุณ
ด้วยข้อแก้ตัวนี้ คุณสามารถดูตัวอย่างที่ได้รับข้อมูลจากอุปกรณ์ที่เชื่อมต่อกับ Internet of Things (รหัสกุญแจและรหัสล็อค) ผลลัพธ์จะถูกส่งกลับ (หนึ่งหรือศูนย์ ขึ้นอยู่กับผลลัพธ์ที่เป็นจริงหรือเท็จ) และ การประมวลผลข้อมูลเล็กน้อยประกอบด้วยการเปรียบเทียบผลลัพธ์ที่ได้รับเมื่อปรึกษาฐานข้อมูลกับผลลัพธ์ที่ส่งโดยโหนด 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
แสดงความคิดเห็น