# Windwalker PHP Framework

> The Next Generation PHP Framework

## Guides

- Mvc
  - [Admin and Forms](./guides/mvc/admin.md): So far the front end shows the data generated by the seeder. Now we build an admin area to manage it.
  - [Getting Started](./guides/mvc/getting-started.md): This tutorial covers the basic Windwalker MVC only. Advanced packages such as Unicorn and Luna are not included.
  - [Entity, Migrations and Seeders](./guides/mvc/modeling.md): In this tutorial we build a simple blog. First we create the database structure and some test data.
  - [Create Views](./guides/mvc/view.md): Next we create views to print the data in the database.
- [Rad](./guides/rad/index.md)
  - [Admin Grid](./guides/rad/admin-grid.md): Unicorn's grid generator provides a working admin list with search, filters, sorting, pagination, row selection and CRUD actions. This chapter adds product-specific fields and search.
  - [Advanced Grid Features](./guides/rad/advanced-grid.md): Unicorn's ListSelector supports custom search and filter handlers, allow-listed sorting, and batch actions.
  - [Edit Forms and Saving](./guides/rad/edit-forms.md): Unicorn's edit-view generator provides the controller and view flow for creating and updating a product. Its reusable fields include lists, dates, switches, and editors.
  - [Entities, Migrations and Seeders](./guides/rad/modeling.md): This chapter adds a Product entity and table, then registers sample products for local development.
  - [Project Setup](./guides/rad/project-setup.md): For general environment setup, see the Installation guide.
  - [Install the Unicorn Package](./guides/rad/unicorn-installation.md): The Windwalker Starter does not include Unicorn or the database and form packages used by this guide. Install them in the application root:
- [Start](./guides/start/index.md)
  - [Debugging](./guides/start/debugging.md): If you need to enter debug mode, such as viewing DB Queries, complete error messages, or want to prevent CSS/JS caching, you can enter debug mode.

## Components

- [Components](./components/index.md)
- [Attributes](./components/attributes/index.md)
  - [Available Types & Actions](./components/attributes/available-type-actions.md): Use registerAttribute() to enable an attribute class for one or more resolver targets. Native targets use the corresponding PHP Attribute::TARGET_ bit; CALLABLE is an additional Windwalker target used
  - [Miscellaneous](./components/attributes/misc.md): AttributeHandler is passed to every attribute's __invoke() method. It exposes the wrapped handler, reflection target, associated object, resolver, and options.
  - [Write Your Own Attribute Handlers](./components/attributes/write-handlers.md): An attribute handler is an invokable attribute class that receives an AttributeHandler and returns a callable. The returned callable wraps the previous handler, which is available by invoking $handler
- [Authentication](./components/authentication/index.md)
  - [Authentication Methods](./components/authentication/authentication-methods.md): An authentication method checks one source of credentials. The
  - [Results](./components/authentication/results.md): Every authentication method returns an AuthResult. The
- [Authorization](./components/authorization/index.md)
- [Cache](./components/cache/index.md)
  - [CachePool](./components/cache/cache-pool.md): CachePool implements the PSR-6 and PSR-16 interfaces. Its constructor takes a storage, a serializer, a logger, and a
  - [Serializers](./components/cache/serializers.md): A serializer converts values to the format the storage accepts, and back. Every serializer implements
  - [Storages](./components/cache/storages.md): A storage determines where cache entries are kept. Every storage implements StorageInterface. Some storages also
  - [Tagged Caches](./components/cache/tagged-pool.md): TaggedCachePool extends CachePool with tag-based invalidation. Each tag has a version. An item records the versions
- [Crypt](./components/crypt/index.md)
- [Data](./components/data/index.md)
  - [Collection](./components/data/collection.md): Most data in an application is nested. An API response contains an order,
  - [Formats](./components/data/formats.md): Applications receive structured data in many forms. A service may read
  - [Record](./components/data/record.md): An array carries no type information. When a request body or a database
