개발 꿀팁/PHP

자체 PHP MVC 프레임워크 개발 (1)

Jammie 2022. 7. 6. 12:36
반응형

이 튜토리얼은 John Squibb의 Builda PHP MVC Framework in an Hour에서 번역되었지만, 변경된 주소: http://johnsquibb.com/tutorials

mvc 모델로 php를 개발하는 기본 개념을 익힐 수 있는 튜토리얼이다.이 튜토리얼은 세 부분으로 나뉘어져 있는데,지금 이 부분은 첫번째 부분이다.

현재 시중에 많은 인기 있는 프레임워크가 있습니다. 하지만 우리가 직접 mvc 프레임워크를 개발할 수 있습니다. mvc 모델을 채택하면 우리가 응용 프로그램을 개발하는 시간을 크게 줄일 수 있고, 또한 프로젝트 소스 코드를 더 잘 구성할 수 있습니다. 그리고 그 중 일부 모듈은 다른 프로젝트에서 사용할 수 있습니다.간단한 mvc 프레임을 가르쳐야겠다.이 항목은 간단하고 경량이기 때문에 베스트 프랙티스가 아닐 수도 있고 안전성도 없을 수도 있고,모두가 실제 응용에서 보완할 필요가 있다.

사용된 기술: php, 객체 지향 개발 방법.

시작

먼저 웹 사이트 루트 아래에 세 개의 폴더를 만듭니다

모델즈
views
controllers
루트 디렉터리에 새 파일을 만듭니다:

index.php
이제 프로젝트 구조는 이렇게 해야 되는데

§ 사이트 루트

§ index.php

§ 모델즈/

§ views/

§ controllers/


index.php가 전체 web 앱의 진입점, 모든 것사용자의 요구는 모두 그것을 거친다.우리는 코드를 좀 써서 이용자의 요구를 분산시킬 것이다.해당 제어기에 가서, 이 제어기들을 제어한다.장치가 cont에 저장됨rollers 폴더에 있습니다.그 후, 우리는 다음과 같은 방법으로 실현할 수 있다.현재 페이지 이동:

HTTP: // 사용자의 도메인.com/index.php?page1
HTTP: // 사용자의 도메인.com/index.php?page2
HTTP: // 사용자의 도메인.com/index.php?page3
전면 컨트롤러 설정
먼저 index.php에서 사이트 루트 및 사이트 도메인 이름을 정의하여 전체적으로 대응할 수 있도록 한다.중간 방문.

<?php
 
//응용 프로그램의 루트 디렉토리는 바로 index.php의 부모 디렉토리이다
define("SERVER_ROOT", dirname(__FILE__));
 
//도메인 이름.comm은 서버 도메인 이름입니다
define('SITE_ROOT' , 'http://도메인 이름.com');

사이트 루트를 정의하면 어떤 php 파일에서도 다른 디렉토리의 php 파일을 쉽게 참조할 수 있는데, index.php는 포털 파일이기 때문에 그 안에서 정의된 변수들에 대해 애플리케이션 전체에서 접근할 수 있다.

라우터 router.php 설정(사용자의 요청을 해당 컨트롤러로 전달)
controllers 디렉토리 아래에 새 파일을 만듭니다. 이름은 "router.php"입니다. 이 파일은 모든 페이지 요청을 처리하는 데 사용됩니다.인터넷에 접속하는 라우터를 상상해 보세요.모든 컴퓨터. router.php 파일은 index로 전달됩니다.php의 페이지 요청은 서로 다른 컨트롤러(controllers)에 전달된다.

루트.php의 코드:

<?php
 
//모든 요청 가져오기
$request = $_SERVER['QUERY_STRING'];

이 코드는 응용 프로그램에 들어오는 요청 매개 변수를 가져옵니다.QUERY_STRING은?"뒤에 있는 모든 문자열.
http: // 도메인.com/index.php?page1
위의 주소에서 page1&action=login을 얻을 수 있으며 page1과 뒤의 참조를 위해숫자를 나누면, 우리는 route.php에 다음 코드를 계속 넣어야 한다.

//$request 변수를 해석하여 사용자가 요청한 페이지(page1)와 기타 GET 변수(&구분된 변수)를 구합니다http://도메인 이름.com/index.php?page1&article=buildawebsite,해석하면array("page1", "article=buildawebsite")
$parsed = explode('&' , $request);
 
//위와 같이 사용자가 요청한 페이지page1,$parsed 첫 번째 변수,shift之后,배열:array("article=buildawebsite")
$page = array_shift($parsed);
 
//나머지는 GET 변수로, 그것들을 해석해 낸다
$getVars = array();
foreach ($parsed as $argument)
{
    //왼쪽은 변수, 오른쪽은 값 '=' 으로 문자열을 구분합니다
    list($variable , $value) = split('=' , $argument);
    $getVars[$variable] = $value;
}
 
