prisma-php 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/01-getting-started/authentication.md +280 -0
- package/dist/docs/01-getting-started/caching.md +346 -0
- package/dist/docs/01-getting-started/components.md +589 -0
- package/dist/docs/01-getting-started/error-handling.md +359 -0
- package/dist/docs/01-getting-started/fetching-data.md +637 -0
- package/dist/docs/01-getting-started/file-manager.md +307 -0
- package/dist/docs/01-getting-started/index.md +142 -0
- package/dist/docs/01-getting-started/installation.md +18 -0
- package/dist/docs/01-getting-started/layouts-and-pages.md +289 -0
- package/dist/docs/01-getting-started/metadata-and-og-images.md +228 -0
- package/dist/docs/01-getting-started/prisma-php-orm.md +374 -0
- package/dist/docs/01-getting-started/project-structure.md +328 -0
- package/dist/docs/01-getting-started/pulsepoint.md +434 -0
- package/dist/docs/01-getting-started/route-handlers.md +344 -0
- package/dist/docs/01-getting-started/upgrading.md +172 -0
- package/dist/docs/index.md +243 -0
- package/package.json +16 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Authentication
|
|
3
|
+
description: Learn how Prisma PHP authentication works so AI agents can generate route protection, sessions, RBAC, credentials auth, and social auth code using the documented framework model.
|
|
4
|
+
related:
|
|
5
|
+
title: Related docs
|
|
6
|
+
description: Read the official Prisma PHP authentication docs before generating or editing auth code.
|
|
7
|
+
links:
|
|
8
|
+
- /docs/auth-get-started
|
|
9
|
+
- /docs/credentials
|
|
10
|
+
- /docs/state-manager-auth
|
|
11
|
+
- /docs/fetch-function
|
|
12
|
+
- /docs/route-php
|
|
13
|
+
- /docs/php-validator
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Prisma PHP authentication should be implemented from the documented Prisma PHP auth model, not from assumptions copied from Laravel guards, NextAuth, Passport, Sanctum, or generic custom JWT middleware.
|
|
17
|
+
|
|
18
|
+
If a task involves login, registration, route protection, role checks, route privacy defaults, session payload updates, credentials auth, OAuth providers, or auth-aware frontend interactions, AI agents should read the relevant auth docs first and keep the implementation aligned with the installed Prisma PHP version.
|
|
19
|
+
|
|
20
|
+
## AI rule: read the auth docs first
|
|
21
|
+
|
|
22
|
+
Before generating, editing, or reviewing auth-related code, use this order:
|
|
23
|
+
|
|
24
|
+
1. Read `./prisma-php.json`.
|
|
25
|
+
2. Read the installed local auth docs in `node_modules/prisma-php/dist/docs`.
|
|
26
|
+
3. Read this `authentication.md` file.
|
|
27
|
+
4. Inspect `src/Lib/Auth/AuthConfig.php` when present.
|
|
28
|
+
5. Inspect the current auth-related route tree under `src/app`.
|
|
29
|
+
6. Inspect the Prisma schema and generated ORM classes if the auth flow reads or writes users.
|
|
30
|
+
7. Inspect Prisma PHP core internals only when the docs do not answer the task.
|
|
31
|
+
|
|
32
|
+
Do not assume another framework’s auth abstractions apply directly.
|
|
33
|
+
|
|
34
|
+
## Read this doc when you need
|
|
35
|
+
|
|
36
|
+
- **route privacy defaults, `AuthConfig.php`, JWT session lifecycle, `Auth::signIn(...)`, `Auth::signOut(...)`, `refreshUserSession(...)`, route RBAC, or provider overview** → official `auth-get-started`
|
|
37
|
+
- **email/password registration, login, password hashing, CSRF-aware credential flow, or user/role schema design** → official `credentials`
|
|
38
|
+
- **social login, provider credentials, callback route handling, account linking, or OAuth account schema** → official `state-manager-auth`
|
|
39
|
+
|
|
40
|
+
## Core auth model AI should follow
|
|
41
|
+
|
|
42
|
+
Prisma PHP documents authentication around a central auth configuration plus framework-managed session handling.
|
|
43
|
+
|
|
44
|
+
The official docs describe these major concepts:
|
|
45
|
+
|
|
46
|
+
- `AuthConfig.php` is the central place for defining route protection strategy and role-based route rules
|
|
47
|
+
- sessions are managed through Prisma PHP auth helpers rather than ad hoc cookie code
|
|
48
|
+
- `Auth::signIn(...)` creates the session payload
|
|
49
|
+
- `Auth::signOut(...)` ends the session and can redirect
|
|
50
|
+
- `refreshUserSession(...)` updates the active session payload when user permissions or profile data change
|
|
51
|
+
- route-level RBAC and function-level access control are separate but complementary concerns
|
|
52
|
+
|
|
53
|
+
## Security strategy
|
|
54
|
+
|
|
55
|
+
Prisma PHP supports two top-level route privacy strategies in `src/Lib/Auth/AuthConfig.php`.
|
|
56
|
+
|
|
57
|
+
### 1. Opt-in privacy (public by default)
|
|
58
|
+
|
|
59
|
+
Use this model when most routes are public and only a few pages should require login.
|
|
60
|
+
|
|
61
|
+
Typical fit:
|
|
62
|
+
|
|
63
|
+
- marketing sites
|
|
64
|
+
- blogs
|
|
65
|
+
- public directories with a small private dashboard
|
|
66
|
+
|
|
67
|
+
Mental model:
|
|
68
|
+
|
|
69
|
+
- routes are public by default
|
|
70
|
+
- specific private routes are listed explicitly
|
|
71
|
+
|
|
72
|
+
### 2. Opt-out privacy (private by default)
|
|
73
|
+
|
|
74
|
+
Use this model when most routes should require authentication and only a few entry points are public.
|
|
75
|
+
|
|
76
|
+
Typical fit:
|
|
77
|
+
|
|
78
|
+
- SaaS dashboards
|
|
79
|
+
- admin panels
|
|
80
|
+
- internal applications
|
|
81
|
+
|
|
82
|
+
Mental model:
|
|
83
|
+
|
|
84
|
+
- routes are private by default
|
|
85
|
+
- specific public routes are whitelisted explicitly
|
|
86
|
+
|
|
87
|
+
## Auth lifecycle
|
|
88
|
+
|
|
89
|
+
### Sign in
|
|
90
|
+
|
|
91
|
+
Use `Auth::signIn(...)` after credentials or provider identity are validated.
|
|
92
|
+
|
|
93
|
+
The session payload should contain the user data your app needs for identity and authorization decisions, commonly including:
|
|
94
|
+
|
|
95
|
+
- `id`
|
|
96
|
+
- `role`
|
|
97
|
+
|
|
98
|
+
Do not invent a separate session writer when the framework already documents `Auth::signIn(...)`.
|
|
99
|
+
|
|
100
|
+
### Sign out
|
|
101
|
+
|
|
102
|
+
Use `Auth::signOut(...)` to destroy the session and invalidate the client cookie.
|
|
103
|
+
|
|
104
|
+
When the flow needs a post-logout redirect, use the documented redirect argument instead of custom manual cookie clearing.
|
|
105
|
+
|
|
106
|
+
### Live session refresh
|
|
107
|
+
|
|
108
|
+
Use `refreshUserSession(...)` when a currently signed-in user’s auth payload must change immediately, such as:
|
|
109
|
+
|
|
110
|
+
- role promotion or demotion
|
|
111
|
+
- profile data updates included in the auth payload
|
|
112
|
+
- account status changes that should take effect without forcing a new login
|
|
113
|
+
|
|
114
|
+
Do not force logout/login loops for cases the framework already handles with a silent session refresh.
|
|
115
|
+
|
|
116
|
+
## Access control model
|
|
117
|
+
|
|
118
|
+
Prisma PHP has at least two auth protection layers that AI should keep separate.
|
|
119
|
+
|
|
120
|
+
### Route-level protection
|
|
121
|
+
|
|
122
|
+
Use auth config to protect entire routes or route groups.
|
|
123
|
+
|
|
124
|
+
This is the right place for:
|
|
125
|
+
|
|
126
|
+
- dashboard-only pages
|
|
127
|
+
- admin sections
|
|
128
|
+
- authenticated profile/account pages
|
|
129
|
+
- public route allowlists in private-default apps
|
|
130
|
+
|
|
131
|
+
### Function-level protection
|
|
132
|
+
|
|
133
|
+
Use `#[Exposed(allowedRoles: [...])]` when frontend code calls PHP functions directly and specific roles must be enforced at the function boundary.
|
|
134
|
+
|
|
135
|
+
This is the right place for:
|
|
136
|
+
|
|
137
|
+
- destructive admin-only actions
|
|
138
|
+
- privileged inline mutations
|
|
139
|
+
- page-local operations triggered from PulsePoint UIs
|
|
140
|
+
|
|
141
|
+
Do not rely only on frontend hiding or route visibility when a backend callable function still needs authorization.
|
|
142
|
+
|
|
143
|
+
## Role model
|
|
144
|
+
|
|
145
|
+
The official auth docs describe roles as type-safe and defined in auth configuration.
|
|
146
|
+
|
|
147
|
+
AI should preserve the project’s existing role vocabulary and avoid inventing mixed casing or alternate role names unless the user explicitly asks for them.
|
|
148
|
+
|
|
149
|
+
Examples commonly shown in docs:
|
|
150
|
+
|
|
151
|
+
- `Admin`
|
|
152
|
+
- `User`
|
|
153
|
+
|
|
154
|
+
When backend functions are protected with `#[Exposed(allowedRoles: [...])]`, keep those role names aligned with the same project role model.
|
|
155
|
+
|
|
156
|
+
## Credentials authentication
|
|
157
|
+
|
|
158
|
+
The credentials docs describe the classic email/password flow as a full-stack Prisma PHP pattern where backend logic and form UI can live together in route files.
|
|
159
|
+
|
|
160
|
+
### Schema expectations
|
|
161
|
+
|
|
162
|
+
For credentials auth, the docs show a user model with fields such as:
|
|
163
|
+
|
|
164
|
+
- `email`
|
|
165
|
+
- `password`
|
|
166
|
+
- `emailVerified`
|
|
167
|
+
- role relation fields
|
|
168
|
+
|
|
169
|
+
The example also includes a `UserRole` model so role names can support RBAC-oriented auth flows.
|
|
170
|
+
|
|
171
|
+
### Registration pattern
|
|
172
|
+
|
|
173
|
+
The documented registration flow uses:
|
|
174
|
+
|
|
175
|
+
- a route such as `src/app/auth/register/index.php`
|
|
176
|
+
- `#[Exposed]` to allow the frontend to call the PHP function directly
|
|
177
|
+
- validation and normalization before persistence
|
|
178
|
+
- password hashing before storing the user
|
|
179
|
+
- a redirect to the login page after successful registration
|
|
180
|
+
|
|
181
|
+
### Login pattern
|
|
182
|
+
|
|
183
|
+
The documented login flow uses:
|
|
184
|
+
|
|
185
|
+
- a route such as `src/app/auth/login/index.php`
|
|
186
|
+
- a user lookup through Prisma ORM
|
|
187
|
+
- `password_verify(...)` for password comparison
|
|
188
|
+
- `Auth::signIn(...)` with the session payload
|
|
189
|
+
- a redirect after successful sign-in
|
|
190
|
+
|
|
191
|
+
### Validation rule
|
|
192
|
+
|
|
193
|
+
When generating credentials auth, do not trust raw request data.
|
|
194
|
+
|
|
195
|
+
For backend validation and normalization, default to Prisma PHP’s validation layer rather than browser-only checks. In this docs set, that means using the documented validation guidance alongside `PP\Validator`-style server validation patterns from the rest of the local docs.
|
|
196
|
+
|
|
197
|
+
## Social authentication
|
|
198
|
+
|
|
199
|
+
The social auth docs describe provider-based authentication using framework helpers and provider classes.
|
|
200
|
+
|
|
201
|
+
### Schema expectations
|
|
202
|
+
|
|
203
|
+
For provider auth, the docs show:
|
|
204
|
+
|
|
205
|
+
- a `User` model
|
|
206
|
+
- an `Account` model that stores provider identity and tokens
|
|
207
|
+
- a unique provider/provider-account pairing
|
|
208
|
+
|
|
209
|
+
This means AI should not generate social auth code without also checking whether the schema already supports provider accounts.
|
|
210
|
+
|
|
211
|
+
### Environment credentials
|
|
212
|
+
|
|
213
|
+
Provider credentials belong in `.env` using provider-specific auth keys.
|
|
214
|
+
|
|
215
|
+
Do not hardcode provider secrets in route files.
|
|
216
|
+
|
|
217
|
+
### Callback route pattern
|
|
218
|
+
|
|
219
|
+
The docs describe a dynamic auth handler route that handles both login redirection and callback processing.
|
|
220
|
+
|
|
221
|
+
Keep the documented route pattern instead of inventing custom callback plumbing.
|
|
222
|
+
|
|
223
|
+
## Prisma ORM workflow for auth tasks
|
|
224
|
+
|
|
225
|
+
When the task involves auth schema updates, do not confuse ORM changes with project updates.
|
|
226
|
+
|
|
227
|
+
Use this order:
|
|
228
|
+
|
|
229
|
+
1. update `prisma/schema.prisma` as needed
|
|
230
|
+
2. run `npx prisma migrate dev` when the schema changes and the database must be updated
|
|
231
|
+
3. run `npx ppo generate` so generated PHP ORM classes match the schema
|
|
232
|
+
4. then implement the PHP auth flow that depends on those classes
|
|
233
|
+
|
|
234
|
+
Do **not** use `npx pp update project -y` as the default response to auth schema changes.
|
|
235
|
+
|
|
236
|
+
## Route placement guidance
|
|
237
|
+
|
|
238
|
+
Common auth route examples from the official docs include:
|
|
239
|
+
|
|
240
|
+
- `src/app/auth/register/index.php`
|
|
241
|
+
- `src/app/auth/login/index.php`
|
|
242
|
+
- a dynamic provider callback route under an auth-related segment
|
|
243
|
+
|
|
244
|
+
If the user asks for a normal auth page, prefer `index.php`.
|
|
245
|
+
|
|
246
|
+
If the user asks for a direct callback or handler-only route, use the documented dynamic auth handler pattern.
|
|
247
|
+
|
|
248
|
+
## PulsePoint and auth
|
|
249
|
+
|
|
250
|
+
When auth UI is interactive, Prisma PHP’s normal full-stack pattern still applies:
|
|
251
|
+
|
|
252
|
+
- use PulsePoint for local reactive state and UI feedback
|
|
253
|
+
- use `pp.fetchFunction(...)` when the page should call PHP directly
|
|
254
|
+
- expose callable PHP functions with `#[Exposed]`
|
|
255
|
+
- enforce final validation and authorization on the PHP side
|
|
256
|
+
|
|
257
|
+
Do not replace the documented Prisma PHP auth flow with a custom SPA-only auth architecture unless the user explicitly wants a different design.
|
|
258
|
+
|
|
259
|
+
## AI rules for auth tasks
|
|
260
|
+
|
|
261
|
+
- read the auth docs before generating auth code
|
|
262
|
+
- do not invent custom middleware layers when `AuthConfig.php` already defines route protection strategy
|
|
263
|
+
- do not invent alternate session storage when the framework already provides documented auth helpers
|
|
264
|
+
- do not skip schema review for credentials or provider-based auth
|
|
265
|
+
- do not hardcode provider secrets in source code
|
|
266
|
+
- do not rely on frontend checks as the final authorization layer
|
|
267
|
+
- keep route-level protection and function-level protection distinct
|
|
268
|
+
- keep role names aligned with the project’s actual role model
|
|
269
|
+
- when using `#[Exposed]`, add role restrictions for privileged actions when required
|
|
270
|
+
- when schema changes are required, migrate first and generate PHP classes second
|
|
271
|
+
|
|
272
|
+
## Suggested file name
|
|
273
|
+
|
|
274
|
+
Use this file name:
|
|
275
|
+
|
|
276
|
+
```txt
|
|
277
|
+
authentication.md
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
It is clear, predictable, and consistent with the existing local docs such as `components.md`, `fetching-data.md`, and `route-handlers.md`.
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Caching
|
|
3
|
+
description: Learn how to cache pages and responses in Prisma PHP with `CacheHandler`, when to invalidate cached output, and when AI agents should inspect the core cache class for framework-level decisions.
|
|
4
|
+
related:
|
|
5
|
+
title: Next Steps
|
|
6
|
+
description: Learn more about the Prisma PHP cache APIs and route-level cache control.
|
|
7
|
+
links:
|
|
8
|
+
- /docs/cache-handler
|
|
9
|
+
- /docs/index-php
|
|
10
|
+
- /docs/route-php
|
|
11
|
+
- /docs/pages-and-layouts
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Caching is a technique for storing the result of work so that future requests can be served faster without repeating the same database queries and rendering logic.
|
|
15
|
+
|
|
16
|
+
In Prisma PHP, caching is documented around **`CacheHandler`**, which provides a **file-based cache layer** that can serve **static HTML snapshots** to reduce TTFB (Time To First Byte). Unlike Next.js Cache Components, Prisma PHP’s documented cache model is not based on `use cache`, Suspense streaming, or partial prerendering. It is based on environment settings, route-level overrides, and explicit cache invalidation.
|
|
17
|
+
|
|
18
|
+
## AI rule: read the cache docs first
|
|
19
|
+
|
|
20
|
+
Before generating, editing, or reviewing Prisma PHP cache-related code, use this order:
|
|
21
|
+
|
|
22
|
+
1. Read `./prisma-php.json`.
|
|
23
|
+
2. Read the installed local docs in `node_modules/prisma-php/dist/docs`.
|
|
24
|
+
3. Read this `caching.md` file.
|
|
25
|
+
4. Inspect the current route tree under `src/app`.
|
|
26
|
+
5. Inspect nearby mutation flows that may need cache invalidation.
|
|
27
|
+
6. Inspect Prisma PHP core internals only when the docs do not answer the task clearly.
|
|
28
|
+
|
|
29
|
+
Do not assume Next.js, Laravel response cache packages, Symfony HTTP cache, or generic PSR cache habits map directly to Prisma PHP.
|
|
30
|
+
|
|
31
|
+
## Where the core cache file lives
|
|
32
|
+
|
|
33
|
+
The Prisma PHP cache core file lives in:
|
|
34
|
+
|
|
35
|
+
```txt
|
|
36
|
+
vendor/tsnc/prisma-php/src/CacheHandler.php
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This file is useful when AI needs to make a **more detailed framework-level decision** that is not already answered by the installed docs.
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
|
|
43
|
+
- confirming the exact available methods and property names
|
|
44
|
+
- verifying how TTL fallback is resolved internally
|
|
45
|
+
- checking how cache files are named or mapped to URIs
|
|
46
|
+
- understanding how route invalidation is normalized
|
|
47
|
+
- verifying write behavior, locking, and file-system assumptions
|
|
48
|
+
- debugging framework-level cache behavior that looks inconsistent with the docs
|
|
49
|
+
|
|
50
|
+
For normal app work, prefer the docs first and inspect `CacheHandler.php` only when the task depends on internal behavior.
|
|
51
|
+
|
|
52
|
+
## Cache decision flow for AI agents
|
|
53
|
+
|
|
54
|
+
When a task mentions caching, use this decision flow:
|
|
55
|
+
|
|
56
|
+
1. identify whether the route is a rendered page or a direct handler
|
|
57
|
+
2. decide whether the output is stable enough to cache safely
|
|
58
|
+
3. check whether the task needs a global default or a route-level override
|
|
59
|
+
4. identify which writes or mutations should invalidate cached routes
|
|
60
|
+
5. inspect `CacheHandler.php` only if the docs and current project code still leave important behavior unclear
|
|
61
|
+
|
|
62
|
+
This keeps AI aligned with documented Prisma PHP behavior instead of inventing cache abstractions from other ecosystems.
|
|
63
|
+
|
|
64
|
+
## How Prisma PHP caching works
|
|
65
|
+
|
|
66
|
+
Prisma PHP determines whether to cache a route using the interaction between:
|
|
67
|
+
|
|
68
|
+
- global `.env` settings
|
|
69
|
+
- route-level `CacheHandler` overrides
|
|
70
|
+
|
|
71
|
+
The docs describe this as a caching logic matrix:
|
|
72
|
+
|
|
73
|
+
- if `CACHE_ENABLED="false"` and no route override is set, the route is not cached
|
|
74
|
+
- if `CACHE_ENABLED="false"` and `CacheHandler::$isCacheable = true`, caching is forced for that route
|
|
75
|
+
- if `CACHE_ENABLED="true"` and no route override is set, caching applies by default
|
|
76
|
+
- if `CACHE_ENABLED="true"` and `CacheHandler::$isCacheable = false`, that route is skipped from caching
|
|
77
|
+
|
|
78
|
+
This means Prisma PHP gives you both a **global cache default** and a **per-route escape hatch**.
|
|
79
|
+
|
|
80
|
+
## Global configuration
|
|
81
|
+
|
|
82
|
+
Prisma PHP documents cache defaults through your `.env` file.
|
|
83
|
+
|
|
84
|
+
```env filename=".env"
|
|
85
|
+
# Enable system-wide caching
|
|
86
|
+
CACHE_ENABLED="true"
|
|
87
|
+
|
|
88
|
+
# Default TTL (600 = 10 minutes)
|
|
89
|
+
CACHE_TTL="600"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
According to the docs, `CACHE_ENABLED` controls whether caching is enabled by default, and `CACHE_TTL` sets the default TTL in seconds.
|
|
93
|
+
|
|
94
|
+
## Route-level overrides
|
|
95
|
+
|
|
96
|
+
You can override cache behavior for a specific route in the route entry file or controller logic.
|
|
97
|
+
|
|
98
|
+
```php filename="src/app/blog/index.php"
|
|
99
|
+
<?php
|
|
100
|
+
|
|
101
|
+
use PP\CacheHandler;
|
|
102
|
+
|
|
103
|
+
// Force cache this specific page
|
|
104
|
+
CacheHandler::$isCacheable = true;
|
|
105
|
+
|
|
106
|
+
// Set a custom TTL in seconds
|
|
107
|
+
CacheHandler::$ttl = 10;
|
|
108
|
+
?>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The docs show `CacheHandler::$isCacheable` for opting a route into or out of caching and `CacheHandler::$ttl` for overriding the default TTL for that route.
|
|
112
|
+
|
|
113
|
+
## What gets cached
|
|
114
|
+
|
|
115
|
+
The Prisma PHP docs describe `CacheHandler` as a way to **bypass database queries and view rendering logic by serving static HTML snapshots**. This means the primary documented cache target is the final rendered output for a route, stored as files on disk.
|
|
116
|
+
|
|
117
|
+
This is the main Prisma PHP equivalent to route-level page caching.
|
|
118
|
+
|
|
119
|
+
## Serving cached content
|
|
120
|
+
|
|
121
|
+
The documented API includes:
|
|
122
|
+
|
|
123
|
+
```php
|
|
124
|
+
CacheHandler::serveCache(string $uri, int $defaultTtl = 600): void
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
According to the docs, this method attempts to serve a static file for the given URI. If a valid, non-expired cache file exists, it outputs the content and terminates script execution. The docs also note that it checks route-specific TTL first, falls back to the default TTL if no route config exists, and appends an HTML comment showing when the cached copy was generated.
|
|
128
|
+
|
|
129
|
+
## Basic page-caching example
|
|
130
|
+
|
|
131
|
+
A typical Prisma PHP page-caching pattern looks like this:
|
|
132
|
+
|
|
133
|
+
```php filename="src/app/blog/index.php"
|
|
134
|
+
<?php
|
|
135
|
+
|
|
136
|
+
use PP\CacheHandler;
|
|
137
|
+
use Lib\Prisma\Classes\Prisma;
|
|
138
|
+
|
|
139
|
+
// Mark this route as cacheable
|
|
140
|
+
CacheHandler::$isCacheable = true;
|
|
141
|
+
|
|
142
|
+
// Optional route-specific TTL
|
|
143
|
+
CacheHandler::$ttl = 600;
|
|
144
|
+
|
|
145
|
+
$prisma = Prisma::getInstance();
|
|
146
|
+
|
|
147
|
+
$posts = $prisma->post->findMany([
|
|
148
|
+
'orderBy' => [
|
|
149
|
+
'createdAt' => 'desc',
|
|
150
|
+
],
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
?>
|
|
154
|
+
|
|
155
|
+
<ul>
|
|
156
|
+
<?php foreach ($posts as $post): ?>
|
|
157
|
+
<li><?= htmlspecialchars($post['title']) ?></li>
|
|
158
|
+
<?php endforeach; ?>
|
|
159
|
+
</ul>
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
This is the Prisma PHP equivalent of caching a page’s rendered result rather than caching a React component tree.
|
|
163
|
+
|
|
164
|
+
## Invalidating cache by route
|
|
165
|
+
|
|
166
|
+
Prisma PHP documents URI-based invalidation through:
|
|
167
|
+
|
|
168
|
+
```php
|
|
169
|
+
CacheHandler::invalidateByUri(string|array $uris): void
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
This method removes cache files for one or more specific routes. The docs note that it accepts leading slashes or plain paths.
|
|
173
|
+
|
|
174
|
+
Example:
|
|
175
|
+
|
|
176
|
+
```php filename="src/app/blog/_lib/save-post.php"
|
|
177
|
+
<?php
|
|
178
|
+
|
|
179
|
+
use PP\CacheHandler;
|
|
180
|
+
|
|
181
|
+
// Invalidate one route
|
|
182
|
+
CacheHandler::invalidateByUri('/blog');
|
|
183
|
+
|
|
184
|
+
// Invalidate multiple routes
|
|
185
|
+
CacheHandler::invalidateByUri([
|
|
186
|
+
'/',
|
|
187
|
+
'/blog',
|
|
188
|
+
'/dashboard',
|
|
189
|
+
]);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
This is the core Prisma PHP pattern for keeping cached pages fresh after content changes.
|
|
193
|
+
|
|
194
|
+
## Resetting cache
|
|
195
|
+
|
|
196
|
+
The docs also describe a lower-level clearing method:
|
|
197
|
+
|
|
198
|
+
```php
|
|
199
|
+
CacheHandler::resetCache(?string $uri = null): void
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
According to the docs:
|
|
203
|
+
|
|
204
|
+
- passing `null` purges all files in the cache directory
|
|
205
|
+
- passing a specific URI deletes the file for that route only
|
|
206
|
+
|
|
207
|
+
Example:
|
|
208
|
+
|
|
209
|
+
```php filename="src/app/admin/route.php"
|
|
210
|
+
<?php
|
|
211
|
+
|
|
212
|
+
use PP\CacheHandler;
|
|
213
|
+
|
|
214
|
+
// Clear everything
|
|
215
|
+
CacheHandler::resetCache();
|
|
216
|
+
|
|
217
|
+
// Or clear one route
|
|
218
|
+
CacheHandler::resetCache('/blog');
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Content update workflow
|
|
222
|
+
|
|
223
|
+
The Prisma PHP docs explicitly recommend invalidating relevant routes after saving dynamic content so users immediately see fresh data.
|
|
224
|
+
|
|
225
|
+
Their documented example follows this pattern:
|
|
226
|
+
|
|
227
|
+
1. save to the database
|
|
228
|
+
2. invalidate the related cache URIs
|
|
229
|
+
|
|
230
|
+
Example:
|
|
231
|
+
|
|
232
|
+
```php filename="src/app/blog/route.php"
|
|
233
|
+
<?php
|
|
234
|
+
|
|
235
|
+
use PP\CacheHandler;
|
|
236
|
+
|
|
237
|
+
function savePost($data)
|
|
238
|
+
{
|
|
239
|
+
// 1. Save post data
|
|
240
|
+
// ... database logic here ...
|
|
241
|
+
|
|
242
|
+
// 2. Invalidate affected routes
|
|
243
|
+
CacheHandler::invalidateByUri([
|
|
244
|
+
'/blog',
|
|
245
|
+
'/blog/recent',
|
|
246
|
+
]);
|
|
247
|
+
|
|
248
|
+
return [
|
|
249
|
+
'success' => true,
|
|
250
|
+
];
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
This is the Prisma PHP equivalent of revalidation after mutation.
|
|
255
|
+
|
|
256
|
+
## Concurrency and writes
|
|
257
|
+
|
|
258
|
+
The docs state that `saveCache` uses `LOCK_EX` by default to prevent race conditions when two requests try to write the same cache file at the same time.
|
|
259
|
+
|
|
260
|
+
That matters most on high-traffic pages where multiple requests may attempt to generate the same cached output simultaneously.
|
|
261
|
+
|
|
262
|
+
## Cache storage location
|
|
263
|
+
|
|
264
|
+
Prisma PHP documents cache storage at:
|
|
265
|
+
|
|
266
|
+
```php
|
|
267
|
+
DOCUMENT_PATH . '/caches'
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
The docs also note that this directory must be writable by the web server user.
|
|
271
|
+
|
|
272
|
+
## `index.php` vs `route.php` and caching
|
|
273
|
+
|
|
274
|
+
In Prisma PHP, your cache choice still follows the route model:
|
|
275
|
+
|
|
276
|
+
- use `index.php` when caching rendered page output
|
|
277
|
+
- use `route.php` when caching or controlling a direct handler route
|
|
278
|
+
- invalidate by URI when content changes affect one or more routes
|
|
279
|
+
|
|
280
|
+
For a full-stack project, page-oriented caching will most commonly apply to `index.php` routes, since those are the normal rendered UI entry points. API-style handlers in `route.php` may also use cache logic where appropriate, but their role is different from full page rendering. This route split aligns with Prisma PHP’s documented distinction between `index.php` as the UI entry point and `route.php` as the direct handler entry point.
|
|
281
|
+
|
|
282
|
+
## Prisma PHP vs Next.js caching mental model
|
|
283
|
+
|
|
284
|
+
If you are coming from Next.js, the closest mapping is:
|
|
285
|
+
|
|
286
|
+
| Next.js idea | Prisma PHP equivalent |
|
|
287
|
+
| -------------------------------------- | ------------------------------------------- |
|
|
288
|
+
| `use cache` on a component or function | Route/page caching with `CacheHandler` |
|
|
289
|
+
| revalidation after mutation | `CacheHandler::invalidateByUri(...)` |
|
|
290
|
+
| clearing cached output | `CacheHandler::resetCache(...)` |
|
|
291
|
+
| config-driven cache defaults | `.env` with `CACHE_ENABLED` and `CACHE_TTL` |
|
|
292
|
+
|
|
293
|
+
The biggest difference is that Prisma PHP’s documented model is file-based route output caching, not React component-level caching.
|
|
294
|
+
|
|
295
|
+
## When to cache
|
|
296
|
+
|
|
297
|
+
Prisma PHP caching is especially useful for routes where:
|
|
298
|
+
|
|
299
|
+
- the rendered output is expensive to generate
|
|
300
|
+
- the content does not change on every request
|
|
301
|
+
- the same route is requested often
|
|
302
|
+
- you want to reduce database and rendering work
|
|
303
|
+
|
|
304
|
+
Examples:
|
|
305
|
+
|
|
306
|
+
- blog index pages
|
|
307
|
+
- marketing pages
|
|
308
|
+
- dashboards with infrequently changing summaries
|
|
309
|
+
- public landing pages
|
|
310
|
+
- documentation-style content pages
|
|
311
|
+
|
|
312
|
+
## When not to cache aggressively
|
|
313
|
+
|
|
314
|
+
Be careful with caching routes that depend heavily on:
|
|
315
|
+
|
|
316
|
+
- per-user personalization
|
|
317
|
+
- rapidly changing data
|
|
318
|
+
- request-specific conditions
|
|
319
|
+
- authentication-sensitive output
|
|
320
|
+
|
|
321
|
+
In those cases, route-specific overrides or targeted invalidation are usually safer than broad default caching.
|
|
322
|
+
|
|
323
|
+
## Practical cache design guidance
|
|
324
|
+
|
|
325
|
+
A good Prisma PHP cache decision usually looks like this:
|
|
326
|
+
|
|
327
|
+
- cache public or mostly-static rendered output
|
|
328
|
+
- keep TTL modest when content changes on a schedule
|
|
329
|
+
- invalidate specific URIs after a successful mutation
|
|
330
|
+
- avoid broad global resets unless the change is truly system-wide
|
|
331
|
+
- avoid caching personalized pages unless you are certain the output is safe to share across requests
|
|
332
|
+
|
|
333
|
+
When uncertain, prefer **targeted invalidation** over aggressive long-lived caching.
|
|
334
|
+
|
|
335
|
+
## Good to know
|
|
336
|
+
|
|
337
|
+
- Prisma PHP’s documented cache system is `CacheHandler`.
|
|
338
|
+
- It is a file-based cache layer for serving static HTML snapshots.
|
|
339
|
+
- Global defaults are configured with `.env` using `CACHE_ENABLED` and `CACHE_TTL`.
|
|
340
|
+
- Per-route overrides use `CacheHandler::$isCacheable` and `CacheHandler::$ttl`.
|
|
341
|
+
- Route invalidation uses `CacheHandler::invalidateByUri(...)`.
|
|
342
|
+
- Full resets use `CacheHandler::resetCache(...)`.
|
|
343
|
+
- Cache files are stored in `DOCUMENT_PATH . '/caches'`.
|
|
344
|
+
- Cache writes use `LOCK_EX` for concurrency safety.
|
|
345
|
+
- The core class lives in `vendor/tsnc/prisma-php/src/CacheHandler.php`.
|
|
346
|
+
- Inspect the core file only when the installed docs and project code are not enough for a precise framework-level decision.
|