Download the PHP package flexagon/framework without Composer

On this page you can find all versions of the php package flexagon/framework. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package framework

Flexagon

PHP

Flexagon is a lightweight, high-performance PHP web framework.

It embraces PHP's inherent simplicity over complex abstractions, keeping conventions to a minimum so you can build applications quickly.

Why Flexagon?

If you know PHP, you can get started right away.
Pages are .php files, views are written directly in PHP and HTML, and you can use the SQL you already know. There is no routing syntax, service container, or query DSL to learn before you start building.

Zero runtime dependencies.
Flexagon runs with PHP 8.3 and the pdo, openssl, and json extensions. There is no need to install dozens of third-party packages just to use the framework.

Small and fast.
In the same environment, framework bootstrap takes 1.09 ms, 2 MB of memory, and 15 loaded files. The framework itself remains compact at 39 PHP files and 7,148 lines of code.

Flexagon 3.5.0 Laravel 13.26.1
Runtime dependencies 0 77 packages
Installed size 532KB (PHAR 237KB) 42MB
Bootstrap time 1.09ms 12.85ms
Bootstrap memory 2MB 20MB
Files loaded at bootstrap 15 336

Simple deployment.
The entire framework can be deployed as a single 237 KB PHAR file. The target server does not need Composer or a separate cache-warming step.

Design Principles

URLs map directly to file paths

A request to /user/profile maps directly to public/user/profile.php.

There is no routing table to maintain. Create a file and it gets a URL; move the file and the URL moves with it. The URL itself makes it easy to see which file will be executed.

The database is the source of truth for the schema

On the first query, a DAO runs DESCRIBE to read column, primary-key, and auto_increment metadata, then reuses it for the rest of the request.

A schema already defined in the database does not need to be duplicated in PHP. When the schema changes, there is no separate mapping definition to keep in sync.

Global configuration stays explicit

Configuration is collected in the static _Global class.

There is no DI container or service locator between you and the configuration, so it is easy to see where settings live and which values are in use. Type _Global:: in your IDE to discover the available settings through autocompletion.

Minimal overhead per request

Framework bootstrap consists of defining constants, registering the autoloader, and loading configuration files.

Flexagon does not eagerly create unnecessary objects or services, and DataSourceManager reuses database connections within each request.


Requirements

Item Version / Notes
PHP 8.3 or later
Extensions pdo_mysql, openssl, json
Web server Apache (mod_rewrite) or nginx
Database MySQL / MariaDB, MS SQL Server

Installation

Flexagon is distributed as two Composer packages.

Package Purpose
flexagon/framework Framework core (library)
flexagon/skeleton Application skeleton (project template)

New Project

You can update the framework independently.

Add to an Existing Project

init creates the 18 files that make up the project structure, including public/, application/, script/, and flexagon.php. Existing files are left untouched, so you can also use it after an upgrade to add only newly introduced structure files. Use --force to overwrite existing files.

Installing only flexagon/framework gives you immediate access to utility classes such as StringUtil, ValidUtil, and CryptoUtil, as well as BaseModel. However, the DAO layer requires the application to define _Global. Without it, BaseGlobal defaults are used, so no fatal error occurs, but the empty data-source configuration prevents database connections. For real applications, start with the skeleton package.

flexagon.php checks three layouts in order, so the entry-point code remains the same regardless of how the framework is installed.

Order Path Scenario
1 vendor/flexagon/framework/Bootstrap.php Composer installation
2 application/_Flexagon.phar (file) Packaged as a single PHAR
3 application/_Flexagon.phar/Bootstrap.php Source directory

Bootstrap.php finds the nearest parent directory containing application/_Global.php and uses it as PROJECT_ROOT. Application path resolution therefore works the same whether the framework lives under vendor/ or inside a PHAR.

Autoloading

Application classes are mapped to application/ through PSR-4 in composer.json.

To add a namespace, simply create a directory with the same name. There is no need to modify composer.json.

The framework automatically loads the _Flexagon\ namespace, global helpers (_echo, _t, ___), and TemplateLoader. No additional configuration is required.

