개발 꿀팁/PHP

PHPMVC 프레임워크 개발(상)

Jammie 2022. 10. 19. 12:05
반응형

포털 파일 정의
정의 상수
인입 라이브러리 함수
핵심 모듈 도입

자동 로딩 완료
입구 파일 index.php

<?php

// door file

// define system const
define('LSPHP', __DIR__ . "/");
define('APP', __DIR__ . "/app");
define('CORE', __DIR__ . "/core");


//define debug
define('APP_DEBUG',true);

if (APP_DEBUG) {
    ini_set('display_errors', 'On');
} else {
    ini_set('display_errors','Off');
}


// include core func file
include CORE . '/common/function.php';
// test
// p("1234");


// include core class file
include CORE . "/lsphp.php";
// test
// \core\lsphp::run();


// 클래스 로딩 구현, 로딩 함수 등록
spl_autoload_register('\core\lsphp::load');

\core\lsphp::run();

자동으로 lspphp.php 불러오기route.php

<?php
    
namespace core;

class lsphp
{

    public static $classMap = [];

    public static function run()
    {
        $route = new \core\route();
    }

    // 자동 로딩 실현
    public static function load($class)
    {
        if (isset(self::$classMap[$class])) {
            return true;
        } else {
            $filepath=str_replace('\\','/',$class);
            $filepath=LSPHP.$filepath.'.php';
            if(is_file($filepath))
            {
                require $filepath;
                self::$classMap=$filepath;
            }else{
                return false;
            }
        }
    }
}

 

route.php

<?php
namespace core;

class route
{
    public function __construct()
    {
        echo 'route';
    }
}

라우팅 클래스
.htaccess
.htaccess 파일은 Apache 서버의 구성 파일로, 그녀는 관련 디렉터리에 있는 웹 사이트 구성을 담당하며, htaccess 파일을 통해 다음을 수행할 수 있습니다.

웹 페이지 301 리디렉션
사용자 정의 404 오류 페이지
파일 확장자 변경
특정 사용자나 디렉터리 허용/ 차단의 방문
금지 목록
기본 문서와 같은 기능 설정

<IfModule mod_rewrite.c>
    # Rerite 기능 켜기
    RewriteEngine On

    # 요청하신 것이 실제 존재하는 파일이나 디렉토리라면, 직접 방문하시기 바랍니다
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # 액세스한 파일이나 디렉터리가 실제 존재하지 않는 경우, index.php로 배포 요청
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

explode
explode — 한 문자열을 다른 문자열로 분할하기

explode ( string $delimiter , string $string [, int $limit ] ) : array

이 함수는 문자열로 구성된 배열을 반환합니다. 각 요소는 문자열 delimiter에 의해 경계점으로 분할된 string의 하위 문자열입니다.

python의 split 함수와 같은 기능

Trim
trim - 문자열의 맨 뒤에 있는 공백 문자(또는 다른 문자)를 제거합니다.

trim (string $str [, string $character_mask = "\t\n\r\0\x0B" ]) : string

이 함수는 문자열 str이 공백 문자를 제거한 결과를 반환합니다.두 번째 인자를 지정하지 않으면 trim() 이 문자를 제거합니다

" " (ASCII 32 (0x20), 일반 공백 문자
"\t" (ASCII 9 (0x09)), 탭
"\n" (ASCII 10 (0x0A)) 줄 바꿈 문자
"\r" (ASCII 13 (0x0D)) , 리턴 기호
"\0" (ASCII 0 (0x00)) , 빈 바이트 문자
"\x0B" (ASCII 11 (0x0B)) 수직형시계 기호

python의 strip 함수와 같은 기능

array_slice
array_slice- 배열에서 한 단락 꺼내기

array_slice (array $arr)ay, int $offset [, int $length = NULL [, bool $preserve_keys = false]]) : array

array_slice() offse를 기준으로 되돌리기t 및 length 매개 변수지정한 array 배열의 시퀀스

<?php
$input = array("a", "b", "c", "d", "e");

$output = array_slice($input, 2);      // returns "c", "d", and "e"
$output = array_slice($input, -2, 1);  // returns "d"
$output = array_slice($input, 0, 3);   // returns "a", "b", and "c"

실현하다
think PHP와 같은 효과를 얻기 위해 url의 인자를 따로 떼어냅니다.

