댓글 검색 목록

[php] PHP MySQL을 사용한 3 단계 국가 주 도시 드롭 다운

페이지 정보

작성자 운영자 작성일 20-04-20 10:30 조회 1,122 댓글 0

계단식 종속 제거 


PHP와 MySQL을 사용하여 AJAX 중심 국가, 주, 도시 드롭 다운 목록을 만드는 방법에 대한 자습서를 시작합니다. 따라서 사용자가 국가, 주 또는 도시를 선택하면 캐스케이드 로드 하는 일급 비밀 닌자 프로젝트를 진행하고 있습니까? 실제로 그렇게 어렵지는 않지만 많은 양의 데이터가 필요합니다. 

이 안내서는 단계별로 수행하는 방법을 단계별로 안내합니다. 계속 읽으십시오!


ⓘ이 튜토리얼을 시작할 때 모든 예제 소스 코드가 포함 된 zip 파일을 포함 시켰으므로 모든 내용을 복사하여 붙여 넣을 필요가 없습니다.


다운로드 


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


소스 코드 다운로드 


소스 코드를 다운로드하려면 여기를 클릭하십시오. MIT 라이센스에 따라 릴리스되었으므로 그 위에 빌드하거나 자신의 프로젝트에서 자유롭게 사용하십시오.


폴더 


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


  • lib : 모든 라이브러리 파일을 저장하는 곳.
  • public : 우리는 모든 CSS와 자바 스크립트를 넣습니다.
  • SQL : 데이터베이스를 빌드하는 데 필요한 모든 SQL 파일 모두 가져온 후에 안전하게 삭제할 수 있습니다.

빠른 시작 


  • 폴더에 다운로드하여 압축을 풉니다.
  • 데이터베이스를 작성하고 sql 폴더의 모든 파일을 가져 오십시오.
  • lib / 2a-config.php에서 데이터베이스 설정을 변경하십시오.
  • 브라우저에서 index.html에 액세스하십시오.
  • PHP 파일과 AJAX 오류가 없습니까? 파일 경로가 올바른지 확인하십시오.
    lib/2a-config.php – define('PATH_LIB', 'ABSOLUTE PATH HERE')
    3a-index.html – All the <script> and <link> tags.
    public/3b-demo.js – xhr.open('POST', "PATH/2c-ajax-geo.php")

필기 해 


zip 파일에는 전 세계 모든 국가와 미국의 주 및 도시에 대한 예제 데이터 만 포함되어 있습니다. 지구상의 모든 장소에 무료 데이터 소스가 없으며 zip 파일에 포함하기에는 너무 방대합니다.


데이터베이스 


먼저, 기초를 마련해야 합니다 – 국가, 주 및 도시에 대한 모든 데이터를 보유 할 데이터베이스 테이블을 작성하십시오.


국가 