//이것은 테스트 문장이므로, 잠시 후에 삭제될 것입니다
print "The page your requested is '$page'";
print '<br/>';
$vars = print_r($getVars, TRUE);
print "The following GET vars were passed to the page:<pre>".$vars."</pre>";

지금 우리는 index.php에 route.php를 도입해야 합니다

<?php
/**
 * 문서 경로 정의
 */
define("SERVER_ROOT", dirname(__FILE__));
define('SITE_ROOT' , 'http://도메인 이름.com');
/** 
 * 引入router.php 
 */
 require_once(SERVER_ROOT . '/controllers/' . 'router.php');
?>

잘 되면 브라우저를 열고 다음을 입력할 수 있습니다.

HTTP: // 도메인 이름.com/index.php?news&article=howtobuildaframework
아래와 같이 출력을 보실 수 있습니다

The page you requested is 'news'
	The following GET vars were passed to the page:
 
	Array
	(
		[article] => howtobuildaframework
	)

위의 출력이 없으면 서버가 올바르게 구성되어 있는지 확인하고 코드에 오류가 없는지 확인하십시오.
이제 우리 사이트에 페이지를 추가해서 router.php를 만들자.위의 정보를 직접 출력하는 것이 아니라 하나의 페이지를 생성한다.

컨트롤러 만들기 (controller)
controllers 폴더에 "news.php"라는 새 파일을 만듭니다.뜻은 다음과 같다

<?php
/**
 * 이 문서는 문장의 조회를 처리하고, 또한 문장을 제공한다
 */
class News_Controller
{
    /**
     *$template 변수는 이 컨트롤러와 연결된 "view(보기)"의 파일 이름을 저장합니다. .php 접미사 제외
     */
    public $template = 'news';
 
    /**
     * 이 메서드는 route.php 기본 호출입니다
     * 
     * @param array $getVars index.php로 들어오는 GET 변수 배열
     */
    public function main(array $getVars)
    {
        //테스트 코드, 나중에 삭제하겠습니다
        print "We are in news!";
        print '<br/>';
        $vars = print_r($getVars, TRUE);
        print 
        (
            "The following GET vars were passed to this controller:" .
            "<pre>".$vars."</pre>"
        );
    }
}

우리가 route.php의 테스트 코드를 복사하여 수정한 것에 주의하세요.우리는 그것을 main 함수에 넣었습니다.이제 route.php의 코드를 수정합시다.

<?php
/**
 * 이 파일은 모든 들어오는 인자를 해당 컨트롤러에 할당합니다
 */
 
//요청 매개 변수 가져오기
$request = $_SERVER['QUERY_STRING'];
 
//페이지와 다른 해석을 요청하고 있다. 변수를 GET
$parsed = explode('&' , $request);
 
//페이지는 첫 번째 요소입니다
$page = array_shift($parsed);
 
//나머지는 GET 변수로, 그것들을 해석해 낸다
$getVars = array();
foreach ($parsed as $argument)
{
    //split GET vars along '=' symbol to separate variable, values
    list($variable , $value) = split('=' , $argument);
    $getVars[$variable] = $value;
}
 
//컨트롤러 파일 경로 구성
$target = SERVER_ROOT . '/controllers/' . $page . '.php';
 
//대상 파일 가져오기
if (file_exists($target))
{
    include_once($target);
 
    //이름 지정 규격(예: $page="news)에 맞게 page 변수 수정",우리 약속은 이니셜 대문자로 하고 컨트롤러는 뒤에 붙이고“_Controller”,즉News_Controller)
    $class = ucfirst($page) . '_Controller';
 
    //해당하는 클래스 초기화
    if (class_exists($class))
    {
        $controller = new $class;
    }
    else
    {
        //클래스의 이름이 맞습니까?
        die('class does not exist!');
    }
}
else
{
    //controllers에서 이 파일을 찾을 수 없습니다
    die('page does not exist!');
}
 
//컨트롤러가 초기화되면 기본 함수 main(;)을 호출합니다
//get 변수 전달하기
$controller->main($getVars);?>

http://.com/index.php에 다시 접속하시겠습니까?News&article=howtobuildaframework, News_Controller에서 출력된 정보를 볼 수 있습니다.참고 현재 die()로 오류를 처리하고 있습니다. 다른 더 나은 오류 처리로 이를 제한할 수 있습니다. 그러나 die()로 충분합니다. http://당신의 도메인.com/index.php와 같은 다른 페이지에 접속해 보십시오.books, 당신은 "page does not exist!"를 보게 될 것이다.오류. 모델( 모델) 완성 News_Controller를 만듭니다.만약 우리가 독자들이 읽을 수 있는 뉴스 클립을 가지고 있다고 가정한다면, News_Controller라는 컨트롤러는 데이터베이스나 파일에 저장된 뉴스 클립을 캡처하기 위해 모델을 호출할 필요가 있습니다.models 폴더에 파일 'news.php'를 새로 만듭니다. 코드는 다음과 같습니다.