index.php/모듈/컨트롤러/조작/파라미터/값
#index.php는 입구 파일로 사용하므로 백엔드에서 패스할 것url 값을 분할합니다

라우팅 매핑이 설정되지 않았기 때문에, 제 웹사이트 url은 다음과 같습니다

http://localhost/demo/develop/index.php

# $_SERVER['REQUEST_URI'] = "/demo/develop/index.php"

배열 첨자 0부터 시작

# route.php

<?php

namespace core\lib;

class route
{
    // 기본 컨트롤러 및 작업
    public $ctrl = "index";
    public $action = "index";
    public $param = [];

    public function __construct()
    {
        if (isset($_SERVER['REQUEST_URI'])) {
            $pathString = $_SERVER['REQUEST_URI'];
            $path_arr = explode('/', trim($pathString, '/'));
            // $path_arr='/demo/develop/index.php/index/index/param/222'
        }

        if (isset($path_arr[2]) && ($path_arr[2]) == "index.php") {
            $path_arr = array_slice($path_arr, 3, count($path_arr) - 2);
             p($path_arr);
            // $path_arr='index/index/param/222'
        }

        if (isset($path_arr[0])) {
            // 제어기를 잡다
            if (isset($path_arr[0])) {
                $this->ctrl = $path_arr[0];
            }
        }

        // 조작하다
        if (isset($path_arr[1])) ;
        {
            $this->action = $path_arr[1];
        }

        //배열을 2로 첨자하여 시작하므로 인자를 가져옵니다
        $i = 2;
        $count = count($path_arr);
        while ($i < $count) {
            if (isset($path_arr[$i + 1])) {
                $this->param[$path_arr[$i]] = $path_arr[$i + 1];
            }
            $i=$i+2;
        }

        p($this->ctrl);
        p($this->action);
        p($this->param);
    }
}

제어기
로드 컨트롤러
컨트롤러 파일 정의하기

# indexController.php<?php

namespace app\controller;

class IndexController
{
    public function index()
    {
        echo 'hello index';
    }
}

lspphp.php 파일에서 로딩 기능 정의

......    
	public static function run()
    {
        $route = new \core\lib\route();

        // 로드 컨트롤러
        $ctrl = $route->ctrl;
        $action = $route->action;

        $controllerFile = APP . "/controller/" . $ctrl . "Controller.php";
        $controllerClass="\\app\\controller\\".$ctrl."Controller";
        // 네임스페이스 \\ $ctrl(index)Controller

        if (is_file($controllerFile)) {
            require $controllerFile;
            $controller = new $controllerClass;
            $controller->$action();

        } else {
            throw new \Exception("controller not found!");
        }
    }
......

데이터베이스
새 데이터베이스, 테이블

연결 초기화

db.php

pdo 사용구현, 데이터베이스 설정 연결

<?php

namespace core\common;

class db extends \PDO
{
    public function __construct()
    {
        $dsn = 'mysql:host=localhost;dbname=lsphp';
        $username = 'root';
        $password = 'root';
        try {
            parent::__construct($dsn, $username, $password);
        } catch (\Exception $e) {
            echo $e->getMessage();
        }
    }
}

데이터 쿼리 함수

# indexController.php  
......
	public function query()
    {
        $db = new \core\common\db();
        $sql = "select * from ls_user";
        $data = $db->query($sql);
        p($data);
        p($data->fetchAll());
    }
......

index 컨트롤러 query 작동

보기
extract
(PHP 4, PHP) 5, PHP 7)

extract-종료배열에서 현재 기호 테이블로 변수 가져오기

extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int

이 함수는 변수를 배열에서 현재 기호 테이블로 가져오는 데 사용됩니다

모든 키 이름을 검사하여 합법적인 변수 이름으로 사용할 수 있는지 확인합니다.기호 테이블에서 기존 변수 이름과 충돌하는 것도 확인합니다.

키의 값을 변수로 맞춥니다. 키의 이름은 변수 이름입니다.값은 변수 값입니다

# render.php

<?php

namespace core;

class render
{
    public $param = [];

    // 전파 매개 변수 함수
    public function assign($name, $value)
    {
        $this->param[$name] = $value;
    }

    // 컨트롤이 그 뷰로 전달됩니다
    public function display($view)
    {
        $viewPath=APP."/view/".$view.".html";

        if(is_file($viewPath))
        {
            extract($this->param);
            include $viewPath;
        }else{
            echo "view is not found";
            exit();
        }
    }
}
# indexController.php
<?php

