설치
요구 사항
| 항목 | 버전 / 비고 |
|---|---|
| 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를 보세요.