Docker

The included docker-compose.yml provides a PHP 8.3 + Apache + Xdebug environment.

Database Configuration

Edit application/_Config.php.

Your First Page

Open http://127.0.0.1:9001/hello to render the page.

Environment Check

Verify that the project layout and runtime configuration are consistent.

It catches configuration mistakes that might otherwise fail silently. If opcache.save_comments is disabled, @encrypt and @db_auto_timestamp are ignored without an error. If _Config.php is placed under public/, database credentials may be exposed over the web. The command exits with status 1 when it finds a problem, making it suitable for deployment pipelines.

See Framework CLI for the complete list of checks.


Directory Structure

Under application/, namespaces map directly to directory paths. ExampleUser\UserDAO → application/ExampleUser/UserDAO.php.

The _Flexagon\ namespace resolves to the framework itself and normally does not need to be defined by the application.

Expose only public/ to the web. application/_Config.php contains database credentials; if the document root points to the project root, those files may be served directly.


Request Lifecycle

The three hooks run at distinct stages of the request lifecycle.

File Stage Purpose
_entry.php Before session Site metadata, response headers, locale
_prepare.php After session Authentication/authorization checks, shared data loading
_router.php Dispatch Executes the page. Replace this file when custom routing is needed

URL Mapping Rules

Request URL Executed file
/ public/index.php
/hello public/hello.php
/user/profile public/user/profile.php
/user/ public/user/index.php
/user/profile?id=3 public/user/profile.php

Request paths are normalized first by HttpUtil::normalizePath(). It removes NUL bytes, converts backslashes to /, and removes empty segments, ., and .., preventing traversal to parent directories.

TemplateLoader then resolves the final path with realpath() and includes it only after verifying that it remains inside public/ (or _Template/). Paths outside that boundary are rejected with a 404. This protection is enforced by the framework itself rather than relying solely on web-server path normalization.

The parsed result is stored in _Global::$URL_PARAM (UrlParamsModel).

Custom Routing

To dispatch requests manually instead of using file mapping, replace public/_router.php.


Configuration

_Global

All global configuration values are static properties of the _Global class, which extends BaseGlobal.

Key configuration options:

Property Default Description
$SITE_TITLE 'Flexagon' Site title
$TIMEZONE 'Asia/Seoul' Passed to date_default_timezone_set()
$DATA_SOURCES [] Data-source map (see below)
$DATA_SOURCE_ID 'default' Default data-source ID
$USE_COMPOSER true vendor/autoload.php auto-load
$USE_OUTPUT_BUFFER true Wrap the entire request with ob_start()
$DB_STATEMENT_CACHE_SIZE 64 Number of prepared statements cached per connection. 0 prepares every time
$DB_CONNECT_FAILURE_FATAL true Abort the request on DB connection failure. If false, connect() returns false
$ENABLE_EXTENSION_PHP false If true, URLs must explicitly include .php
$USE_AUTO_CREATED_AT_TIMESTAMP true @db_auto_timestamp insert automatic timestamping
$USE_AUTO_UPDATED_AT_TIMESTAMP true @db_auto_timestamp update automatic timestamping
$RUNNING_MODE FLEXAGON_CONST::RUNNING_MODE_PRODUCTION Runtime mode. The framework does not interpret this value; applications may use it for branching
$DEBUG_ON false Debug flag for application use
$DEBUG_QUERY_BREAKPOINT false after each query Mysql::debugQueryAfter() call (for debugger breakpoints)
$SITE_CONFIG['web']['header'] — HTTP headers added to every response
$SESSION_AUTO_START false Restore session automatically during bootstrap
$SESSION_NAME 'session_data' Session cookie name
$SESSION_DOMAIN '' Cookie domain (.example.com)
$SESSION_COOKIE_SECURE null Cookie Secure flag. null enables it automatically for HTTPS requests
$SESSION_COOKIE_HTTPONLY true Cookie HttpOnly flag
$SESSION_COOKIE_SAMESITE 'Lax' 'Lax' · 'Strict' · 'None'. 'None'automatically enables Secure
$SESSION_MODEL_CLASSES [] Classes allowed in session cookies. If empty, only BaseModel inheritance is checked
$SESSION_TIMEOUT_SECONDS 86400 Session lifetime (seconds)
$SESSION_REQUIRE_EXPIRY false Reject legacy cookies without exp. Set to true after the migration period
$SESSION_NOT_BEFORE 0 Invalidate all sessions issued before this timestamp (stateless forced logout)
$SESSION_ENCRYPTION_STRING '' Session encryption key (10characters or more)
$CLASS_PROPERTY_ENCRYPTION_PASSPHRASE '' @encrypt property encryption key (10characters or more)

