เข้าถึงฐานข้อมูลจากภาษาการเขียนโปรแกรม 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
แสดงความคิดเห็น