쉬운 개발을 위한 플러그인
PHP 플러그인 모듈 시스템을 만드는 방법에 대한 튜토리얼에 오신 것을 환영합니다. 그래서 당신은 프로젝트가 엄청나게 커졌고 일이 좀 더 조직화 될 수 있는지 궁금해 합니다… 게다가 개발이 좀 더 쉬워 질 것입니다. 플러그인 모듈 시스템이 정답입니다.
그러나 어떻게 핵심 시스템을 구축합니까? 모듈을 어떻게 구축합니까? 알아 보려면 계속 읽으십시오!
ⓘ이 튜토리얼의 시작 부분에 모든 소스 코드가 포함 된 zip 파일이 포함되어 있으므로 모든 것을 복사하여 붙여 넣을 필요가 없습니다.
소스 코드 다운로드
먼저 약속 한대로 소스 코드에 대한 다운로드 링크가 있습니다.
소스 코드 다운로드
소스 코드를 다운로드하려면 여기를 클릭하십시오. MIT 라이센스에 따라 릴리스되었으므로 그 위에 빌드하거나 자신의 프로젝트에서 자유롭게 사용하십시오.
폴더
다음은 zip 파일에서 폴더를 구성하는 방법에 대한 간략한 소개입니다.
빠른 시작
핵심 시스템
이제 전체 플랫폼의 기초가 될 핵심 시스템 개발부터 시작하겠습니다.
핵심 폴더 및 HTACCESS 파일
먼저 모든 핵심 라이브러리 파일을 핵심 폴더에 포함 시켜 보호해야 합니다.
Deny from all
이렇게 하면 사용자가 코어 파일에 직접 액세스하고 엉망이 되는 것을 방지 할 수 있습니다. 예 : http://site.com/core/lib-Core.php에 직접 액세스하면 오류가 발생합니다.
핵심 라이브러리
Class Core { public $error = ""; // Holder for error messages /* [DATABASE FUNCTIONS] */ 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->base->error = $ex; return false; } $this->stmt = null; return true; } function start () { // start() : auto-commit off $this->pdo->beginTransaction(); } function end ($commit=1) { // end() : commit or roll back? if ($commit) { $this->pdo->commit(); } else { $this->pdo->rollBack(); } } 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 fetch ($sql, $cond=null, $sort=null) { // fetch() : perform select query (single row expected) // returns an array of column => value // PARAM $sql : SQL query // $cond : array of conditions // $sort : custom sort function $result = []; try { $this->stmt = $this->pdo->prepare($sql); $this->stmt->execute($cond); if (is_callable($sort)) { while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) { $result = $sort($row); } } else { while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) { $result = $row; } } } 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; } /* [LOADING THE PLUGINS] */ function extend ($module) { // extend () : extend a new module // Cannot extend the core... if ($module=="Core") { $this->error = "'$module' is already defined!"; return false; } // Given module name or property already exist if (isset($this->$module)) { if (is_object($this->$module)) { return true; } else { $this->error = "'$module' is already defined!"; return false; } } // Extend the base object $file = PATH_CORE . "lib-" . $module . ".php"; if (file_exists($file)) { // Include library file and create child module require_once $file; $this->$module = new $module(); // The evil base object pointer... // This will allow sibling objects to communication with each other // Otherwise impossible with traditional OOP $this->$module->core =& $this; $this->$module->error =& $this->error; // Done! return true; } else { $this->error = "'$file' not found!"; return false; } } }
핵심 라이브러리는 매우 복잡해 보이지만 실제로는 두 섹션으로 나뉩니다.
Function | Description |
__construct | The constructor. Will connect to the database when the object is being created. |
__destruct | The destructor. Will close the database connection when the object is being destroyed. |
exec | Run an insert, replace, update, or delete query. |
start | Auto-commit off, used in conjunction with end, for a series of queries. |
end | Commit or rollback? Used in conjunction with start. |
fetchAll | Run a select query, multiple rows of results expected. |
fetch | Run a select query, a single row of result expected. |
fetchCol | Runs a select query on a single field only. |
extend | The very evil function that will extend modules onto the core object. More on this later. |
핵심 스타터
// MUTE NOTICES error_reporting(E_ALL & ~E_NOTICE); // 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', ''); // AUTO FILE PATHS define('PATH_CORE', __DIR__ . DIRECTORY_SEPARATOR); // START SESSION session_start(); // INIT SYSTEM CORE require PATH_CORE . "lib-Core.php"; $_CORE = new Core();
핵심 라이브러리를 만들었으므로 데이터베이스 설정을 포함하고 핵심 개체를 작성하는 스크립트 일뿐입니다. 이것을 "파이어 스타터"라고 부를 수 있을 것입니다. 모든 페이지에 포함 시킬 것입니다.
코어 시스템 작동 방식
핵심 시스템의 핵심은 실제로 클래스 핵심이며 함수 확장입니다.
빌딩 모듈
작동하는 핵심 시스템을 갖추었으므로 이제 그 위에 모듈을 빌드하는 방법을 보여줄 차례입니다. 이 섹션에서 간단한 사용자 플러그인을 예로 들어 보겠습니다.
1 단계. 사용자 테이블
먼저 간단한 더미 사용자 테이블을 만들어 봅시다.
CREATE TABLE `users` ( `user_id` int(11) NOT NULL, `user_name` varchar(255) NOT NULL, `user_email` varchar(255) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `users` (`user_id`, `user_name`, `user_email`) VALUES (1, 'John Doe', 'john@doe.com'), (2, 'Jane Doe', 'jane@doe.com'), (3, 'Josh Doe', 'josh@doe.com'), (4, 'Joy Doe', 'joy@doe.com'), (5, 'Jasmine Doe', 'jasmine@doe'); ALTER TABLE `users` ADD PRIMARY KEY (`user_id`), ADD UNIQUE KEY `user_email` (`user_email`), ADD KEY `user_name` (`user_name`); ALTER TABLE `users` MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
Field | Description |
user_id | The user ID. Primary key, auto-increment. |
user_name | The user’s name. |
user_email | The user’s email. |
2 단계. 사용자 라이브러리 파일
extend () 함수는 core / lib- $ module.php를 찾고 새 객체 $ this-> $ module = new $ module ()을 생성한다는 것을 기억하십시오. 우리는 각각의 라이브러리 파일, 클래스를 만든 다음 그에 따라 함수를 추가해야 합니다.
class Users { function getAll () { // getAll() : get all users return $this->core->fetchAll( "SELECT * FROM `users`", null, "user_id" ); } function get ($id) { // get() : get user by ID or email $sql = is_numeric($id) ? "SELECT * FROM `users` WHERE `user_id`=?" : "SELECT * FROM `users` WHERE `user_email`=?" ; return $this->core->fetch($sql, [$id]); } function add ($name, $email) { // add() : create a new user // Check if given email is already registered $check = $this->get($email); if (is_array($check)) { $this->error = "'$email' is already registered!"; return false; } // Proceed add return $this->core->exec( "INSERT INTO `users` (`user_name`, `user_email`) VALUES (?, ?)", [$name, $email] ); } function edit ($name, $email, $id) { // edit() : update an existing user return $this->core->exec( "UPDATE `users` SET `user_name`=?, `user_email`=? WHERE `user_id`=?", [$name, $email, $id] ); } function del ($id) { // del() : delete user return $this->core->exec( "DELETE FROM `users` WHERE `user_id`=?", [$id] ); } }
일부 초보자에게는 복잡해 보일 수 있지만 주의 깊게 살펴보십시오. 이전부터 포인터 $ this-> $ module-> base = & $ this? 말 그대로 여기에 SQL을 작성하고 핵심 데이터베이스 기능을 활용하여 나머지 작업을 수행합니다.
3 단계. 완료 – 사용하십시오!
마지막으로 필요한 곳에서만 사용해야 합니다. 예를 들어, 사용자를 나열하는 페이지에서 :
// The fire starter require __DIR__ . DIRECTORY_SEPARATOR . "core" . DIRECTORY_SEPARATOR . "core.php"; // We only have to extend the relative module + use the functions $_CORE->extend("Users") or die($_CORE->error); $users = $_CORE->Users->getAll(); // Now for the HTML <html> <body> foreach ($users as $id=>$u) { printf("<div>%s - %s</div>", $u['user_name'], $u['user_email']); } </body> </html>
유용한 비트
이것으로 코드가 완성되었으며 여기에 유용한 몇 가지 추가 기능이 있습니다.
요약
그게 전부 플러그인 시스템입니다. 말 그대로 코어 폴더에 더 많은 라이브러리 파일을 만들고 함수를 추가하기 만하면 됩니다.
모델 뷰 컨트롤러 (MVC)
라이브러리와 HTML 파일을 개별적으로 유지하는 개념은 MVC라는 것을 기반으로 합니다. 이것은 사이버 세계에서 들을 수 있는 다소 일반적인 용어이므로 자세한 내용을 알고 싶으면 다른 가이드를 읽으십시오.
링크 및 참조
등록된 댓글이 없습니다.