<?php
/**
 * 뉴스 모델은 뉴스 제어기를 위해 복잡한 배경 조작을 한다
 */
class News_Model
{
    public function __construct()
    {
        print 'I am the news model';
    }
}

이제 뉴스 컨트롤러에 약간의 변경이 필요합니다. controllers에서 news.php를 열고 news_Controller 클래스의 main 함수의 코드를 다음과 같이 변경해야 합니다. 그러면 우리는 "News_Model"을 초기화할 때 화면에 인쇄된 메시지를 볼 수 있습니다.

public function main(array $getVars)
{
    $newsModel = new News_Model;
}

지금 페이지를 새로 고치면 다음과 같이 표시됩니다.

Fatal error: Class 'News_Model' not found in /var/www/mvc/controllers/news.php on line xx

잠깐만, 이건 우리가 원하는 결과가 아니야!존재하지 않는 클래스를 로드하려고 합니다./models/news.php 파일을 도입하지 않았기 때문이다.이 문제를 해결하기 위해 router.php를 다시 보고 그 위에 코드를 추가하세요.

//클래스를 초기화할 때 자동으로 관련 파일 가져오기
function __autoload($className)
{
    //파일 이름 확인, 파일 저장 경로 가져오기,예News_Model보관함을 나타냅니다models폴더 안的news.php(여기 작가님의 이름 약속입니다))
    list($filename , $suffix) = split('_' , $className);
 
    //구성 파일 경로
    $file = SERVER_ROOT . '/models/' . strtolower($filename) . '.php';
 
    //파일 가져오기
    if (file_exists($file))
    {
        //파일 가져오기
        include_once($file);        
    }
    else
    {
        //파일이 존재하지 않습니다
        die("File '$filename' containing class '$className' not found.");    
    }
}

파일이 존재하지 않는 이 함수는 PHP에 내장된 autoload 함수를 재로드한다.존재하지 않는 클래스를 초기화하려고 할 때 php가 수행하는 동작을 차단하는 '마술적 방법'이다.__autoload 함수를 사용하면 php에게 이러한 파일이 들어 있는 위치를 찾을 수 있도록 알려준다.만약 당신이 이 기사의 클래스 이름과 파일 이름 규칙을 따랐다고 가정한다면, 클래스를 초기화할 때마다, 이러한 클래스를 포함하는 파일을 수동으로 도입할 필요가 없습니다!
route.php를 저장하고 브라우저를 새로 고치면 다음과 같습니다.

I am the news model

뉴스 모델 클래스에서 몇 가지 함수를 정의해서 문장을 제공합시다.이제 우리는 단지 하나의 배열만을 정의하고 몇 개의 문장을 저장한 다음 컨트롤러가 제목에 따라 하나의 문장을 얻을 수 있는 함수를 제공합니다.models/ news.php 수정:

<?php
/**
 * 뉴스 모델은 뉴스 제어기를 위해 복잡한 배경 조작을 한다
 *
 */
class News_Model
{
    /**
     * 문장 배열. key는 문장 제목이며, 값은 상응하는 것이다
     * 문장。
     */
    private $articles = array
    (
        //문장 1
        'new' => array
        (
            'title' => 'New Website' ,
            'content' => 'Welcome to the site! We are glad to have you here.'
        )
        ,
        //2
        'mvc' => array
        (
            'title' => 'PHP MVC Frameworks are Awesome!' ,
            'content' => 'It really is very easy. Take it from us!'
        )
        ,
        //3
        'test' => array
        (
            'title' => 'Testing' ,
            'content' => 'This is just a measly test article.'
        )
    );
 
    public function __construct()
    {
    }
 
    /**
     * 제목에 따라 문장 가져오기
     * 
     * @param string $articleName
     * 
     * @return array $article
     */
    public function get_article($articleName)
    {
        //배열에서 문장 가져오기
        $article = $this->articles[$articleName];
    
        return $article;
    }
 
}?>

controllers/ news.php에서 main 함수를 수정합니다

public function main(array $getVars)
{
    $newsModel = new News_Model;
    
    //한 편의 문장을 얻다
    $article = $newsModel->get_article('test');
    
    print_r($article);
}

