댓글 검색 목록

[php] PHP를 사용하여 MYSQL에서 배열을 저장하고 검색하는 방법

페이지 정보

작성자 운영자 작성일 20-04-18 23:35 조회 1,203 댓글 0

배열 저장


PHP를 사용하여 MySQL에서 배열을 저장하고 검색하는 방법에 대한 자습서에 오신 것을 환영합니다. 

PHP에 배열이 있고 데이터베이스에 저장하고 싶습니까? MySQL은 플랫 문자열, 숫자 및 타임 스탬프 만 사용합니다. 배열이나 객체를 허용하지 않습니다.


짧은 대답은 – 우리는 MySQL에 직접 배열을 삽입 할 수 없습니다. 

삽입하기 전에 먼저 JSON, implode 또는 serialize를 사용하여 배열을 문자열로 변환해야 합니다. 예를 들어, $ sql =“INSERT INTO 테이블 (ID, 데이터) VALUES (999,””json_encode ($ array)”“”)”;


그러나 우리는 어떻게 그렇게 합니까? 인코딩 된 문자열을 어떻게 검색합니까? 인코딩 된 문자열이 실제로 가장 좋은 솔루션입니까? 몇 가지 예를 살펴보고 계속 읽으십시오!


ⓘ이 튜토리얼의 시작 부분에 모든 예제 코드가 포함 된 zip 파일이 포함되어 있으므로 모든 것을 복사하여 붙여 넣을 필요가 없습니다.


소스 코드 다운로드 


먼저 약속 된 예제 소스 코드에 대한 다운로드 링크가 있습니다.


소스 코드 다운로드 


모든 예제 코드를 다운로드하려면 여기를 클릭하십시오. MIT 라이센스에 따라 릴리스 했으므로 코드 위에 빌드하거나 자신의 프로젝트에서 자유롭게 사용할 수 있습니다.


폴더 


다음은 zip 파일에서 폴더를 구성하는 방법에 대한 간략한 소개입니다.

  • lib : 모든 PHP 라이브러리 파일을 저장하는 곳.
  • SQL : 데이터베이스를 빌드 하는 데 필요한 모든 SQL 파일

빠른 시작 

  • 폴더에 다운로드하여 압축을 풉니다.
  • 더미 테스트 데이터베이스를 작성하고 SQL 폴더의 모든 파일을 가져 오십시오.
  • lib / 2-database.php에서 데이터베이스 설정을 원하는 대로 변경하십시오.
  • 웹 브라우저를 시작하고 예제 3 및 4를 실행하십시오.

DUMMY 데이터베이스 테이블 


코드로 들어가기 전에이 예제의 기초를 설정하여 시작하겠습니다. 좋아하는 색상을 저장하는 간단한 사람 테이블을 만들 것입니다.


DUMMY PEOPLE 테이블 


