Download the PHP package cloude/framework without Composer

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

Cloude Framework

A minimalist PHP micro-framework. No magic, no service container. Persistence is opt-in: file-based (JSON / Markdown) by default, with a thin Active Record over PDO via Cloude\Model when you need a relational database.

Built with Claude Code

Cloude is shaped while pair-coding with Claude Code — Anthropic's terminal-native AI coding agent. The "one file per class, no magic, no DSL, no annotations" rules aren't aesthetic preferences: they exist so the agent (and you) can reason about any piece of the framework without loading a runtime in your head.

Try it:

Then ask Claude Code to scaffold a front controller with Cloude\Bootstrap, expose an MCP server with Cloude\Mcp\Server, or migrate a routes file into nested groups. The surface area is small enough that the agent usually nails it in one prompt.

For agents: see AGENTS.md — a tight reference card with the decision matrix, idioms and anti-patterns. AI tools (Claude Code, Cursor, Codex, …) pick it up automatically when they see the file at the repo root.

For Claude Code users specifically: CLAUDE.md is the "from zero to running feature" playbook — quick start, project layout, the standard add-a-feature workflow, common patterns, and how to brief Claude effectively. Copy it into your own project root once you start building on top of cloude/framework.

For design-pattern guidance: PATTERNS.md is the decision guide for picking an architecture — Transaction Script, MVC

  • Repository, or DDD layered. It maps "what your app looks like" to "which example to copy", with migration paths and anti-patterns.

For brand-new projects, AI-guided: SETUP.md is an interview script for AI coding agents. Point Claude Code (or any tool-capable agent) at this file and it walks you through eight steps — namespace, docroot, run mode (php -S / Docker / both), pattern, CSS, JS, optional modules — and scaffolds the project based on your answers.

Installation

Repository layout

Components

Core

Class Responsibility
Cloude\Arr Array helpers with dot-notation: get/set/has/forget/pluck/only/except/dot/undot/merge
Cloude\Bootstrap Front-controller bootstrap: initPaths() defines DOCROOT/APPPATH/BASEPATH; run() wires cli-server passthrough + ob_start + ErrorHandler + view base (pulls debug/views from Config when omitted)
Cloude\Cli Argv parsing + colored output for app/cli/ scripts
Cloude\Collection Fluent, chainable wrapper: map/filter/reduce/pluck/keyBy/groupBy/sortBy/take/chunk/unique/sum/avg/min/max/...
Cloude\Config Env helpers (env/boolEnv); multi-env file loader (configure/load/get); typed accessors (baseUrl/debug/path); legacy defineBaseUrl/defineDebug
Cloude\DateTime Tiny immutable date helper extending \DateTimeImmutable. Static constructors (now/today/parse/fromTimestamp); format shortcuts (toDateString/toTimeString/toDateTimeString/toIsoString); arithmetic (addDays/addHours/addMinutes/…); boundaries (startOfDay/endOfMonth/…); comparisons (isPast/isToday/isSameDay/…); signed diffIn{Days,Hours,Minutes,Seconds} and English diffForHumans(). Carbon-style setTestNow() / clearTestNow() for test isolation. Used automatically by the datetime cast
Cloude\EventLog Fire-and-forget POST to a webhook for usage analytics
Cloude\Format Yaml / json / xml / markdown encode-decode dispatcher (string ↔ array)
Cloude\Input Wrapper over $_GET, $_POST, $_SERVER, raw body and JSON
Cloude\JsonFile Per-request cached, atomic-write helper for JSON files
Cloude\JsonSchema In-house JSON Schema subset validator (no external deps)
Cloude\Logger File-backed logger with daily rotation and debug/info/warn/error
Cloude\TaskRunner CLI task runner. prefix:method dispatch over registered callables or static class methods, with auto list / help
Cloude\Router Router with /{param}, /{param?}, /{param:regex} patterns, nested route groups, and get/post/put/patch/delete/any helpers
Cloude\Session Static façade over $_SESSION with hardened cookie defaults (httponly, samesite=Lax, secure on HTTPS). Typed get/set/has/forget/all, flash messages (flash/pullFlash/reflash), CSRF helpers (csrfToken/checkCsrf), regenerate() for login flows
Cloude\Str String utilities: upTo/truncate/truncateMiddle/words/after/afterLast/between/squish/mask, slug/ascii, camel/pascal/snake/kebab, random/uuid/hash
Cloude\View Plain PHP template rendering with variable extraction and HTML escape

Cloude\Http\…