Data Sources

You can register multiple data sources.

Each data source receives a unique ID based on sha1(username@host/dbName), and DataSourceManager reuses connections by that ID. Multiple DAOs pointing to the same database therefore share a single connection within the request.

Stage-specific Configuration

Place stage-specific configuration in application/_Config/<stage>/_Config.php and select it from the CLI with the runtimeStage argument.

The default stage directories are alpha, beta, and production.


Models and DAOs

Models

Extending BaseModel provides array/JSON conversion, encryption/decryption, and automatic timestamps. Declare properties as private with getters and setters; mapping is based on method names.

Methods provided by BaseModel:

Method Description
getArray(bool $containsObject = true, bool $forceAll = false) Convert getters to an associative array
setByArray(array $data) Populate through setters; both snake_case and camelCase keys are accepted
getJson(int $flags = JSON_UNESCAPED_UNICODE) JSON serialization (nested objects are flattened to arrays)
encrypt() / decrypt() @encrypt Encrypt/decrypt annotated properties
getCreatedAt() / getUpdatedAt() Unix timestamp
getCreatedAtDatetimeString() Y-m-d H:i:s string

Because BaseModel implements JsonSerializable, json_encode($model) works directly.

setByArray() uses reflection to reconcile common type mismatches. Empty strings become null for nullable properties, and scalar values are converted to matching cases for backed-enum properties. This makes it practical to pass form input directly into a model.

DAOs

Extend BaseMySqlDAO and specify $tableName to get the core CRUD operations.

The CRUD methods are protected by design. Each DAO explicitly chooses which operations to expose, keeping its public interface narrow and aligned with the domain.

Method Description
_insert($modelOrArray) INSERT. Returns the auto-increment value (false on failure)
_update($modelOrArray) UPDATE by primary key
_updateByQuery($modelOrArray, $whereSql, $params) UPDATE with a custom condition
_select($modelOrArray, ?object $vo) Fetch one row; returns an object when $vo is provided, otherwise an array
_selectByQuery($whereSql, $params, ?object $vo) Fetch one row with a custom condition
_selectList(?object $vo, $page, $perPage, $whereSql, $params, $orderSql) Fetch a paginated list
_selectTotalCount($whereSql, $params) Count matching rows
_delete($modelOrArray) DELETE by primary key
_deleteByQuery($whereSql, $params) DELETE with a custom condition
_insertAll($modelList, $chunkSize = 500) Bulk INSERT using one statement per chunk; returns the number of inserted rows
_truncate() TRUNCATE

When using SQL Server, BaseMsSqlDAO provides the same method surface. Both DAO implementations extend BaseSqlDAO, where CRUD operations, schema caching, and transaction handling are shared. Subclasses contain only dialect-specific behavior: identifier quoting (`name` / [name]), schema inspection (DESCRIBE / INFORMATION_SCHEMA), and pagination (LIMIT / OFFSET·FETCH).

When you need direct SQL, use $this->db (a Mysql instance).

Column ↔ Property Mapping

Database snake_case columns are mapped automatically to PHP camelCase properties.

DB column Getter / Setter Property
id getId() / setId() $id
user_name getUserName() / setUserName() $userName
created_at getCreatedAt() / setCreatedAt() $createdAt

Parameter Binding

Queries use PDO prepared statements with named placeholders. Framework-generated queries use the uppercase column name as the placeholder (user_name → :USER_NAME).

