Download the PHP package migears/dao without Composer

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

migears/dao

Version

Minimalist DAO layer — connects SQL and Domain with zero abstraction.

Background: miGears is the open-source successor of TinyGears, a self-developed PHP framework. It was renamed and open-sourced recently because the name TinyGears is already taken in the open-source community.

Philosophy

DAO design principle

The API is shaped around one convention:

The package is therefore Domain-oriented rather than row-oriented. It stops short of a full Repository: there is no identity map and no collection semantics — a DAO reads and writes one table, and cross-table work is the application's job.

Boundaries

In scope

Not in scope (by design)

Installation

Requires: PHP 8.1+, ext-pdo, psr/log, migears/sql, migears/domain, migears/cache, migears/utils.

Constructor Contract

Every DAO constructor is explicit and follows a fixed argument order:

Argument Type Required Meaning
$pdo PDO always database connection
$logger Psr\Log\LoggerInterface always logger — inject it explicitly, never rely on a silent default
$cache MiGears\Cache\CacheInterface only when cacheable cache layer, only for DAOs using CachedDao

A DAO constructor takes at least two arguments (pdo, logger). If the DAO is cacheable (uses CachedDao), add the third cache argument:

$logger is never defaulted inside a DAO — it is always injected by the caller. This keeps every DAO's construction explicit, testable, and uniform across the codebase.

table(), idColumn() and domainClass() are declared abstract by the trait, so a DAO that forgets any of them fails to compile rather than misbehaving at run time; there is no separate "define the properties" step.

Quick Start

Define a DAO

CRUD Operations

Pagination

Pagination is opt-in: compose OffsetPagination or CursorPagination on top of SingleTableDao, whichever matches the query strategy.

Offset — page numbers with an exact total (MiGears\Utils\Paginator):

Cursor — keyset / "load more" without a total (MiGears\Utils\FlowPaginator):

CursorPagination reads one extra row to decide hasMore instead of running a COUNT(*), and orders by the primary key descending; the cursor is that key, so the Domain must expose it publicly.

With Domain Objects

Pick the write that matches the intent — save() first, and reach for the lower-level methods only when they earn it:

Patching a few columns

patch() reads the values straight off the Domain it is handed — it never rebuilds or copies it. Pass a Domain that already carries the values you want written, and name the columns to persist:

This is what separates patch() from save(): a Domain built from a request often carries values for columns that are not yours to write, and patch() writes only the columns you name. Naming no column throws, and a name that is not a column of the Domain throws too.

Using CachedDao

Both traits return hydrated Domain objects; CachedDao additionally caches the primary-key lookups (getById / getByIds). getAll() and count() always query the database — only the primary-key reads are cached. Pagination is not part of the cache layer: compose OffsetPagination / CursorPagination on the cacheable DAO if you need it. CachedDao depends only on CacheInterface and the SingleTableDao contract — it references no migears/sql type, so all SQL and its exceptions stay in SingleTableDao. A cache hit is returned only when it really is a Domain of the DAO's class; a stale or foreign value is logged as a warning, deleted, and re-read from the database.

Write operations (insert / update / delete) automatically invalidate the primary-key cache entry. To clear additional cache keys (e.g. lookups by secondary indexes like byEmail), override the deleteCacheFor() hook:

deleteCacheFor() receives the fresh Domain object (an uncached read taken after the write) so the hook can inspect current field values. It receives null when the record no longer exists (e.g. after a delete).

insert() preserves a caller-supplied primary key — pass idColumn in the data array for UUID or application-generated keys. When omitted, the auto-increment ID from the database is used.

Custom Primary Key

Complex Queries

For queries beyond simple CRUD, use the underlying SqlBuilder:

Complex joins and multi-table queries also belong in the DAO — all database access logic is encapsulated here. The Service layer should never touch the database directly.

Type Contract (with Domain)

SingleTableDao / CachedDao hand raw rows straight to Domain::fromArray() — hydrate() (defined in SingleTableDao, reused by CachedDao) calls fromArray($row) on the class returned by domainClass(), with no hydration magic. The Domain layer performs zero coercion: PHP 8.x strict typed named arguments bind each value to the declared constructor type, so a missing key, an extra key, or a type mismatch throws a native \Error / \TypeError (see migears/domain "Type Contract").

The DAO adds no casting of its own — no column-type map, no intval(). Native types come from PDO itself: since PHP 8.1 it returns real int / float for numeric columns, under both emulated and native prepares. So an int column arrives as a genuine PHP int and a nullable column as null, with no normalizing step in this layer. The SQL layer likewise only executes queries and returns raw arrays.

See migears/domain "Type Contract" for the caveats (DECIMAL stays string, TINYINT(1) is int, never enable PDO::ATTR_STRINGIFY_FETCHES) and why the strict binding is deliberate rather than something to paper over with casts.

Architecture

DAO is the glue layer of miGears' three-layer data architecture:

Why a Trait?

  1. No inheritance lock-in — DAO classes can extend whatever they need
  2. Explicit constructor — user controls PDO, logger (and cache for CachedDao) injection; no hidden defaults
  3. Readable — all methods are visible in the class, no hidden base class methods

License

MIT


migears/dao

Version

极简 DAO 层 — 连接 SQL 和 Domain,零抽象。

设计哲学

DAO 设计原则

API 的形状只为一条约定服务:

因此本包是「面向 Domain」而非「面向行」的。它并未做成完整 Repository:没有 identity map,也没有集合语义——DAO 只读写一张表,跨表编排归应用。

