Download the PHP package rayfunghk/razy without Composer

On this page you can find all versions of the php package rayfunghk/razy. 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 razy

Razy Framework

A modular PHP framework for multi-site, multi-distributor application development.

CI Version PHP codecov PSR-4 PSR-12

Razy lets you manage multiple websites, APIs, and services from a single codebase. Each distributor runs its own set of versioned modules with independent routing, templates, and database access — while sharing common services through a unified module system.


Table of Contents


Key Features

Category Highlights
Multi-Site Architecture Run multiple distributors (sites/apps) from one installation with independent module sets, routing, and configuration
Module System Dependency-aware loading with 14 lifecycle hooks, cross-module APIs, event emitters, and bridge commands
Template Engine Block-based rendering with modifiers, function tags, WRAPPER/INCLUDE/TEMPLATE/USE/RECURSION blocks
Database Layer Multi-driver (MySQL, PostgreSQL, SQLite) with fluent query builder, Simple Syntax, ORM, migrations, and schema management
CLI Tooling 20+ commands — build, pack, publish, install from GitHub, interactive shell (runapp), bridge calls
Thread System Process-based concurrency via ThreadManager with spawn, await, and joinAll
Package Management Version-locked modules, Composer integration, phar distribution, repository publishing
Standalone Packages Run modules as CLI apps (.phar), exec/serve modes, dependency orchestration, inter-package API & events
Built-in Classes SSE, XHR (CORS), Mailer (SMTP), DOM builder, Crypt (AES-256), Collection, HashMap, YAML, OAuth2, Cache (PSR-16), Authenticator (TOTP/HOTP 2FA), FTPClient, SFTPClient, WebSocket

Requirements

Installation

Via Composer

Via Docker

From Source