CREATE TABLE `countries` ( `country_code` varchar(2) NOT NULL, `country_name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `countries` ADD PRIMARY KEY (`country_code`), ADD KEY `country_name` (`country_name`); 


FieldDescription
country_codeThe ISO country code, primary key.
country_nameThe country name.

STATES 


CREATE TABLE `states` ( `country_code` varchar(2) NOT NULL, `state_code` varchar(32) NOT NULL, `state_name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `states` ADD PRIMARY KEY (`country_code`,`state_code`), ADD KEY `state_name` (`state_name`); 


FieldDescription
country_codeThe ISO country code. Partial primary key.
state_codeThe state code or postal code. Partial primary key.
state_nameThe state name.

CITIES 


CREATE TABLE `cities` ( `country_code` varchar(2) NOT NULL, `state_code` varchar(32) NOT NULL, `city_name` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE `cities` ADD PRIMARY KEY (`country_code`,`state_code`,`city_name`); 


FieldDescription
country_nameThe ISO country code. Partial primary key.
state_codeThe state code or postal code. Partial primary key.
city_nameCity name. Partial primary key.

라이브러리 파일 


계속해서 다음과 같은 토대를 마련합니다. – 데이터베이스와 함께 작동하는 데 필요한 PHP 라이브러리 파일을 만듭니다.


구성 파일 


<?php // 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', ''); ?> 


구성 파일은 설명이 필요합니다 ... 데이터베이스 설정을 원하는 대로 변경하십시오.


지오 라이브러리 


<?php class Geo { /* [DATABASE HELPER FUNCTIONS] */ protected $pdo = null; protected $stmt = null; public $error = ""; 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 ] ); return true; } // ERROR - DO SOMETHING HERE // THROW ERROR MESSAGE OR SOMETHING 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 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 ; } function fetchCol ($sql, $cond=null) { // fetchCol() : yet another version of fetch that returns a flat array // I.E. Good for one column SELECT `col` FROM `table` $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($cond); $result = $this->stmt->fetchAll(PDO::FETCH_COLUMN, 0); return count($result)==0 ? false : $result; } /* [GEO FUNCTIONS] */ function getCountries () { // getCountries() : get all countries $sql = "SELECT * FROM `countries` ORDER BY `country_name`"; return $this->fetchAll($sql, null, "country_code", "country_name"); } function getStates ($country) { // getStates() : get states of given country // PARAM $country : country code $sql = "SELECT * FROM `states` WHERE `country_code`=? ORDER BY `state_name`"; return $this->fetchAll($sql, [$country], "state_code", "state_name"); } function getCities ($country, $state) { // getCities() : get cities of given country and state // PARAM $country : country code // $state : state code $sql = "SELECT `city_name` FROM `cities` WHERE `country_code`=? AND `state_code`=? ORDER BY `city_name`"; return $this->fetchCol($sql, [$country, $state]); } } ?> 


이 도서관은 하나의 거대한 도서관이지만 침착하고 면밀히 살펴보십시오. – 2 개의 부품 만 있습니다.

  • 상위 절반은 다양한 SQL 요가를 수행하는 데 사용할 PDO 데이터베이스 함수일 뿐입니다.
  • 아래쪽 절반에는 데이터베이스에서 국가, 주 및 도시를 가져 오는 3 개의 함수 만 있습니다.
Database Helper Functions
FunctionDescription
__constructThe constructor, automatically connects to the database when the object is created.
__destructThe destructor, automatically closes the database connection when the object is destroyed.
fetchAllRuns a select SQL query. Returns a numeric array of the results – Good for multiple row queries.
fetchColRuns a specific select SQL query on a single column only. Returns a numeric array of the results.
Geo Functions
FunctionDescription
getCountriesGet all the countries.
getStatesGet all the states for the given country.
getCitiesGet all the cities for the given country and state.

AJAX HANDLER 


<?php // (1) INIT require __DIR__ . DIRECTORY_SEPARATOR . "lib" . DIRECTORY_SEPARATOR . "2a-config.php"; require PATH_LIB . "2b-lib-geo.php"; $geoLib = new Geo(); // HANDLE AJAX REQUESTS switch ($_POST['req']) { // (2) INVALID REQUEST default: echo json_encode([ "status" => 0, "message" => "Invalid request" ]); break; // (3) GET COUNTRIES case "country": $countries = $geoLib->getCountries(); echo json_encode([ "status" => $countries==false ? 0 : 1, "message" => $countries ]); break; // (4) GET STATES case "state": $states = $geoLib->getStates($_POST['country']); echo json_encode([ "status" => $states==false ? 0 : 1, "message" => $states ]); break; // (5) GET CITIES case "city": $cities = $geoLib->getCities($_POST['country'], $_POST['state']); echo json_encode([ "status" => $cities==false ? 0 : 1, "message" => $cities ]); break; } ?> 


물론 라이브러리 파일은 자체적으로 마법을 수행하지 않습니다. 따라서 이것은 AJAX 호출에 대한 데이터를 제거하는 실제 스크립트입니다. 작동 방식은 매우 간단합니다.이 핸들러에 $ _POST [ 'request']를 게시하여 원하는 것을 지정하고 필요한 매개 변수를 지정합니다.


RequestDescription
countryGet all the countries.
stateGet states for a given country.

Parameters: country

cityGet cities for a given country and state.

Parameters: countrystate

HTML 