- [Database](./components/database/index.md)
  - [Connections](./components/database/connections.md): A DatabaseAdapter owns a driver, and the driver owns the connection to
  - [Databases and Schemas](./components/database/databases-and-schemas.md): A database server holds several databases, and each database holds one or
  - [Events](./components/database/events.md): The adapter emits events while a query runs and when rows are fetched.
  - [Hydrators](./components/database/hydrators.md): A database returns each row as an array of column values. Application code
  - [Queries](./components/database/queries.md): Most work with the database is reading and writing rows. The adapter runs
  - [Schema Diff](./components/database/schema-diff.md): Keeping a database in step with the application is a recurring task. A
  - [Tables](./components/database/tables.md): Tables are created and changed through a TableManager. Instead of writing
  - [Writer](./components/database/writer.md): Writing rows by hand means building an INSERT or UPDATE statement,
- [Di](./components/di/index.md)
  - [Attributes](./components/di/attributes.md): The container can resolve attributes as decorators. Register each attribute for the targets where it should be
  - [Basic Usage](./components/di/basic-usage.md): Create a container with Container:
  - [Lazy Loading](./components/di/lazy.md): Windwalker DI can use PHP 8.4 lazy proxies to defer creating an object until its first property access. This is
  - [Multi Levels](./components/di/multi-levels.md): Windwalker Container supports a nested structure, you can create many children of a parent Container.
  - [Parameters](./components/di/parameters.md): Container can create a parameters structure to resolve object and dependencies.
  - [Tagged Services](./components/di/tagged-services.md): Tags are useful when one service has several fixed implementations or must build a driver variant at runtime. For
- [Dom](./components/dom/index.md)
  - [Elements](./components/dom/elements.md): Building HTML with string concatenation means every value must be escaped at
  - [Parsing and Rendering](./components/dom/parsing-and-rendering.md): Not all markup starts as element calls. Templates, rich-text editor output,
- [Edge](./components/edge/index.md)
  - [Differences from Blade](./components/edge/blade-differences.md): Edge keeps the Blade syntax for echoes, control structures, layouts,
  - [Compiled Template Cache](./components/edge/cache.md): Compiling a template means parsing its tokens and generating PHP. This
  - [Components](./components/edge/components.md): A component is a reusable piece of UI that you call with an HTML-like
  - [Extending Edge](./components/edge/extending.md): Edge is built from small parts, and each part can be extended without
  - [Layouts, Sections, and Stacks](./components/edge/layouts.md): Most pages share the same outer frame: a header, a navigation area, and
  - [Template Loaders](./components/edge/loaders.md): Edge separates two jobs: finding a template and compiling it. The loader
  - [Template Syntax](./components/edge/syntax.md): Edge templates are HTML files with two kinds of markup. Output tags such
- [Environment](./components/environment/index.md)
  - [PHP Helper](./components/environment/php-helper.md): Some code must choose a path based on the PHP runtime itself: whether
  - [Server and Platform](./components/environment/server-and-platform.md): Code that writes files, builds shell commands, or generates absolute
- [Event](./components/event/index.md)
  - [Dealers](./components/event/dealers.md): A dealer is another dispatcher that receives every event an emitter
  - [Event Objects](./components/event/events.md): An event object is the message that travels through the system. It has a
  - [Listeners and Subscribers](./components/event/listeners.md): A listener is a callable that runs when a given event is emitted. Event
  - [Observable](./components/event/observable.md): EventEmitter::observe() turns an event class into a reactive stream. Each
  - [Listener Providers](./components/event/providers.md): PSR-14 splits event handling into two roles. The dispatcher sends an event