현재 우리는 사용자의 입력을 걸러내는 문제를 고려하지 않고 있습니다. 왜냐하면 우리는 지금 PHP MVC의 기본 내용을 최대한 빨리 파악하려고 하기 때문에 우리는 지금 그것에 너무 관심을 가질 필요가 없습니다.
다음 URL에 접속할 경우:
§ http://yourdomain.com/mvc/index.php?News&article=test

다음과 같은 출력을 볼 수 있습니다.

Array ( [title] => Testing [content] => This is just a measly test article. )

보기 만들기( VIEW)
지금 저희가 컨트롤러와 컨트롤러가 있고모형입니다. 보기 한 개만 차이가 없습니다.뷰는 표현 계층입니다. 이것은 당신의 앱에서 사용자와 가장 자주 접촉하는 부분입니다.앞서 말씀드린 바와 같이 뷰는 업무 로직과 분리된 사용자 인터페이스를 제공하는 것이며, 이를 위한 여러 가지 방법이 있습니다.템플릿 엔진 Smarty나 다른 유사한 것을 사용할 수 있다.너는 자신의 템플릿 엔진을 하나 쓸 수 있지만,그것은 확실히 상당히 어려운 임무이다.마지막으로 네이티브 php 뷰를 사용할 수 있습니다.

현재로선 php뷰그림은 충분합니다. 이것은 php와 html 코드를 혼합한 것과 같습니다. 하지만 한가지 다른 점은 우리의 업무 로직이 뷰와 분리되어 있다는 것입니다.아래 코드를 보세요.

<html>
    <head></head>
    <body>
        <h1>Welcome to Our Website!</h1>
        <hr/>
        <h2>News</h2>
        <h4><?=$data['title'];?></h4>
        <p><?=$data['content'];?></p>
    </body>
</html>

내장된 php 태그는 PHP 퀵 오퍼레이터를 활용한다는 점에 유의하시기 바랍니다.이렇게 하면 저희 콘텐츠를 HTML로 바로 출력할 수 있습니다.뷰스 폴더에 파일 '뉴스.php'를 새로 만들어 이 코드를 복사했다.지금 우리는 뷰파일을 가지고 있지만,우리는 뷰와 상호 작용하는 방법이 필요하다.models 폴더에 파일 "view.php" 을 새로 만들어 다음 코드를 추가합니다.

<?php
/**
 * 우리의 MVC 프레임워크에서 뷰의 기능을 다룬다
 */
class View_Model
{
    /**
     * 보기 템플릿에 할당된 변수 저장
     */
    private $data = array();
 
    /**
     * 보기 렌더링 상태 저장
     */
    private $render = FALSE;
 
    /**
     *보기 템플릿 불러오기
     */
    public function __construct($template)
    {
        //전체 파일 경로 구성
        $file = SERVER_ROOT . '/views/' . strtolower($template) . '.php';
    
        if (file_exists($file))
        {
            /**
             * 모델 오브젝트가 파괴되었을 때 보기 렌더링하기
             * 지금 보기를 렌더링하면 보기 템플릿에 변수를 지정할 수 없습니다
             * 그림% 1개의 캡션을 편집했습니다
             */
            $this->render = $file;
        }        
    }
 
    /**
     * 컨트롤러로부터 주어진 변수를 받아들여 data 배열에 저장
     * 
     * @param $variable
     * @param $value
     */
    public function assign($variable , $value)
    {
        $this->data[$variable] = $value;
    }
 
    public function __destruct()
    {
        //보기 템플릿에서 사용하기 쉽도록 클래스의 data 배열을 이 함수의 로컬 변수로 바꿉니다
        $data = $this->data;
    
        //렌더링 보기
        include($this->render);
    }
}

이제 마지막으로 해야 할 일은 News_Controller에서 보기를 로드하는 것입니다.controllers/ news.php 수정:

<?php
/*
 *이 문서는 문장의 조회를 처리하고, 신문 기사를 생성한다* 
 */
 class News_Controller{ 
    /** 
     * $template이 컨트롤러와 연결된 변수를 저장합니다."view(보기)"파일 이름(.php 접미사 제외)
     * 
     */
     public $template = 'news'; 
    /**
     * 이 메서드는 route.php 기본 호출입니다
     * 
     * @param array $getVars index.php로 들어오는 GET 변수 배열 
     */ 
     public function main(array $getVars) {
         $newsModel = new News_Model; 
         //문장 하나를 얻다
         $article = $newsModel->get_article($getVars['article']); 
         //보기를 만들고 이 컨트롤러의 template 변수를 가져옵니다 
         $view = new View_Model($this->template); 
         //보기 템플릿에 문장 데이터 할당하기
         $view->assign('title' , $article['title']); 
         $view->assign('content' , $article['content']); 
     }
}
?>

 

반응형