namespace app\controller;

class IndexController extends \core\render
    # render 상속 필요
{
    public function render()
    {
        $this->assign("title","ocean");
        $this->assign("content",'test');
        $this->display("index");
    }
}
# index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>
<body>

<h2>
    <?php echo $title ?>
</h2>
<p>
    <?php echo $content ?>
</p>
</body>
</html>

효과는 다음과 같다

기타류
설정 클래스
코드 프로필을 구현하기 위해, 코드를 기능별로 구분하여 설정파일을 따로 보관하여 수정도 용이함

두 개의 프로필이 예시로 사용됨

# db_config.php
<?php
return array (
    "dsn" => 'mysql:host=localhost;dbname=lsphp',
    "username" => 'root',
    "password" => 'root',
);
# route_config.php
<?php
return array(
    "1"=>"one",
    "2"=>"two",
    "3"=>"three"
);

\core\conf.php 설정 클래스 로드 안 함

# \core\conf.php
<?php
// 설정 config 정보를 불러오는 함수
namespace core;

class conf
{
    # 정보를 얻다
    public static function get($name, $file)
    {
        $fileName = CONFIG . "/$file" . ".php";
        if (is_file($fileName)) {
            $conf = include $fileName;
            if (isset($conf[$name])) {
                return $conf[$name];
            }else{
                throw new \Exception("not found config name!");
            }
        } else {
            throw new \Exception("not found file!");
        }
    }

    # 모든 정보 가져오기
    public static function all($file)
    {
        $fileName = CONFIG . "/$file" . ".php";
        if (is_file($fileName)) {
            $conf = include $fileName;
            return $conf;
        } else {
            throw new \Exception("not found file!");
        }
    }
}

CONFIG 상수를 사용하므로 미리 정의해야 함

# index.php
define("CONFIG",__DIR__."/config");

이렇게 하면 config 파일에 데이터베이스 프로필을 저장할 수 있습니다.

다음 호출 데이터

# \core\common\db.php
class db extends \PDO
{
    public function __construct()
    {
        $db_config=\core\conf::all('db_config');
        $dsn=$db_config['dsn'];
        $username=$db_config['username'];
        $password=$db_config['password'];
        .....
            
# 단일 호출       
    public function getroute(){
        $route= \core\conf::get("1",'route_config');
        p($route);

로그 클래스
작업 단계를 기록하다

LOG 상수 추가

# index.php
header("Content-type:text/html;charset=utf-8");
// 중국어로 돌아가기 때문에 깨진 코드가 있으면 header 헤드를 설정한다

define('LOG', __DIR__ . "/log");
# \core\log.php 로그 파일

<?php
namespace core;

class log
{
    public function log($message)
    {
        ini_set('data.timezone', 'Asia/Beijing');
        $log_dir = LOG . '/' . date('Ymd');
        if (!is_dir($log_dir)) {
            if (mkdir($log_dir)) {

            } else {
                throw new \Exception("log file create error");
            }
        }

        $log_file = $log_dir . '/' . date('Hi');
        //H는 24시간, i는 60분을 나타낸다
        if (!is_file($log_file)) {
            if(!file_put_contents($log_file,$message.PHP_EOL,FILE_APPEND)){
                // 파일 이름, 파일 내용.php 줄 바꾸기(\n), 쓰기 방법: 추가 쓰기
            }else{
                throw new \Exception("log content write error");
            }
        }
    }
}

호출하다

# indexController.php
	public function log()
    {
        $log = new \core\log();
        $log->log("this is a test log");
        echo 'ok';
    }

로그 디렉터리에 파일을 생성합니다

    $log_file = $log_dir . '/' . date('Hi');
    // H는 24시간, i는 60분을 나타낸다
    if (!is_file($log_file)) {
        if(!file_put_contents($log_file,$message.PHP_EOL,FILE_APPEND)){
            // 파일 이름, 파일 내용.php 줄 바꾸기(\n), 쓰기 방법: 추가 쓰기
        }else{
            throw new \Exception("log content write error");
        }
    }
}
호출하다

```php
# indexController.php
	public function log()
    {
        $log = new \core\log();
        $log->log("this is a test log");
        echo 'ok';
    }

 

반응형