Subdirectory installs (https://host/your-prefix/)

If the application is not at the web root (for example https://localhost/abc/ with files under …/htdocs/abc/), Razy builds RAZY_URL_ROOT and module asset URLs from RELATIVE_ROOT. The framework prefers the path of SYSTEM_ROOT relative to DOCUMENT_ROOT, and falls back to dirname($_SERVER['SCRIPT_NAME']) when those paths do not align (symlinks, mounts, or unusual server variables). Ensure your front controller (index.php) is invoked with a correct SCRIPT_NAME (typical Apache, nginx + PHP-FPM, and Caddy setups do). Rewrite rules should still map /your-prefix/webassets/… to the framework as documented.

Quick Start

This creates the working directory structure:

sites.inc.php examples

Map domains to distributors in sites.inc.php:

config_mapping in dist.php

Reuse the same distributor across domains with different config folders:


Docker

Razy ships with a complete Docker setup for development and testing.

Development

Full Test Suite (Linux + Redis + SSH2)

Run all tests including those that require Linux-only extensions:

DevContainer (VS Code / Codespaces)

Open the project in VS Code and select "Reopen in Container" — the DevContainer is pre-configured with PHP 8.3, Composer, and all required extensions.


Architecture Overview

Each distributor maps to a domain/path via sites.inc.php and loads its own versioned module set. Modules communicate through APIs, events, and bridge commands. The Standalone mode provides a lightweight runtime for single-module applications.


Module Lifecycle

Modules progress through a well-defined lifecycle during each request:


Core Concepts

Routing

Two routing strategies: lazy routes (convention-based) and regex routes (pattern-based).

Cross-Module API

Modules expose and consume APIs for inter-module communication:

Template Engine

Block-based templates with variables, modifiers, conditionals, and iteration:

Database Simple Syntax

Shorthand syntax for joins, WHERE clauses, and JSON operations:

CLI Commands


Package Management (Composer Integration)

Razy includes a built-in Composer-compatible package manager that downloads, extracts, and version-locks third-party packages from Packagist or any private mirror — scoped per distributor so each site gets its own isolated dependency tree.

How It Works

  1. Modules declare prerequisites in their package.php using vendor/package notation:

  2. On compose, the framework collects all prerequisite entries across every loaded module, resolves version constraints, and downloads matching packages:

  3. Per-distributor isolation — packages are extracted into autoload/{distributor_code}/ with PSR-4/PSR-0 namespace mapping, and a single autoload/lock.json tracks installed versions keyed by distributor:

Transport Layer

The package manager is transport-agnostic. By default it fetches from Packagist over HTTPS, but you can point it at any mirror using a pluggable transport:

Transport Protocol Use Case
HttpTransport HTTP/HTTPS Packagist, Satis, Private Packagist, GitHub
FtpTransport FTP/FTPS FTP mirrors with optional TLS
SftpTransport SFTP SSH-based secure transfer
SmbTransport SMB/CIFS Windows network shares, Samba
LocalTransport File system Local directory or mounted drive

All transports implement PackageTransportInterface. Set a global default at bootstrap:

Version Constraints

Supports the same constraint syntax as Composer: ^1.0, ~2.3, >=1.2.0, *, exact versions, and stability flags (@dev, @beta, @RC). Sub-dependencies declared in each package's own require block are resolved recursively.

Full details: Packaging & Distribution wiki


Standalone Package System

Razy modules can run as standalone CLI applications — packaged as .phar archives and executed outside the web request lifecycle. This turns any module into a self-contained tool, background service, or migration script while retaining full access to Razy's module system, APIs, and events.

Architecture

Two execution modes:

Mode Behaviour Hook
exec Run-to-completion — exits with a code __onPackageExec()
serve Long-running (HTTP, WebSocket, queue) — blocks until signal __onPackageServe()

Two runtime modes:

Runtime Flag How modules load
Standalone (default) Single module + co-modules from on_depend "load"
Distributor -d dist/module Full Distributor loads ALL dist modules; target module executes lifecycle

razy.pkg.json

Every package has a manifest at the archive root:

Field Purpose
package_name Unique identifier (e.g., my-api, or vendor/name for dist mode)
version SemVer version string
mode exec (run-to-completion) or serve (long-running)
strict When true, serve mode binds to localhost only
on_depend Dependency orchestration — see below
healthcheck HTTP polling config for serve-mode packages
prerequisite Composer packages to auto-install

Dependency Orchestration (on_depend)

Packages can depend on other packages with three wait strategies:

Wait Mode Behaviour
"complete" Run the dependency as exec-mode, block until it exits successfully
"healthcheck" Spawn the dependency as serve-mode, poll its healthcheck URL until healthy
"load" Extract the dependency and inject it as a co-module into the same Standalone runtime — full API, events, and cross-module access

PackageTrait — Lifecycle Hooks

Add PackageTrait to any Controller to make it package-aware. All hooks use the reserved __onPackage* prefix — no conflict with module closures or routing methods.

Hook When Return
__onPackageStart After prerequisites + dependencies resolve false aborts execution
__onPackageExec Exec-mode entry point int exit code (0 = success)
__onPackageServe Serve-mode entry point (blocks) void
__onPackageStop On shutdown or stop signal void
__onPackageHealthcheck Polled by dependents or /_razy/health bool

Package API & Package Events

Separate from the Module API/Event system — these are inter-package communication channels for packages running in the same process (e.g., co-modules loaded via on_depend "load").

CLI Usage

Dual Mode Detection

A single Controller can serve both web requests and package execution:


Demo Modules

The demo_modules/ directory contains 22 production-ready reference modules organized by category:

Category Modules
core/ event_demo, event_receiver, route_demo, template_demo, thread_demo, bridge_provider
data/ collection_demo, database_demo, hashmap_demo, yaml_demo
demo/ demo_index, hello_world, markdown_consumer
io/ api_demo, api_provider, bridge_demo, dom_demo, mailer_demo, message_demo, sse_demo, xhr_demo
system/ advanced_features, helper_module, markdown_service, plugin_demo, profiler_demo

Each module includes inline documentation and can be copied directly into your distributor's module directory. See the demo README for detailed descriptions.


Roadmap

All items for v1.0 are complete. The framework is in beta — APIs are stable but may receive minor refinements before the final release.

Status Feature
Multi-site distributor architecture with domain routing
Module system with dependency resolution & 14 lifecycle hooks
Template engine with blocks, modifiers, conditionals, iteration
Multi-driver database layer (MySQL, PostgreSQL, SQLite)
GitHub module installer via CLI
Thread system (ThreadManager)
Cross-distributor bridge system
Module repository & publishing system
Cache system (PSR-16 SimpleCache with File, Redis, Null adapters)
Authenticator (TOTP/HOTP 2FA)
FTP/SFTP file transfer clients
Database migration system
Queue / job dispatching
Rate limiting middleware
WebSocket server & client
Docker image & CI/CD pipeline
Standalone Package System (exec/serve, dependency orchestration, Package API/Events)
Comprehensive test suite (4,564 tests, 8,178 assertions)

Version Milestone Summary

v1.0-beta — First Public Beta (Feb 2026)

The foundation release. Razy shipped as an open-source project with full governance (MIT license, contributing guide, security policy), Docker infrastructure, a Composer-compatible package manager, and a comprehensive test suite of 4,564 tests with zero skips. This milestone established the framework's public contract — stable APIs, reproducible builds, and CI/CD from day one.

v1.0.1-beta — Worker Optimization & Tenant Isolation (Feb 2026)

Two problems drove this release:

1. Performance under persistent workers.
The original FrankenPHP worker loop rebuilt the entire object graph (Application, Container, Standalone, Module, RouteDispatcher) on every single request — the same work a traditional CGI process does, but inside a persistent worker where it should only happen once. Fixing this was straightforward in concept (boot once, dispatch many) but required rethinking how state flows through the framework. The result was a 37× throughput improvement (171 → 6,311 RPS) and 5× faster than Laravel Octane (Swoole) on read-heavy workloads, with an additional round of 8 hot-path micro-optimizations shaving another 4.6% off tail latency.

2. Cross-vendor module identity collisions.
Razy's module system uses a two-part vendor/package code (e.g., acme/logger), but several internal paths — config files, asset URLs, API registration, closure prefixes, rewrite rules — were keyed on only the short class name or alias (the last segment). In a single-vendor setup this worked fine. But in multi-tenant and multi-vendor deployments — the exact use case Razy was designed for — two modules from different vendors with the same package name (e.g., acme/logger and beta/logger) would silently collide: one module could read another's config, hijack its API, shadow its assets, or cause rewrite rules to be silently dropped.

This is not an edge case. In enterprise SaaS environments, module vendors operate independently and cannot coordinate naming. A platform hosting modules from multiple vendors must guarantee vendor-scoped isolation by default. Five collision vectors were identified and fixed, API registration now throws on duplicates instead of silently overwriting, and all identity keys now use the full vendor/package module code.

Version Key Changes
v1.0-beta Open-source readiness, Docker, Composer package management, 4,564 tests
v1.0.1-beta 37× worker throughput, 5× vs Laravel, cross-vendor module isolation (5 collision fixes), DI security hardening, pre-commit hook, 4,794 tests

Full per-version changelogs: changelog/ directory.

Cross-Tenant Architecture — Why and What's Next

Razy was designed from the start as a multi-site, multi-distributor framework: one codebase, many projects. But as the architecture matured — especially with FrankenPHP worker mode keeping the entire Application graph alive in memory — a deeper problem surfaced.

The problem: shared-process trust boundaries.

In a traditional CGI model, each request starts a fresh PHP process. Isolation is free — one request can't reach into another's memory. But in a persistent worker, all distributors and modules share the same process. A malicious or buggy module in one distributor can theoretically access another distributor's data, configs, or API registrations. The v1.0.1-beta cross-vendor collision fixes addressed the naming side of this problem, but the runtime isolation side remains.

The real-world scenario is straightforward: a SaaS platform hosts multiple tenants (clients), each with their own distributors, modules, domains, and data. Today, they all run inside the same PHP process, share the same filesystem, and trust each other implicitly. For internal tooling this is acceptable. For enterprise multi-tenant SaaS — where tenants are separate legal entities with separate data obligations — it is not.

The solution: 1 Tenant = 1 Razy Application environment.

Each tenant runs as a complete, isolated Razy instance — its own container, its own filesystem, its own open_basedir. The local host becomes just another tenant (the "Host Tenant"). Cross-tenant communication uses an explicit HTTP bridge with HMAC authentication, not shared memory. Module code requires zero changes — isolation is enforced at the framework and OS layers.

Phase Version What It Delivers
Phase 0 — Foundation v1.0.1-beta DI security blocklist, worker dispatch guards, boot-once, distributor caching, module change detection
Phase 1 — Tenant Isolation Core v1.1.0-beta Bootstrap tenant constants, data path isolation guards, in-memory hotplug (plugTenant/unplugTenant), worker signal integration
Phase 2 — Docker Multi-Tenant v1.1.0 Hardened tenant Dockerfile (open_basedir + disable_functions), Compose templates, per-tenant config generator
Phase 3 — Communication Layers v1.2.0 TenantEmitter (HTTP bridge + HMAC), DataRequest/DataResponse (file I/O), __onTenantCall permission gates, CLI razy tenant commands
Phase 4 — Kubernetes + Lifecycle v1.3.0 K8s namespace/PVC/NetworkPolicy templates, Helm chart, WorkerLifecycleManager integration
Phase 5 — Whitelist + Admin UI v2.0.0 TenantAccessPolicy, fine-grained cross-tenant data sharing, admin dashboard

Architecture deep-dive: architecture/ENTERPRISE-TENANT-ISOLATION.md


Performance: Razy vs Laravel

Benchmarked against Laravel 12 + Octane (Swoole) under identical conditions — same host, same MySQL, same container resources (2 CPUs / 4 GB RAM), same k6 load profiles.

Head-to-Head Results

Scenario Razy RPS Laravel RPS Razy Advantage Razy p95 Laravel p95
Static Route 6,331 1,254 5.0× faster 18.6ms 186ms
Template Render 6,264 1,137 5.5× faster 19.0ms 189ms
DB Read (SELECT) 3,763 952 4.0× faster 38.5ms 191ms
DB Write (INSERT) 754 842 Laravel 1.1× 182ms 186ms
Composite (DB + Template) 4,528 958 4.7× faster 72.4ms 395ms
Heavy CPU (500K MD5) 144 325 Laravel 2.3× 595ms 1,590ms

Razy outperforms Laravel Octane in 4 of 6 scenarios — all throughput-dominant workloads. Laravel leads in DB Write (MySQL INSERT is the bottleneck, not framework overhead) and CPU-bound fast-request throughput (Swoole's coroutine isolation). Even in the Heavy CPU scenario, Razy achieves 2.7× lower tail latency (p95: 595ms vs 1,590ms).

Runtime Configuration

Razy Laravel
Runtime FrankenPHP (Caddy, PHP 8.3.7, Alpine) PHP 8.3-cli + Swoole (Octane)
Worker Mode Persistent worker, boot-once dispatch Octane Swoole (--workers=auto)
OPcache JIT 1255, 128 MB buffer JIT 1255, 128 MB buffer
Config Cache N/A (standalone Phar) config:cache, route:cache, view:cache

Why Is Razy Faster?

The difference is architectural, not just runtime tuning:

Razy Laravel
Per-request overhead ~0.05ms (dispatch only) ~0.8ms (service container resolution, middleware pipeline, route matching)
Object graph Boot once, reuse across all requests Rebuilt partially per request even with Octane
Template engine Native PHP blocks, zero compilation Blade compiles to PHP, then executes
Route matching Direct hash lookup from pre-compiled table Regex matching through middleware stack
Deployment Single Razy.phar — nothing to cache Requires config:cache, route:cache, view:cache, event:cache for production

Conceptual Differences

Razy and Laravel solve different problems with fundamentally different philosophies:

Aspect Razy Laravel
Design goal Multi-project, multi-tenant module platform Full-featured web application framework
Unit of work Module (reusable, versioned, distributable) Application (monolithic, project-bound)
Multi-site First-class — distributors share modules Bolted on via tenancy packages
Team boundary Distributor per team, modules per sub-team, API/Event contracts Package per team, service classes, facades
Upgrade model Update shared module → all projects benefit Update per project via composer update
Code sharing Shared Modules (reference, not clone) Composer packages (vendor lock per project)
Configuration dist.php + package.php (minimal, flat) .env + config/*.php + service providers (layered, ceremonial)
Learning curve Steep upfront (module lifecycle), low ongoing Low entry (conventions), steep at scale (deep service container knowledge)
Ecosystem Purpose-built, self-contained Massive third-party ecosystem (Forge, Vapor, Nova, Livewire, etc.)

When to Choose Razy

Razy is ideal for:

Laravel is ideal for:

Full benchmark methodology, raw data, and reproduction steps: benchmark/ directory.


Testing

Full Platform Coverage via Docker

To run all tests with zero skips (including Redis, SSH2, and Linux-only permission tests):

Test suite covers: 102 test classes across Authenticator, Cache (File/Redis/Null), Collection, Configuration, Container (DI), Controller, Crypt, Database (drivers, queries, transactions, migrations), DOM, EventDispatcher, FTPClient, HashMap, HttpClient, Logger, Mailer, Middleware, Module system, ORM, Pipeline, Routing, SFTPClient, Session, Template, Validation, WebSocket, Worker lifecycle, YAML, and more.


Documentation

New here? Start with the Quick Start (5 min) tutorial — build and run your first module in under 5 minutes.

Full documentation is available on the GitHub Wiki and the Documentation Site.

Section Topics
Getting Started Quick Start · Installation · Architecture
Core Concepts Modules · Controller · Agent · Routing · Events
Data & Storage Database · Collection · Configuration · HashMap · YAML
Rendering Template Engine · DOM Builder
IO & Communication XHR · SSE · Mailer · FTP/SFTP · SimplifiedMessage
Security Crypt · Authenticator
Advanced Plugins · Threads · Simple Syntax
Deployment Sites Config · Packaging · CLI · Caddy Worker
Reference API Reference · ModuleInfo · Utilities · Testing

Contributing

Contributions are welcome! Please read the Contributing Guide before submitting a pull request.

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/my-feature)
  3. Write tests for your changes
  4. Ensure all tests pass (composer test)
  5. Submit a pull request

For bug reports and feature requests, please use GitHub Issues.

See also: Security Policy


Why Razy?

Razy was born from real-world freelance experience managing multiple client projects simultaneously. Traditional frameworks made it painful to share code between projects, backport updates across deployments, and maintain version-specific module sets for different clients.

Razy solves this by treating modules as versioned, distributable units — each project (distributor) picks exactly which module versions to load, shared services are available globally, and the entire system packages into a single phar for deployment.

Design principles:


Development Journey

Razy didn't start as a framework. It grew out of years of real-world project delivery, each stage solving a pain that the previous one exposed.

Phase 1 — The Template Problem

In the early days of web development, PHP and HTML were tangled together. MVC was a good idea in theory, but in practice, frontend designers and backend developers constantly stepped on each other's toes. To reduce friction between the two roles, the first generation of Razy's template engine was born — inspired by phpBB's template architecture rather than Smarty, because Smarty's syntax was something a frontend person couldn't read at a glance. The goal was simple: give designers markup they can understand without learning a programming language.

Phase 2 — The Copy-Paste Trap

When freelance projects started coming in, a painful pattern emerged. Every new project meant creating a new folder, copying in the template engine, configuring everything from scratch, and dragging over whatever libraries were useful from the last project. Each copy diverged the moment it was created. Changes were large, setup was slow, and nothing was truly reusable.

Phase 3 — The Version Drift Crisis

The natural next step was to consolidate common code into a shared library. But as that library grew, maintaining it became its own problem. Updating a feature in one project didn't transfer cleanly to another — it wasn't just copy-and-paste. Worse, working with other vendors' systems revealed a deeper structural issue: the earlier a client was onboarded, the more outdated their system became. Debugging old versions was expensive, shipping new features to legacy clients was impractical, and the business incentive for building new functionality dropped because only the newest clients would benefit.

Phase 4 — Rethinking the Development Model

This led to a fundamental rethink. Instead of treating each project as a standalone codebase, what if code management and project management were the same thing? What if every client's system was part of one unified development environment — different configurations of the same modules, not different copies? The concept of a module-driven, version-aware architecture started taking shape.

Phase 5 — From Project Fees to Subscription Services

The business model evolved alongside the architecture. Rather than charging one-time project fees and walking away, the shift was toward monthly subscription services — maintaining a long-term relationship with each client. This meant every client, old and new, could receive continuous upgrades on a shared foundation. The economic incentive aligned perfectly with the architectural vision: invest once in a feature, roll it out across all subscribers.

Phase 6 — Razy Takes Shape

Razy's first real prototype emerged with a clear mission: minimize the cost of developing and maintaining modules. Modules became reusable across projects. Multiple projects shared a single development environment. Module functionality was broken into small, focused fragments. URL-path-to-controller mapping made code navigation intuitive. Shared Modules could be referenced rather than cloned — one update propagated everywhere.

Phase 7 — Team Boundaries via API & Event

As projects grew, multiple teams began working on the same system. To prevent teams from interfering with each other's codebases, Razy introduced Module API and Event systems. Each team declared what data they needed via requirement requests, and the providing team exposed it through formal APIs and events. Cross-module communication became explicit and permissioned rather than implicit and fragile.

Phase 8 — From Module-Base to Distributor-Base

The unit of team ownership expanded. A team no longer managed just a single module — they managed an entire distributor, with sub-teams responsible for individual modules within it. This matched real organizational structures: one team owns the shop, another owns the admin panel, another owns the API gateway — each a distributor with its own routing, modules, and release cycle.

Phase 9 — Security & Isolation Hardening

With multiple teams and multiple distributors sharing infrastructure, security became a priority. Razy went through continuous refinement to ensure modules couldn't reach across distributor boundaries and tamper with core logic. The architecture evolved to enforce isolation by default — not as a policy, but as a structural impossibility.

Phase 10 — Developer Experience Refinement

Through years of real project delivery, Razy was continuously refined. Features like Simple Syntax (a shorthand for complex SQL joins and JSON operations) were added to make everyday development faster and more intuitive. Each pain point encountered in production fed back into the framework's design.

Phase 11 — Modern Stack & v1.0-Beta

The modern development environment demanded more. FrankenPHP Worker Mode was integrated for persistent-process performance. Mainstream deployment patterns (Docker, Caddy, CI/CD) were supported natively. AI tooling was adopted to accelerate documentation, code auditing, and architectural analysis — turning months of manual work into days. After three years of development plus six months of AI-assisted refinement, Razy v1.0-Beta shipped. Benchmarks showed higher throughput, lower latency, and better resource efficiency than mainstream frameworks like Laravel.

Phase 12 — Container Architecture for Zero-Downtime Updates

To minimize the impact of hotfixes and upgrades on running systems, Razy introduced Core Container and Module Container concepts. As long as a worker process was serving requests, hotplugged updates could be staged and transitioned using configurable strategies — from graceful drain to immediate swap — enabling zero-downtime version transitions in production.

Phase 13 — Tenant Isolation for Enterprise & SaaS

The latest evolution brings enterprise-grade tenant isolation. Each tenant runs as an isolated pod with its own filesystem, data, and configuration — supporting both Docker Compose and Kubernetes deployments. Staging environments are cleaner, SaaS onboarding is streamlined, and microservice architectures can leverage Razy's module system without sacrificing security boundaries. The framework now supports the full spectrum from single-developer side projects to multi-team, multi-tenant enterprise platforms.


License

MIT License — Copyright (c) Ray Fung


All versions of razy with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
ext-zip Version *
ext-curl Version *
ext-json 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 rayfunghk/razy contains the following files

Loading the files please wait ...