If the same placeholder appears multiple times in a query, SqlUtil::expandQueryParams() automatically expands it into distinct parameters, avoiding PDO's duplicate-binding limitation.

Debugging

When _Global::$DEBUG_QUERY_BREAKPOINT is enabled, Mysql::debugQueryAfter() is called after every query. The method is intentionally empty, making it a convenient IDE breakpoint for inspecting executed queries.


Annotations

Flexagon reads PHPDoc tags at runtime to modify behavior (PhpDocUtil).

The canonical notation is snake_case.

Tag names are case-insensitive and separator-insensitive. The following forms are equivalent.

Tag values are case-insensitive, but separators remain significant (insert = INSERT, while my_value ≠ myvalue).

Both single-line docblocks (/** @db_auto_timestamp insert */) and multiline docblocks are supported.

@db_auto_timestamp

Automatically fills Unix timestamps on INSERT and UPDATE. This is already applied to createdAt and updatedAt in BaseModel.

@encrypt

Automatically encrypts and decrypts properties with AES-256-CBC. Values are encrypted before being stored in the database and decrypted when query results are mapped back to objects.

Ciphertext uses the format base64(version || IV || HMAC-SHA256 || ciphertext). A fresh IV is generated for every operation, so identical plaintext produces different ciphertext each time. Before decryption, the HMAC is verified with hash_equals() to reject tampered data. Encryption and authentication keys are derived separately from the passphrase using hash_hkdf().

_Global::$CLASS_PROPERTY_ENCRYPTION_PASSPHRASE must be at least 10 characters long or an exception is thrown. Make sure the database column is large enough to hold the ciphertext.

@exclude_from_get_array

Excludes a getter from getArray() / getJson() output. Use it for values such as password hashes that should not be serialized.

Calling getArray(forceAll: true) ignores exclusions and returns all values. DAOs use this mode internally when writing to the database.


See ANNOTATIONS.md for the complete list, constraints, and instructions for defining custom annotations.


Transactions and Multiple Data Sources

Single DAO

Transactions Across Multiple DAOs

Start a global transaction with DataSourceManager, and every data source used afterward automatically participates in the transaction.

Commits and rollbacks are performed in the reverse order in which connections were registered.

Assigning a Data Source to a DAO

Override the DATA_SOURCE_ID constant.


Sessions

Flexagon sessions serialize model objects into encrypted cookies rather than server-side files. Because there is no shared session store, horizontally scaling across multiple web servers requires no additional session-storage configuration.

Configuration

Session cookies carry authentication state, so HttpOnly and SameSite=Lax are enabled by default, and Secure is added automatically for HTTPS requests. HTTPS detection checks $_SERVER['HTTPS'], port 443, and then X-Forwarded-Proto.

Session Model and DAO

Usage

When $SESSION_AUTO_START is enabled, the session is restored during bootstrap and exposed in two locations.

The second form is derived by converting the model class name to UPPER_SNAKE_CASE (SessionUserModel → SESSION_USER_MODEL). To access it with a type hint, declare the corresponding static property in _Global in advance.

A common pattern is to perform authorization checks in _prepare.php.

Note: A session-model property marked with @encrypt is encrypted twice inside the cookie. Because the entire session cookie is already encrypted with $SESSION_ENCRYPTION_STRING, the additional annotation is usually unnecessary.


Security

What the Framework Provides

Item Description
SQL injection All DAO queries use PDO prepared statements
Path traversal Router include paths cannot escape public/
Session integrity AES-256-CBC + HMAC-SHA256, expiration verified server-side
Session cookies HttpOnly·SameSite enabled by default; Secure automatic
Column encryption @encrypt — random IV, HMAC verification, HKDF key derivation
Forced logout $SESSION_NOT_BEFOREinvalidates all sessions (stateless)

Application Responsibilities

These features are intentionally not provided by the framework. Do not assume Flexagon handles them automatically.

The application is also responsible for validating redirect targets, preventing SSRF, sanitizing HTML, and setting appropriate security headers.

The HtmlUtil::stripSpecificTag() family is regex-based and is not an XSS filter. These methods are convenience helpers for cleaning up tags only.