Class Responsibility
Cloude\Http\AssetUrl Versioned asset URLs (/{mtime}/assets/...) for cache-busting
Cloude\Http\Cache HTTP cache headers (ok, notFound, unavailable) and conditionalGet()
Cloude\Http\ErrorHandler Global error handler. Defaults to 503 (Retry-After: 600); honors HttpException::statusCode when thrown. HTML / JSON / .md / CLI / AJAX negotiation, debug mode
Cloude\Http\HttpException Throwable carrying a status code; caught by ErrorHandler to render with that status
Cloude\Http\NotFoundException HttpException pinned to 404; renders bundled 404.html.php (or your override)
Cloude\Http\Response One-call response helpers: json, html, xml, markdown, redirect, notFound, noContent

Cloude\Data\…

Class Responsibility
Cloude\Data\Repository Abstract base for directory-of-files repositories. Subclasses implement find / slugs / path; exists, findOr, all and the transform() hook come for free
Cloude\Data\JsonRepository One .json per entity. Atomic writes, per-request read cache via JsonFile
Cloude\Data\MarkdownRepository One .md (or .md.gz) per entity. Read returns frontmatter + parsed HTML via Markdown::parse

Cloude\Model\… and Cloude\Storage\…

Class Responsibility
Cloude\Model\Model Abstract Active Record. Subclass with protected static string $table + $connection (+ optional $types). CRUD via find / findBy / create / save / delete. Static helpers: table(), field('col'), as('alias'), ref(), query()
Cloude\Model\Cast Opt-in attribute coercion driven by the $types map: int, float, string, bool, decimal[:N], json/array, datetime[:FMT], date[:FMT], enum:FQCN. Null passes through
Cloude\Model\Storage\PdoStorage PDO-backed adapter. Driven by Cloude\Storage\Connection named pool
Cloude\Model\Storage\JsonStorage One JSON file per row (collection mode) or one big array (collection storage)
Cloude\Model\Storage\MarkdownStorage Markdown body + frontmatter as a row
Cloude\Model\Storage\ArrayStorage In-memory rows; ideal for tests
Cloude\Storage\Query Fluent SQL builder. SELECT / INSERT / UPDATE / DELETE + WHERE (with nested AND/OR groups) + INNER/LEFT/RIGHT/CROSS JOIN + ORDER BY + LIMIT/OFFSET + count()
Cloude\Storage\TableRef Lightweight (table, alias) value object. Pair with Model::as('u') for typed joins; __toString() yields the quoted FROM/JOIN expression
Cloude\Storage\Identifier SQL identifier-quoting helper. quote() for single names, qualify() for table.column / table.* / *
Cloude\Storage\Connection Named PDO pool keyed off Config::get('storage.{name}')
Cloude\Storage\Factory Builds a Storage adapter from a config row (dispatches on driver)
Cloude\Storage\StorageException Framework-level wrapper around \PDOException. Public readonly $sqlState, $sql, $bindings. Specialised subclasses: TableNotFoundException (42S02/42P01), ColumnNotFoundException (42S22/42703), DuplicateKeyException (23000+1062, 23505), IntegrityConstraintException (23xxx), ConnectionException (08xxx), SyntaxErrorException (42000/42601)
Cloude\Storage\Transaction begin / commit / rollback / inTransaction / depth + closure-based run(fn, $connection). Real nested transactions via SAVEPOINTs. Wraps PDO errors as StorageException
Cloude\Storage\Schema DDL emitter — produces CREATE TABLE / DROP TABLE SQL from structured arrays. Indexes (UNIQUE/INDEX), foreign keys (ON DELETE/ON UPDATE), DEFAULT NULL, composite primary keys, MySQL + Postgres dialects. Not a migration framework — feed the SQL to your existing tooling

Cloude\Markdown\…

Class Responsibility
Cloude\Markdown Frontmatter + body parser. Body rendered via Markdown\Parser by default; swappable with useParser()
Cloude\Markdown\File Disk I/O for markdown with transparent gzip (.md + .md.gz)
Cloude\Markdown\Parser In-house markdown → HTML parser. No external dependency
Cloude\Markdown\Server Serves a markdown file with 304 / canonical / gzip passthrough

Cloude\Mcp\…

Class Responsibility
Cloude\Mcp\Server MCP server (Model Context Protocol) over HTTP / JSON-RPC 2.0, with auto inputSchema validation
Cloude\Mcp\JsonRpc Constants for JSON-RPC 2.0 + MCP error codes

Cloude\Testing\… — built-in test framework (no PHPUnit dependency)