CREATE TABLE `people` ( `id` int(11) NOT NULL, `name` varchar(255) NOT NULL, `fav_color` text NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `people` ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `name` (`name`); ALTER TABLE `people` MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 


FieldDescription
idPerson ID, primary key and auto-increment.
nameThe person’s name, unique.
fav_colorThe person’s favorite colors.

데이터베이스 라이브러리 


더미 예제 테이블을 만들었으므로 이제 모든 SQL 무거운 작업을 수행 할 각각의 PHP 라이브러리 파일을 작성하겠습니다.


데이터베이스 라이브러리


<?php /* [SETTINGS] */ // MUTE NOTICES error_reporting(E_ALL & ~E_NOTICE); // PATH define('PATH_LIB', __DIR__ . DIRECTORY_SEPARATOR); // DATABASE SETTINGS // ! CHANGE THESE TO YOUR OWN ! define('DB_HOST', 'localhost'); define('DB_NAME', 'test'); define('DB_CHARSET', 'utf8'); define('DB_USER', 'root'); define('DB_PASSWORD', ''); /* [DATABASE LIBRARY] */ class DB { private $pdo = null; private $stmt = null; public $lastID = null; function __construct () { // __construct() : connect to the database // PARAM : DB_HOST, DB_CHARSET, DB_NAME, DB_USER, DB_PASSWORD // ATTEMPT CONNECT try { $str = "mysql:host=" . DB_HOST . ";charset=" . DB_CHARSET; if (defined('DB_NAME')) { $str .= ";dbname=" . DB_NAME; } $this->pdo = new PDO( $str, DB_USER, DB_PASSWORD, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false ] ); } // ERROR - CRITICAL STOP - THROW ERROR MESSAGE catch (Exception $ex) { print_r($ex); die(); } } function __destruct () { // __destruct() : close connection when done if ($this->stmt !== null) { $this->stmt = null; } if ($this->pdo !== null) { $this->pdo = null; } } function exec ($sql, $data=null) { // exec() : run insert, replace, update, delete query // PARAM $sql : SQL query // $data : array of data try { $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($data); $this->lastID = $this->pdo->lastInsertId(); } catch (Exception $ex) { $this->error = $ex; return false; } $this->stmt = null; return true; } function fetchAll ($sql, $cond=null, $key=null, $value=null) { // fetchAll() : perform select query (multiple rows expected) // PARAM $sql : SQL query // $cond : array of conditions // $key : sort in this $key=>data order, optional // $value : $key must be provided. If string provided, sort in $key=>$value order. If function provided, will be a custom sort. $result = []; try { $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($cond); // Sort in given order if (isset($key)) { if (isset($value)) { if (is_callable($value)) { while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) { $result[$row[$key]] = $value($row); } } else { while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) { $result[$row[$key]] = $row[$value]; } } } else { while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) { $result[$row[$key]] = $row; } } } // No key-value sort order else { $result = $this->stmt->fetchAll(); } } catch (Exception $ex) { $this->error = $ex; return false; } // Return result $this->stmt = null; return count($result)==0 ? false : $result ; } } $libDB = new DB(); ?> 


FunctionDescription
__constructConstructor, automatically connects to the database when the object is created.
__destructDestructor, automatically closes database connection when the object is destroyed.
execRun insert, replace, update, or delete query.
fetchAllRun a select query, returns a multidimensional array with results from multiple rows.

저장 및 검색 배열 


이제 모든 기초가 설정되었으므로 마지막 단계는 데이터베이스 라이브러리를 사용하여 인코딩 된 문자열을 저장하는 것입니다. 그런 다음 배열을 디코딩하여 다시 검색 할 수 있습니다.


1. JSON 사용 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) LET'S CREATE A DUMMY JOHN DOE ENTRY $name = "John Doe"; $colors = ["red", "green", "blue"]; // (3) THE SQL + DATA // Note - We simply JSON encode the favorite colors into a string echo $libDB->exec( "INSERT INTO `people` (`name`, `fav_color`) VALUES (?, ?)", [$name, json_encode($colors)] ) ? "OK" : $libDB->error; ?> 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) FETCH JOHN DOE $person = $libDB->fetchAll( "SELECT * FROM `people` WHERE `name`=?", ["John Doe"] ); // (3) THE RETRIEVED PERSON // We can get back the favorite colors with json decode if (count($person)!=false) { echo "Retrieved data: "; print_r($person); echo "<br><br><br>Decoded favorite colors: "; $colors = json_decode($person[0]['fav_color']); print_r($colors); } ?> 



이 첫 번째 방법은 json_encode를 사용하여 배열을 문자열로 인코딩 한 다음 json_decode의 반대쪽을 사용하여 다시 검색합니다. JSON이 무엇인지 모르는 분들을 위해 아래의 엑스트라 섹션에 추가 링크를 남겨 두겠습니다.


2. IMPLODE & EXPLODE 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) CREATE A DUMMY JANE DOE ENTRY $name = "Jane Doe"; $colors = ["red", "pink", "purple"]; // (3) THE SQL + DATA // Implode will "combine" the array into a string, values separated by a comma echo $libDB->exec( "INSERT INTO `people` (`name`, `fav_color`) VALUES (?, ?)", [$name, implode(",", $colors)] ) ? "OK" : $libDB->error; ?> 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) FETCH JANE DOE FROM THE DATABSE $person = $libDB->fetchAll( "SELECT * FROM `people` WHERE `name`=?", ["Jane Doe"] ); // (3) THE RETRIEVED DATA // Explode will "seperate" the string back to an array if (count($person)!=false) { echo "Retrieved data: "; print_r($person); echo "<br><br><br>Decoded favorite colors: "; $colors = explode(",", $person[0]['fav_color']); print_r($colors); } ?> 


이것은 JSON 인 코드 / 디코딩을 사용하는 대안이며, implode를 사용하여 배열을 문자열로 결합하고 explode를 사용하여 검색하는 것입니다. 그러나 2 차원 배열 (인덱싱 또는 연관 배열)에서만 작동합니다.


3. SERIALIZE & UNSERIALIZE 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) CREATE A DUMMY JOSH DOE ENTRY $name = "Josh Doe"; $colors = ["green", "lime", "cyan"]; // (3) THE SQL + DATA // Serialize will create a string representation of a php variable, array, or object echo $libDB->exec( "INSERT INTO `people` (`name`, `fav_color`) VALUES (?, ?)", [$name, serialize($colors)] ) ? "OK" : $libDB->error; ?> 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) FETCH JOSH DOE.COM FROM THE DATABSE $person = $libDB->fetchAll( "SELECT * FROM `people` WHERE `name`=?", ["Josh Doe"] ); // (3) THE RETRIEVED DATA // We can get back the favorite colors with unserialize if (count($person)!=false) { echo "Retrieved data: "; print_r($person); echo "<br><br><br>Decoded favorite colors: "; $colors = unserialize($person[0]['fav_color']); print_r($colors); } ?> 