Templates and Assets

TemplateLoader

The supplied array is passed through extract() and exposed as local variables inside the template.

AssetLoader

Collect CSS and JavaScript assets and render them together at the desired location. A version query string can be added for cache invalidation.


Utility Libraries

All utilities use static methods and have no external dependencies. Their namespace is _Flexagon\Libs.

Class Key Features
StringUtil case conversion, UTF-8 cleanup, hex encoding, random string generation
ArrayUtil camelCase key conversion, array diff, nested-array key lookup
ValidUtil email, integer, float, alphanumeric, and ID validation
CryptoUtil AES-256-CBC encryption/decryption (strings / arrays, random IV support)
FileUtil directory traversal, recursive creation, extension detection
HttpUtil URL parsing, query-string parsing, request-path resolution
NetUtil GET/POST HTTP client, JSON response parsing, file uploads
HtmlUtil redirects, HTML tag/attribute removal, image URL extraction
TimeDateUtil timestamp conversion, timezone offsets, relative time formatting
SqlUtil parameter normalization/expansion, SQL escaping, SELECT → COUNT conversion
ClassUtil class name, path, property, and caller inspection
PhpDocUtil PHPDoc tag parsing (basis of annotation support)
AssetLoader CSS/JS management
TemplateLoader template loading
DataSourceManager connection reuse and global transactions

Global Helper Functions

The three functions defined by Libs/_Util.php are available globally without a namespace.

When gettext (__() or _()) is available, translation is applied before placeholder substitution.

Enum Helpers

Add the EnumSupporter trait to a backed enum to enable convenience methods.

When generating DDL for an ENUM column, use toQuotedCommaString(). It quotes each value and escapes embedded quotes by doubling them.

For pure enums without backing values, keys() and toCommaString() return case names, while values() and toArray() return null values.

Enum-typed properties are also handled automatically by DAO mapping. Scalar database values are converted to matching enum cases when models are hydrated, and ->value is bound when values are stored.


CLI Scripts

Place batch jobs in the script/ directory.

Arguments in key=value form are parsed into both $_PARAMS and $_REQUEST. runtimeStage is reserved and selects the configuration directory to load.

When running from the CLI, FLEXAGON_ENV::$_RUNTIME_ENV is set to RUNTIME_ENV_SCRIPT, bypassing the web request pipeline entirely, including sessions, routing, and output buffering.

Framework CLI

The framework itself provides two commands.

Invocation Supported installation types
php script/flexagon.php All (Composer · PHAR · source)
php vendor/bin/flexagon Composer installation

A PHAR cannot be passed to the PHP CLI as a phar://... script path, so script/flexagon.php acts as the entry point. The PHAR does not contain templates for init, so only check is available in that installation mode.

init

Creates the 18 files that make up the project structure. If you started with composer create-project flexagon/skeleton, these files already exist. This command is primarily useful when adding flexagon/framework to an existing project with composer require.

Existing files are left untouched. You can also run the command after an upgrade to add only newly introduced structure files.

Use --force if you need to overwrite existing files. Be careful: modified files will be replaced with the template versions.

check

Checks that the project layout and runtime configuration are consistent and returns exit code 1 when a problem is found, making it suitable for deployment pipelines.

Item Check Result
php 8.3 or later Error
ext-json · ext-openssl · ext-pdo Loaded Error
opcache.save_comments Enabled Error
project layout flexagon.php · application/_Global.php · public/__flexagon.php · public/_router.php Error
config placement _Config.php and application/ are not exposed under public/ Error
bootstrap Framework boots successfully Error
session key $SESSION_ENCRYPTION_STRING length when $SESSION_AUTO_START is enabled Error
data sources Configured; no template placeholders remain Warning
display_errors Enabled in production mode Warning

The following checks are especially important because these issues can otherwise fail silently.

License

MIT License

Copyright (c) 2010-2026 Younghwan Yong


All versions of framework with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
ext-json Version *
ext-openssl Version *
ext-pdo Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package flexagon/framework contains the following files

Loading the files please wait ...