- [Filesystem](./components/filesystem/index.md)
  - [Async Operations](./components/filesystem/async-operations.md): Some workflows read or write several files and do not need the result of
  - [File Object](./components/filesystem/file-object.md): Plain PHP file functions return booleans, do not create missing parent
  - [Iterating Files](./components/filesystem/iterating-files.md): Listing a directory with RecursiveDirectoryIterator means handling
  - [Path Collection](./components/filesystem/path-collection.md): Many features read from several roots at once, such as a theme folder,
  - [Path Utilities](./components/filesystem/path-utilities.md): Paths come from many places: configuration files, operating system
  - [Temporary Files](./components/filesystem/temp-files.md): Import jobs, PDF renderers, and archive tools often need a scratch file
- [Filter](./components/filter/index.md)
- [Form](./components/form/index.md)
  - [Choice Fields](./components/form/choices.md): Many form values come from a fixed list: a country, a category, a set of
  - [Data Lifecycle](./components/form/data.md): Form data takes a round trip. A record from storage fills the form for
  - [Defining Forms](./components/form/defining.md): A form is easy to build for two fields and hard to maintain at twenty. The names, labels, groups, and filters tend to be repeated in the view, the controller, and the save logic. A form definition kee
  - [Fields](./components/form/fields.md): A field is a PHP object that describes one control in a form. Its name and
  - [Rendering](./components/form/rendering.md): A field knows what it holds and how it is validated, but it does not decide
- [Html](./components/html/index.md)
  - [Grid](./components/html/grid.md): Admin screens often render tables whose columns are known only at runtime. A
  - [Helpers](./components/html/helpers.md): HTMLHelper is a static toolbox with two independent jobs. The first is
- [Http](./components/http/index.md)
  - [HTTP Client](./components/http/client.md): Most applications call other services: a payment gateway, an internal
  - [Messages](./components/http/messages.md): HTTP messages are the shared model of this package. A request describes
  - [Middleware](./components/http/middleware.md): Some work applies to many requests before any listener runs: checking an
  - [Output](./components/http/output.md): A PHP application sends a response in two steps: it writes the status
  - [Server](./components/http/server.md): A server accepts incoming HTTP requests, turns each one into a PSR-7
  - [Transports](./components/http/transports.md): A client describes a request, and a transport performs it. The client
- [Language](./components/language/index.md)
  - [Debugging](./components/language/debugging.md): Missing or misplaced translations are easy to overlook. A message that shows
  - [Loading Files](./components/language/loading.md): Translation texts live in files, one set per locale, so translators can work
  - [Plural Forms](./components/language/plurals.md): Languages do not pluralize in the same way. English has two forms, 1 apple
  - [Translating Strings](./components/language/translation.md): Translation in Windwalker is a lookup by key. Code asks for order.shipped,
- [Orm](./components/orm/index.md)
  - [Attributes](./components/orm/attributes.md): The ORM describes an entity with attributes. The table name, the columns, the
  - [Casting](./components/orm/casting.md): A database stores scalars, such as strings, integers, and dates in text form.
  - [Energize](./components/orm/energize.md): Entities are plain data objects, so an entity method cannot reach a service
  - [Entities](./components/orm/entities.md): An entity is the PHP object that represents one row of a table. In
  - [Events](./components/orm/events.md): Saving and deleting rows often triggers more work: filling in a timestamp,
  - [Hydration](./components/orm/hydration.md): Hydration turns a database row into an entity, and extraction turns an entity
  - [Custom Mappers](./components/orm/mappers.md): Most logic belongs to an entity, and the events in Events cover
  - [Nested Sets](./components/orm/nested-set.md): A tree of categories, menu items, or permission nodes is usually stored with a
  - [Optimistic Locking](./components/orm/optimistic-lock.md): Two requests often load the same row, change it, and save it. Without a
  - [Persisting Data](./components/orm/persisting.md): Writing data is the other half of the ORM. You can create, update, save,
  - [Querying](./components/orm/querying.md): Reading data is the most common use of the ORM. To load one row, pass a
  - [UUID](./components/orm/uuid.md): Auto-increment IDs are simple, but they come from one database sequence. Two