Class Responsibility
Cloude\Testing\TestCase Test base class. Lifecycle (setUp/tearDown), PHPUnit-compatible assertion surface (assertSame/assertTrue/assertInstanceOf/…), exception expectations, Cloude-specific helpers (useArrayModel, useSqliteModel, useMockModel, captureHttp, freezeTime, …)
Cloude\Testing\Assert Static assertion library used by TestCase. Each method increments an internal counter shown in the runner's summary
Cloude\Testing\Runner Discovery + execution + reporting. bin/cloude-test calls Runner::main($argv). Supports --filter=PATTERN and one or more path arguments
Cloude\Testing\DataProvider #[DataProvider('cases')] attribute — name a static method returning an iterable of arg arrays; one test invocation per row
Cloude\Testing\AssertionFailedException Thrown by Assert methods on failure. The runner catches it to flag the test as failed (vs. errored)
Cloude\Testing\MockStorage Recording wrapper around ArrayStorage for behaviour assertions ($store->received('update', times: 1))
Cloude\Mcp\McpException Structured-error throwable for tool / resource handlers

Quick start

A typical www/index.php looks like this:

Bootstrap::run wires up ob_start, the global 503 error handler, and the view base path in one call. Drop in app/config.php and you have a complete front controller in ~15 lines.

Example projects

Ready-to-run sample apps live in examples/. Each one is fully self-contained — no cross-dependencies, no Apache or nginx required, no composer install needed when running from inside this repo. From the repository root:

Folder What it shows
examples/basic/ Front-controller skeleton: routing, dynamic params, JSON echo, plain-PHP views
examples/contacts/ Form + JsonSchema validation + accent-insensitive search + fetch() from JS
examples/library/ DDD layering: Domain / Application / Infrastructure / Presentation
examples/recipes/ Standalone snippets — sitemap, JSON-LD, MCP, CLI tasks, repos

Run via Docker without installing PHP locally — see DEPLOYMENT.md.

Class reference

Cloude\Router

{name} segments are extracted into an associative array and passed as the first handler argument.

Pattern syntax:

Form Meaning
/{name} captures any non-slash segment as $params['name']
/{name?} optional — the segment and its leading / can be absent
/{name:regex} constrains the capture to regex (e.g. \d+, [a-z]{2})
/{name?:regex} optional + constrained

Examples:

Route groups stack a URL prefix onto a block of routes. Nestable.

Cloude\Input

Cloude\View

View templates use the .html.php double extension by convention — visually separates HTML-producing templates from PHP source files (controllers, models) and improves IDE highlighting. The render() / capture() methods don't enforce it; any require-able path works.

Short names inside views

include-based templates run in their own scope, so View::e() etc. need the framework namespace. Two equally supported shapes — pick the one that fits the project:

Option A — standard use statement (per-view, explicit, IDE-friendly):

Option B — declarative aliases in app/config/app.php (one declaration, every view inherits):

Bootstrap::run() reads the aliases list and calls class_alias('Cloude\<short>', '<short>') for each entry. The framework skips silently when the short name is already taken (your own classes, PHP built-ins, prior aliases) so user code is never stomped. Default config registers no aliases — the feature is strictly opt-in.

Bundled examples (examples/basic/, examples/contacts/, examples/library/) use Option A so they're explicit about every import. Real apps with many views often prefer Option B to drop the use boilerplate.

Cloude\Markdown

Supports minimal YAML frontmatter (single-line key: value pairs):

The body is rendered with the in-house Cloude\Markdown\Parser. To swap in a different engine (e.g. Parsedown if you want its full feature set):

Cloude\Markdown\Parser

Minimalist Markdown → HTML parser. Covers the editorial subset:

Block Inline
ATX headings (#######) **bold** / __bold__
Paragraphs *italic* / _italic_
Unordered / ordered lists `inline code`
Fenced code blocks (` markdown
Type Bore License
--- :---: ---:
Shotgun smooth E
Rifle rifled D

app/config/ ├── app.php # base — always loaded ├── db.php ├── mail.php ├── dev/ # active when environment is 'dev' │ └── app.php # deep-merged onto the base └── prod/ ├── app.php └── db.php json {"error": "not_found", "status": 404} apacheconf RewriteRule ^[0-9]+/assets/(.*)$ /assets/$1 [L] bash php app/cli/tasks.php # list every task php app/cli/tasks.php help content:rebuild-index # describe one php app/cli/tasks.php content:rebuild-index --country=fr --dry-run php app/cli/tasks.php content:purge-old --days=30 bash composer install composer test # cloude-test (Cloude\Testing\Runner) composer cs-check # php-cs-fixer in dry-run mode composer cs-fix # apply fixes bash git tag -a v0.15.0 -m "v0.15.0" git push origin v0.15.0 bash composer require cloude/framework bash vendor/bin/cloude-test # run tests/ (default) vendor/bin/cloude-test tests/Storage # scope to a directory vendor/bin/cloude-test --filter=Cast # regex match on ClassName::method vendor/bin/cloude-test --help # usage summary



The runner discovers `*Test.php` files recursively, instantiates every
class extending `Cloude\Testing\TestCase`, and runs each public
method whose name starts with `test`. Dots / `F` / `E` printed
PHPUnit-style; final summary lists failures and errors with stack
traces. Exit code 0 on green, 1 on anything red.

**Why ship a custom runner?** The framework's philosophy is small,
hand-rolled, no dependencies the user didn't ask for. Dropping PHPUnit
(15+ MB in `vendor/`) keeps `composer install` lean for downstream
consumers; the runner itself is < 500 LOC across `Runner.php`,
`TestCase.php`, `Assert.php` and `bin/cloude-test`. PHPUnit's API
shape (method names, attributes, lifecycle) is mirrored so the muscle
memory transfers and existing tests migrate with two `use`
substitutions.

#### Writing a test

#### Assertions

PHPUnit-compatible names (`assertSame`, `assertTrue`, etc.) are
available both as `$this->...` and `self::...` (route to the same
implementation). The full list:

| Equality        | `assertSame`, `assertNotSame`, `assertEquals`, `assertEqualsWithDelta` |
| Booleans / null | `assertTrue`, `assertFalse`, `assertNull`, `assertNotNull` |
| Containers      | `assertCount`, `assertEmpty`, `assertNotEmpty`, `assertContains`, `assertArrayHasKey`, `assertArrayNotHasKey` |
| Type            | `assertInstanceOf`, `assertNotInstanceOf`, `assertIsString` |
| Strings         | `assertStringContainsString`, `assertStringNotContainsString`, `assertStringStartsWith`, `assertStringEndsWith`, `assertMatchesRegularExpression`, `assertJson` |
| Comparison      | `assertGreaterThan`, `assertLessThan`, `assertLessThanOrEqual` |
| Filesystem      | `assertFileExists`, `assertDirectoryExists` |
| Escape hatch    | `fail($message)` |

#### Cloude-specific helpers

| Helper                                     | Purpose                                                                                  |
|--------------------------------------------|------------------------------------------------------------------------------------------|
| `useArrayModel(class, rows = [])`          | Configure a `Model` subclass with `ArrayStorage` + seed rows for the duration of the test |
| `useSqliteModel(class, createSql)`         | Same, but with an in-memory SQLite + `PdoStorage`. Returns the PDO for extra setup        |
| `useMockModel(class, rows = [])`           | Like `useArrayModel()` but the storage records every call. Returns a `MockStorage` for assertions |
| `captureHttp($handler)`                    | Run a route handler; return `['status' => …, 'body' => …]`                               |
| `assertJsonResponse($expected, $handler)`  | Capture + decode + structural compare. Optional `status:` named arg                       |
| `assertHttpException($status, $handler)`   | Catch a `Cloude\Http\HttpException`; check status; return the exception for chaining     |
| `freezeTime($when)` / `unfreezeTime()`     | Pin `DateTime::now()` to a fixed instant for deterministic time-aware tests              |
| `assertModelReceived($store, $method, times: ?int)` | Assert that a `MockStorage` got `$method` (optionally exactly `$times` times)        |
| `assertModelDidNotReceive($store, $method)` | Inverse — assert `$method` was never called                                              |
| `assertModelHas($model, $attributes)`      | Assert each attribute key in `$attributes` matches on the model                          |

**Picking a model helper:**

| Need                                                          | Helper            |
|---------------------------------------------------------------|-------------------|
| State-based test ("after doing X, the row has these fields")  | `useArrayModel`   |
| Behaviour test ("X causes a delete on PK 42")                 | `useMockModel`    |
| Tests that go through `Model::query()` (joins, raw SQL builder) | `useSqliteModel`  |

`useMockModel` is the right choice when you want to assert _how_ the
code used the storage. Don't use it for code that calls
`Model::query()` — faking the SQL builder leads to tests that pass
even when the underlying SQL is wrong. SQLite in-memory (the
`useSqliteModel` path) is fast enough that real SQL is the better
default whenever the query shape matters.

State that bleeds across tests is automatically cleared in
`setUp()` / `tearDown()`:

- `Cloude\Config::reset()` — forgets all loaded config files
- `Cloude\DateTime::clearTestNow()` — releases any frozen `now()`

## Philosophy

- **No magic**: the code you read is the code that runs. No generators, annotations or proxies.
- **Small classes**: each class fits in a file you can read in one sitting — and so can [Claude Code](https://claude.com/claude-code).
- **No required dependencies**: the core pulls nothing in. `ext-intl` is recommended for slug transliteration but not required.
- **No global state**: no container, no singletons. Static classes are just namespaces for functions.
- **AI-readable by design**: explicit APIs, no DSL, no inheritance webs. The framework is small on purpose so an agent can edit any piece without missing context.

## License

MIT - see [LICENSE](LICENSE).

All versions of framework with dependencies

PHP Build Version
Package Version
Requires php Version >=8.3
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 cloude/framework contains the following files

Loading the files please wait ...