이 마지막 대안은 변수, 배열 및 객체를 문자열로 인코딩하는 PHP의 방법인 직렬화 및 직렬화 해제를 사용합니다.


최고는 무엇입니까? 


개인적으로 JSON은 보편적으로 지원되므로 사용하는 것이 좋습니다. PHP뿐만 아니라 Javascript, ASP, C #, Python 등도 있습니다. JSON 형식을 사용하면 플랫폼 간 현명한 작업이 훨씬 쉬워집니다.


별도 테이블 사용 


인코딩 된 문자열을 사용하면 멋지지만 몇 가지 단점이 있습니다. 선호하는 색상을 독점적으로 저장할 다른 테이블을 만들어 이 섹션의 대체 솔루션을 살펴 보겠습니다.


인코딩 된 문자열이 나쁜 이유 


인코딩 된 문자열에 대해 나쁜 점은 무엇입니까? 가장 인기 있는 색상을 찾아야 하는 다음 시나리오를 고려하십시오. 데이터베이스에서 인코딩 된 모든 문자열을 추출하고 디코딩 한 다음 수동으로 계산해야 합니다.


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) GET ALL COLORS + DATA CRUNCHING $all = $libDB->fetchAll("SELECT `fav_color` FROM `people`"); $total = []; foreach ($all as $a) { $colors = json_decode($a['fav_color']); foreach ($colors as $c) { if ($total[$c]) { $total[$c]++; } else { $total[$c] = 1; } } } ?> 


수천 개의 항목이 있으면 매우 느리고 비효율적입니다. 그렇기 때문에 인코딩 된 문자열이 나쁘고 스마트한 방법은 선호하는 색상을 저장하기 위해 별도의 테이블을 만드는 것입니다.


FAVORITE COLORS TABLE 


CREATE TABLE `fav_color` ( `id` int(11) NOT NULL, `color` varchar(64) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `fav_color` ADD PRIMARY KEY (`id`,`color`); 


FieldDescription
idPerson ID, partial primary key.
colorColor name, partial primary key.

STORING DATA 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) CREATE A JAY DOE ENTRY $name = "Jay Doe"; $colors = ["cyan", "magenta", "yellow", "blue"]; // Create main entry first $pass = $libDB->exec("INSERT INTO `people` (`name`) VALUES (?)", [$name]); // Create color entries if ($pass) { $id = $libDB->lastID; $sql = "INSERT INTO `fav_color` (`id`, `color`) VALUES "; $data = []; foreach ($colors as $c) { $sql .= "(?, ?),"; $data[] = $id; $data[] = $c; } $sql = substr($sql, 0, -1) . ";"; $pass = $libDB->exec($sql, $data); } // (3) DONE echo $pass ? "OK" : $libDB->error ; ?> 


이 대안 솔루션으로 데이터를 저장하는 것은 조금 더 지루할 것이지만 우리가 하는 일은 단순히 색상 배열을 반복하여 항목과 SQL을 만드는 것입니다.


RETRIEVING THE ARRAY 


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) FETCH JAY DOE FROM THE DATABSE $person = $libDB->fetchAll("SELECT * FROM `people` WHERE `name`=?", ["Jay Doe"]); // (3) THE RETRIEVED DATA if ($person != false) { echo "Retrieved data: "; print_r($person); // (4) GET FAVORITE COLORS $colors = $libDB->fetchAll("SELECT `color` FROM `fav_color` WHERE `id`=?", [$person[0]['id']]); echo "<br><br><br>Favorite colors: "; print_r($colors); } ?> 


선호하는 색상을 가져 오려면 여기에서 디코딩 할 필요가 없습니다. 데이터베이스에서 모든 데이터를 다시 꺼내십시오.


별도의 테이블이 감지되는 이유 


이제 선호하는 별도의 색상 표를 사용하여 단 한 줄의 SQL로 데이터 마이닝을 매우 쉽게 수행 할 수 있습니다.


<?php // (1) LOAD DATABASE LIBRARY require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2-database.php" ; // (2) DATA MINING // This will get colors that people like - From most popular to least popular $data = $libDB->fetchAll("SELECT `color`, COUNT(*) `count` FROM `fav_color` GROUP BY `color` ORDER BY `count` DESC"); print_r($data); ?> 


별도의 테이블을 생성하는 진정한 가치는 코딩의 편의성이 아니라 분석의 용이성에 있습니다. 따라서 몇 줄의 코드를 자르는 게으름은 적절한 데이터 마이닝을 수행하는 능력을 잃는 비용이 발생한다는 점에서 항상 장단점을 신중하게 평가하십시오.


유용한 비트 및 링크 


이것으로 코드가 완성되었으며 여기에 유용한 몇 가지 추가 기능이 있습니다.


참조 및 링크 



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.