- [Pool](./components/pool/index.md)
  - [Connection Pool](./components/pool/connection-pool.md): Opening a connection is expensive. A pool opens connections once, keeps
  - [Connections](./components/pool/connections.md): A pool manages the lifecycle of its connections, but it does not know how
  - [Health and Lifetime](./components/pool/health-and-lifetime.md): Connections do not last forever. A database server closes idle sessions
  - [Swoole Stack](./components/pool/swoole-stack.md): In a coroutine server, many coroutines can need a connection at the same
- [Promise](./components/promise/index.md)
- [Query](./components/query/index.md)
  - [Common Table Expressions](./components/query/cte.md): A common table expression (CTE) names an intermediate result and lets the
  - [Cursor Pagination](./components/query/cursor-pagination.md): Offset paging reads and discards every row before the offset, so later pages
  - [Raw SQL and Bindings](./components/query/expressions.md): The builder quotes every name and binds every value, so most statements
  - [Grammars and Escaper](./components/query/grammars.md): A builder describes a statement without knowing the target database. The
  - [Iteration](./components/query/iteration.md): Some jobs read far more rows than fit in memory. An export, a data migration
  - [Joins](./components/query/join.md): A normalized schema keeps posts, authors and categories in separate tables.
  - [JSON](./components/query/json.md): Many applications store flexible settings or metadata in a JSON column. The
  - [Method Index](./components/query/methods.md): This page lists the public methods of the Query class, grouped by topic.
  - [Rendering and Debugging](./components/query/rendering.md): A builder object is a description of a statement. Before it runs, the
  - [Selecting Data](./components/query/select.md): Reading rows is the most common use of the builder. Naming the columns,
  - [Upsert](./components/query/upsert.md): An upsert inserts a row, or updates the existing row when a unique key
  - [Conditions](./components/query/where.md): Conditions decide which rows a statement reads or changes. The builder turns
  - [Writing Data](./components/query/writing.md): The builder also creates INSERT, UPDATE and DELETE statements. It uses
- [Queue](./components/queue/index.md)
  - [Drivers](./components/queue/drivers.md): A driver is the storage backend behind a Queue. Every driver implements
  - [Enqueuer](./components/queue/enqueuer.md): An Enqueuer is a loop that creates jobs instead of consuming them. Use
  - [Failed Jobs](./components/queue/failed-jobs.md): A job that keeps failing after all its attempts is removed from the queue.
  - [Workers](./components/queue/workers.md): A Worker is the long-running process that takes messages from the queue
  - [Writing Jobs](./components/queue/writing-jobs.md): A job is the unit of work that a worker runs later. Keep a job small and
- [Reactor](./components/reactor/index.md)
  - [Coroutine Server](./components/reactor/coroutine-server.md): SwooleCoroutineServer runs Swoole's coroutine HTTP server in a single
  - [HTTP](./components/reactor/http.md): An HTTP server turns each Swoole request into a PSR-7 request, runs it
  - [Memory Tables](./components/reactor/memory-tables.md): Worker processes do not share variables. Memory tables are a fixed-schema
  - [Servers](./components/reactor/servers.md): A Reactor server wraps one Swoole server. It owns the listening socket,
  - [Sub-servers and Protocols](./components/reactor/sub-servers.md): One Swoole server listens on one port. A sub-server adds a listener on
  - [WebSocket](./components/reactor/websocket.md): A WebSocket server sees each client as a connection, identified by a
- [Renderer](./components/renderer/index.md)
  - [Composite Renderer](./components/renderer/composite.md): Applications often keep templates in more than one engine, for example during a migration from PHP templates to
  - [Engine Renderers](./components/renderer/engines.md): Each template engine has an adapter class. The adapter builds the engine from your options, then renders a
- [Scalars](./components/scalars/index.md)
  - [Array Object](./components/scalars/array-object.md): ArrayObject wraps a native array and provides methods for filtering,
  - [String Object](./components/scalars/string-object.md): StringObject wraps a string together with the encoding used to read it.
