설치

요구 사항

항목 버전 / 비고
PHP 8.3 이상
확장 모듈 pdo_mysql (또는 pdo_pgsql, pdo_sqlite, pdo_sqlsrv/pdo_dblib), openssl, json
웹 서버 Apache (mod_rewrite) 또는 nginx
데이터베이스 MySQL / MariaDB, PostgreSQL, SQLite, MS SQL Server

Flexagon은 두 개의 Composer 패키지로 배포됩니다.

패키지 용도
flexagon/framework 프레임워크 본체 (라이브러리)
flexagon/skeleton 애플리케이션 스켈레톤 (프로젝트 템플릿)

새 프로젝트

composer create-project flexagon/skeleton myapp
cd myapp
myapp/
├── application/          # 도메인 코드
├── public/               # ← document root
├── script/               # CLI 배치
├── flexagon.php
├── composer.json
└── vendor/
    └── flexagon/framework/   # 프레임워크 본체

프레임워크만 따로 올릴 수 있습니다.

composer update flexagon/framework

기존 프로젝트에 추가

composer require flexagon/framework
composer exec flexagon init      # 또는 php vendor/bin/flexagon init

init 이 public/, application/, script/, flexagon.php 등 프로젝트 구조 34개 파일을 만듭니다. 이미 있는 파일은 건드리지 않으므로 버전을 올린 뒤 새로 생긴 구조 파일만 받아 오는 용도로도 쓸 수 있습니다(덮어쓰려면 --force).

create   flexagon.php
create   application/_Global.php
...
keep     public/index.php        ← 이미 있으면 그대로

flexagon/framework만 설치하면 유틸리티 클래스(StringUtil·ValidUtil·CryptoUtil 등)와 BaseModel은 바로 쓸 수 있지만, DAO 계층은 애플리케이션이 _Global을 정의해야 동작합니다. 정의하지 않으면 BaseGlobal의 기본값으로 대체되므로 fatal 은 나지 않지만, 데이터소스가 비어 있어 DB 연결이 되지 않습니다. 실제 애플리케이션은 스켈레톤으로 시작하세요.

flexagon.php는 두 가지 레이아웃을 순서대로 탐색하므로, 어느 방식으로 설치하든 진입점 코드는 동일합니다.

순서 경로 상황
1 vendor/flexagon/framework/Bootstrap.php Composer 설치
2 application/_Flexagon.phar (파일) 단일 phar 로 패키징한 경우

둘 다 없으면 RuntimeException으로 중단하고 composer install 또는 ant build를 안내합니다. Composer files 항목이 먼저 등록되도록 vendor/autoload.php를 프레임워크보다 앞서 불러옵니다.

Bootstrap.php는 application/_Global.php를 가진 가장 가까운 상위 디렉터리를 찾아 PROJECT_ROOT로 삼습니다. 따라서 프레임워크가 vendor/ 안에 있든 phar 안에 있든 애플리케이션 경로 해석은 동일합니다.

오토로딩

애플리케이션 클래스는 composer.json 이 application/ 에 PSR-4 로 매핑합니다.

ExampleUser\UserDAO  →  application/ExampleUser/UserDAO.php

네임스페이스를 추가하면 같은 이름의 디렉터리를 만드는 것으로 끝이고, composer.json 을 고칠 필요가 없습니다.

프레임워크 쪽은 _Flexagon\ 네임스페이스와 전역 헬퍼(_echo·_t·___), 그리고 TemplateLoader 를 자동으로 올려 줍니다. 별도 설정은 없습니다.

데이터베이스 설정

application/_Config.php를 편집합니다.

<?php
use _Flexagon\Libs\Env;
use _Flexagon\Models\DataSourceModel;

_Global::$DATA_SOURCES['default'] = new DataSourceModel(
    Env::get('DB_HOST', 'localhost'),
    Env::int('DB_PORT', 3306),
    Env::get('DB_USER'),
    Env::required('DB_PASSWORD'),
    Env::get('DB_NAME')
);

값은 .env.php나 환경변수에서 옵니다. 다음 절을 보세요.

비밀 값 (.env.php)

비밀번호와 키는 application/ 밖에 둡니다. .env.example.php를 프로젝트 루트의 .env.php로 복사해 채우고, _Config.php에서는 Env로 읽습니다.