필요한 모든 기초 작업이 완료되었으므로 퍼즐의 마지막 부분은 HTML 형식으로 간단히 사용하는 것입니다.


HTML 


<!DOCTYPE html> <html> <head> <title> AJAX Country State City Dropdown Demo </title> <script src="public/3b-demo.js"></script> <link href="public/3c-demo.css" rel="stylesheet"> </head> <body> <form id="sel-form" onsubmit="return false;"> <label for="sel-country">Country</label> <select id="sel-country"></select> <label for="sel-state">State</label> <select id="sel-state"></select> <label for="sel-city">City</label> <select id="sel-city"></select> <input type="submit" value="Go"/> </form> </body> </html> 


ajax-country-state-city.jpg 


네, 여기에는 특별한 것이 없습니다. 국가, 주 및 도시 선택자가 있는 일반적인 Joe HTML 양식 일 뿐입니다.


자바 스크립트 


var demo = { init : function () { // demo.init() : initialize form document.getElementById("sel-country").addEventListener("change", function(){ demo.up("state") }); document.getElementById("sel-state").addEventListener("change", function(){ demo.up("city") }); demo.up('country'); }, toggle : function (disabled) { // demo.toggle() : enable/disable form // PARAM disabled : true or false var all = document.querySelectorAll("#sel-form select, #sel-form input[type=submit]"); for (var el of all) { el.disabled = disabled; } }, up : function (target) { // demo.up() : update country, state, city via AJAX // PARAM target : target select field to load // (1) DISABLE FORM demo.toggle(true); // (2) APPEND FORM DATA var data = new FormData(); data.append('req', target); if (target=="state" || target=="city") { data.append('country', document.getElementById("sel-country").value); } if (target=="city") { data.append('state', document.getElementById("sel-state").value); } // (3) INIT AJAX var xhr = new XMLHttpRequest(); xhr.open('POST', "2c-ajax-geo.php", true); // (4) UPDATE SELECTOR ON AJAX LOAD xhr.onload = function(){ // Append options var res = JSON.parse(this.response), selector = document.getElementById("sel-" + target); selector.innerHTML = ""; if (res.status) { for (var key in res.message) { var opt = document.createElement("option"); opt.value = key; opt.innerHTML = res.message[key]; selector.appendChild(opt); } } else { var opt = document.createElement("option"); opt.innerHTML = "NA"; selector.appendChild(opt); } // Load next if (target=="country") { demo.up("state"); } if (target=="state") { demo.up("city"); } // Enable form when done loading everything if (target=="city") { demo.toggle(false); } }; // SEND xhr.send(data); } }; window.addEventListener("load", demo.init); 


이것은 혼란스러운 것들 중 하나이지만, 간단하게 작동하는 방법입니다 (정확히 무슨 일이 일어나고 있는지 알고 싶다면 코드를 한 줄씩 살펴보십시오).


functionDescription
demo.initFires on window load.
  • Attaches onchange events to the country and state selectors, so that they will cascade load the state/city when changed.
  • Initialize load the country, state, and city.
demo.toggleHelper function. Used to enable/disable the selectors so that users don’t mess with them while AJAX is still loading.
demo.upThe main function that will do the loading. Pretty much a straightforward one that will cascade load the country, state, and city via AJAX.

CSS 


#sel-form { background: #f2f2f2; border: 1px solid #aaa; padding: 10px; max-width: 300px; } #sel-form, #sel-form input, #sel-form select { font-family: arial; font-size: 1em; } #sel-form label, #sel-form select, #sel-form input[type=submit] { box-sizing: padding-box; width: 100%; } #sel-form select { padding: 5px; margin: 10px 0; } #sel-form input[type=submit] { background: #3568ba; border: 0; padding: 10px; color: #fff; cursor: pointer; } 


마지막으로 CSS에는 특별한 것이 없습니다. 물건을 더 멋지게 보이게 하는 옵션 화장품.


유용한 비트 


이것이 이 프로젝트의 전부이며, 여기에 도움이 될만한 추가 정보에 대한 작은 섹션이 있습니다.


참조 및 신용 



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

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