- [Session](./components/session/index.md)
  - [Bridges](./components/session/bridges.md): A session has to be loaded when it starts, kept in memory while the request
  - [Cookies](./components/session/cookies.md): A session is found again on the next request through its ID. The ID is
  - [Flash Messages](./components/session/flash-messages.md): A flash message is a short message that is shown once. The classic case is
  - [Storage Handlers](./components/session/handlers.md): A bridge decides when the session is loaded and saved. A handler decides
  - [Security](./components/session/security.md): A session is trust. The server decides who a visitor is based on the ID the
- [Srp](./components/srp/index.md)
  - [Configuration](./components/srp/configuration.md): Both SRPServer and SRPClient extend the same base class and share
  - [JavaScript](./components/srp/javascript.md): The JavaScript package, @windwalker-io/srp, is a TypeScript
  - [Protocol](./components/srp/protocol.md): SRP is a challenge-response protocol. Both sides contribute random
  - [Sample Flow](./components/srp/sample-flow.md): This page runs the full SRP flow in one script: registration, login
- [Stream](./components/stream/index.md)
  - [Caching Stream](./components/stream/caching-stream.md): CachingStream wraps a source that you can read only once, or that is slow
  - [Gz Stream](./components/stream/gz-stream.md): GzStream reads and writes gzip-compressed files through the same stream
  - [Stream](./components/stream/stream.md): Stream is the general-purpose stream. It wraps a PHP resource, which can be
  - [String Stream](./components/stream/string-stream.md): StringStream is a stream that holds a string in memory. Unlike Stream,
- [Test](./components/test/index.md)
  - [Accessing Members](./components/test/accessors.md): Some classes keep state in private or protected properties, and some
  - [Assertions](./components/test/assertions.md): Framework tests often compare generated text: SQL statements, HTML
  - [Database Tests](./components/test/database.md): Tests for database code need a real database that starts from a known schema.
  - [Swoole Tests](./components/test/swoole.md): Some Windwalker code runs asynchronously on the Swoole event loop, such as
- [Uri](./components/uri/index.md)
  - [Helpers](./components/uri/helpers.md): UriHelper and UriNormalizer are static classes that hold the low-level
  - [URI Template](./components/uri/uri-template.md): UriTemplate implements RFC 6570,
  - [Uri](./components/uri/uri.md): Uri is the main class of the package. It parses a URL string into its
- [Utilities](./components/utilities/index.md)
  - [Array Sync](./components/utilities/arr-sync.md): Many forms edit a list that is stored elsewhere: tags on a post, members
  - [Arr](./components/utilities/arr.md): Arr is a static helper for arrays and objects. Configuration files,
  - [Assert](./components/utilities/assert.md): Argument and invariant checks are often written as a plain if followed
  - [Attributes](./components/utilities/attributes.md): PHP attributes attach metadata to classes, properties, methods, and
  - [Enum Metadata](./components/utilities/enum-metadata.md): A native PHP enum holds a value and a name, but nothing for display. A
  - [Exceptions](./components/utilities/exceptions.md): The utilities in this package signal problems with exceptions of their own,
  - [Helpers](./components/utilities/helpers.md): The utilities package provides a set of global functions in the Windwalker
  - [Identifiers](./components/utilities/identifiers.md): Two small helpers cover identifiers that live for the length of a process.
  - [Iterators](./components/utilities/iterators.md): Lists of rows are often transformed in several steps: filter the active
  - [Object Helpers](./components/utilities/object-helpers.md): Three helpers work with objects at the level of their state and identity.
  - [Str](./components/utilities/str.md): Str is a static helper for strings. Many native PHP string functions
  - [Text Transforms](./components/utilities/text-transforms.md): Three kinds of text work appear again and again: filling a fixed text with
  - [Type Cast](./components/utilities/type-cast.md): Input from a form, a query string, or a JSON body arrives as strings or

## Framework

- [HtmlFrame](./framework/html-frame.md)

## Other

- [Documentation](./index.md)