<?php
// .env.php — git 제외, public/ 아래 두지 않음
return [
    'DB_USER'     => 'app',
    'DB_PASSWORD' => 's3cr3t',
    'DB_NAME'     => 'service',
    'SESSION_ENCRYPTION_STRING' => '...',
];
메서드 반환
Env::get($key, $default = null) 값, 없으면 $default
Env::required($key) 값. 없거나 빈 값이면 예외
Env::int($key, $default) / Env::bool($key, $default) 형 변환된 값. 변환할 수 없으면 예외
Env::has($key) 설정되어 있는지

값은 실제 환경변수 → .env.php → 기본값 순서로 찾습니다. 운영에서는 같은 키를 PHP-FPM env[...], Docker, 플랫폼 설정으로 넣고 .env.php를 두지 않아도 됩니다. 파일이 PHP라서 opcache가 컴파일된 채로 캐시하고, 값은 타입을 유지합니다. Env를 처음 쓸 때 읽으므로 쓰지 않는 앱에는 비용이 없습니다. 다른 파일을 쓰려면 부팅 전에 ENV_FILE을 정의하거나 Env::load($path)를 호출하세요. 서버마다 .env.php를 프로젝트 밖(/etc/flexagon/ 등)에 두는 방법은 application/_Config/README.md에 있습니다.

putenv()나 $_ENV에는 넣지 않고, 오류 메시지에는 키 이름만 나오며 값은 나오지 않습니다. DataSourceModel을 var_dump()하면 비밀번호는 ***로 보입니다.

flexagon check는 .env.php가 public/ 아래에 있거나 git에서 추적되면 오류로 판정합니다. .env.example.php의 키가 설정되지 않았을 때, _Config.php에 비밀번호가 직접 적혀 있을 때, .env 파일이 있을 때(Flexagon은 읽지 않음), opcache.file_cache가 켜져 있을 때(컴파일된 비밀 값이 디스크에 저장됨)는 경고합니다.

AI 코딩 에이전트가 읽지 못하게 하기

비밀 값을 .env.php로 옮기면 application/ 아래 파일은 에이전트가 읽어도 안전합니다. 남은 파일 하나는 에이전트 쪽에서 막으세요. Claude Code용으로는 스켈레톤에 .claude/settings.json이 들어 있습니다(flexagon init도 없으면 만들어 줍니다).

{
  "permissions": {
    "deny": ["Read(./.env.php)", "Read(./**/.env.php)"]
  },
  "sandbox": {
    "filesystem": { "denyRead": ["./.env.php"] }
  }
}

permissions.deny는 Read 도구를, sandbox.filesystem.denyRead는 cat .env.php 같은 셸 명령까지 막습니다. 둘 다 설정하세요. 다른 에이전트는 각자의 제외 설정을 쓰면 됩니다. 코드를 실행할 수 있는 에이전트는 런타임에 값을 출력할 수 있으므로(php -r 'echo Env::get(...)'), 개발용 .env.php에는 운영이 아닌 개발용 자격증명만 넣으세요.

첫 페이지

<?php
// public/hello.php
_Global::$SITE_TITLE = '안녕하세요';

TemplateLoader::show('head');
echo '<h1>Hello, Flexagon</h1>';
TemplateLoader::show('tail');

http://127.0.0.1:9001/hello 로 접속하면 렌더링됩니다.

점검

배치와 런타임이 서로 맞는지 확인합니다.

php script/flexagon.php check     # 설치 형태와 무관
php vendor/bin/flexagon check     # Composer 설치라면 이쪽도 가능
ok       php 8.3.33
ok       opcache.save_comments
ok       project layout
ok       bootstrap
warn     data sources  default 이 템플릿 플레이스홀더 그대로
ok       display_errors  off

조용히 잘못되는 것들을 잡아 줍니다 — opcache.save_comments 가 꺼져 있으면 @encrypt·@db_auto_timestamp 가 오류 없이 무시되고, _Config.php 가 public/ 안에 있으면 DB 자격증명이 웹으로 노출됩니다. 문제가 있으면 종료 코드 1을 반환하므로 배포 파이프라인에 넣어도 됩니다.

확인 항목 전체는 프레임워크 CLI를 보세요.