边界

范围内

范围外(刻意不做)

安装

要求:PHP 8.1+、ext-pdo、psr/log、migears/sql、migears/domain、migears/cache、migears/utils。

构造契约

每个 DAO 构造函数都是显式的,且遵循固定的参数顺序:

参数 类型 是否必须 含义
$pdo PDO 始终 数据库连接
$logger Psr\Log\LoggerInterface 始终 日志器——显式注入,绝不静默使用默认实现
$cache MiGears\Cache\CacheInterface 仅 cacheable 时 缓存层,仅用于使用了 CachedDao 的 DAO

每个 DAO 构造函数至少接收两个参数(pdo、logger)。如果 DAO 是 cacheable 的 (使用了 CachedDao),则需额外接收第三个 cache 参数:

$logger 在 DAO 内部绝不会被默认填充——始终由调用方注入。 这让每个 DAO 的构造过程保持显式、可测试,并在整个代码库中保持一致。

table()、idColumn() 与 domainClass() 由 trait 声明为 abstract, DAO 漏掉任何一个都无法通过编译,而不是到运行时才出错; 也不再需要单独声明属性。

快速开始

定义 DAO

CRUD 操作

分页

分页是可选的:在 SingleTableDao 之上按查询策略组合 OffsetPagination 或 CursorPagination 之一。

偏移分页 —— 页码 + 精确总数(MiGears\Utils\Paginator):

游标分页 —— keyset / 「加载更多」,无总数(MiGears\Utils\FlowPaginator):

CursorPagination 用多取一行来判断 hasMore,不执行 COUNT(*);按主键 降序排列,游标就是该主键,因此 Domain 必须公开暴露它。

配合 Domain 对象

按意图选择写方法——首选 save(),更低层的方法只在确有理由时才用:

局部更新(patch)

patch() 直接从交给它的 Domain 上取值——不会重建、也不会复制它。给它一个已带着待写入值的 Domain,再点名要落库的列:

这正是 patch() 与 save() 的分野:从请求构造出的 Domain 常带着一些不归你写的列的值,而 patch() 只写你点名的那些列。不点名任何列会抛异常,点名了不属于该 Domain 的列同样抛异常。

使用 CachedDao

两个 trait 都返回 已 hydrate 的 Domain 对象;CachedDao 额外为按主键的 读取(getById / getByIds)加上缓存层。getAll() 与 count() 始终查询 数据库——只有按主键的读取走缓存。分页不属于缓存层:需要时在 cacheable DAO 上另行组合 OffsetPagination / CursorPagination。CachedDao 只依赖 CacheInterface 与 SingleTableDao 的契约——不引用任何 migears/sql 类型, SQL 及其异常都留在 SingleTableDao。缓存命中只在该值确实属于本 DAO 的 Domain 类时才返回;陈旧或异类的缓存值会被记一条 warning、从缓存中删除, 再重新查库。

写操作(insert / update / delete)会自动失效主键缓存。如需清理 额外的缓存键(例如按二级索引查找的 byEmail),重写 deleteCacheFor() 钩子即可:

deleteCacheFor() 收到的是新鲜读出的 Domain 对象(写操作后绕过缓存 重新读取),因此钩子可以检查最新的字段值。记录已不存在时(例如 delete 之后)收到 null。

insert() 会保留调用方传入的主键值——UUID 或应用生成的主键只需在 data 数组中带上 idColumn 字段即可。不传时使用数据库返回的自增 ID。

自定义主键

复杂查询

简单 CRUD 之外的查询,使用底层的 SqlBuilder:

复杂的关联查询和多表查询同样应放在 DAO 中 — 所有数据访问逻辑都封装在 DAO 层,Service 层不应直接操作数据库。

类型契约(与 Domain 衔接)

SingleTableDao / CachedDao 将原始行直接交给 Domain::fromArray() — hydrate()(定义在 SingleTableDao,CachedDao 复用)即对 domainClass() 返回的类调用 fromArray($row),不做任何 hydration 魔法。Domain 层零类型转换:PHP 8.x 强类型命名参数把每个值绑定到 构造声明的类型,缺键、多键或类型不匹配都会抛原生 \Error / \TypeError (参见 migears/domain「类型契约」)。

DAO 自身不做任何 cast — 没有列类型映射,也没有 intval()。原生类型来自 PDO 本身:PHP 8.1 起,数字列在结果集中即返回真正的 int / float,模拟预处理 与原生预处理皆然。因此 int 列到达时就是真正的 PHP int,可空列为空时就是 null,本层无需任何归一化步骤。SQL 层同样只负责执行查询并返回原始数组。

关于注意事项(DECIMAL 保持 string、TINYINT(1) 是 int、切勿开启 PDO::ATTR_STRINGIFY_FETCHES),以及强类型绑定为何是刻意设计而非需要用 cast 抹平的东西,参见 migears/domain「类型契约」。

架构

DAO 是 miGears 三层数据架构的胶水层:

为什么用 Trait?

  1. 不受继承锁定 — DAO 类可以继承任何需要的父类
  2. 构造函数显式 — 用户控制 PDO、logger(以及 CachedDao 的 cache)注入,没有隐藏的默认值
  3. 可读性好 — 所有方法都在类里可见,没有隐藏的基类方法

许可证

MIT


All versions of dao with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
ext-pdo Version *
psr/log Version ^3.0
migears/sql Version ^2.0
migears/domain Version ^2.0
migears/cache Version ^2.0
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 migears/dao contains the following files

Loading the files please wait ...