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,374 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Prisma PHP ORM
|
|
3
|
+
description: Learn how Prisma PHP ORM works, how to configure it, how to migrate your database, and how to generate the PHP ORM classes correctly.
|
|
4
|
+
related:
|
|
5
|
+
title: Related docs
|
|
6
|
+
description: Read the official Prisma PHP ORM docs before generating code or running ORM commands.
|
|
7
|
+
links:
|
|
8
|
+
- /docs/orm-get-started
|
|
9
|
+
- /docs/config-file
|
|
10
|
+
- /docs/prisma-cli
|
|
11
|
+
- /docs/find-many
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Prisma PHP ORM gives Prisma PHP applications a schema-first, Prisma-style data layer for PHP projects.
|
|
15
|
+
|
|
16
|
+
It uses your Prisma schema, Prisma migrations, and generated PHP classes so your application can query the database through the documented Prisma PHP API.
|
|
17
|
+
|
|
18
|
+
## ORM result shape rule
|
|
19
|
+
|
|
20
|
+
Prisma PHP ORM query results should be treated as model-shaped objects returned by the generated Prisma PHP classes that follow `prisma/schema.prisma`.
|
|
21
|
+
|
|
22
|
+
For normal reads, do not assume query results need defensive serializer layers just to become usable in PHP. Prisma ORM is already the source of truth for the requested model shape.
|
|
23
|
+
|
|
24
|
+
Only add a presentation mapper when you intentionally need to:
|
|
25
|
+
|
|
26
|
+
- flatten included relations for the frontend
|
|
27
|
+
- hide sensitive fields before returning data to the browser
|
|
28
|
+
- format dates or values for display
|
|
29
|
+
- produce a custom client-facing response shape
|
|
30
|
+
|
|
31
|
+
Use `PP\Validator` for inbound payload validation, sanitization, casting, and rule-based checks. Do not use output serialization as a substitute for backend validation.
|
|
32
|
+
|
|
33
|
+
## Backend validation rule
|
|
34
|
+
|
|
35
|
+
For Prisma PHP pages, exposed functions, and route handlers, backend validation should default to `PP\Validator`, which is part of the Prisma PHP core files and lives in:
|
|
36
|
+
|
|
37
|
+
```txt
|
|
38
|
+
vendor/tsnc/prisma-php/src/Validator.php
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`Validator` is the server-side validation layer for user input. It is not the ORM result layer.
|
|
42
|
+
|
|
43
|
+
Use this split:
|
|
44
|
+
|
|
45
|
+
- Prisma ORM for model-shaped query results
|
|
46
|
+
- `PP\Validator` for request validation and normalization
|
|
47
|
+
- optional presentation mapping only when the UI needs a deliberate response shape
|
|
48
|
+
|
|
49
|
+
## AI agent rule: read the ORM docs first
|
|
50
|
+
|
|
51
|
+
When a task involves any of the following:
|
|
52
|
+
|
|
53
|
+
- `schema.prisma`
|
|
54
|
+
- database provider selection
|
|
55
|
+
- migrations
|
|
56
|
+
- generated Prisma PHP classes
|
|
57
|
+
- `Prisma::getInstance()`
|
|
58
|
+
- `findMany`, `findFirst`, `create`, `update`, `delete`
|
|
59
|
+
- `prisma.config.ts`
|
|
60
|
+
- `npx prisma ...`
|
|
61
|
+
- `npx ppo generate`
|
|
62
|
+
|
|
63
|
+
read the ORM docs first before deciding what command to run or what code to generate.
|
|
64
|
+
|
|
65
|
+
Use this order:
|
|
66
|
+
|
|
67
|
+
1. Read `prisma-php.json`
|
|
68
|
+
2. Read the installed Prisma PHP ORM docs
|
|
69
|
+
3. Read `schema.prisma`
|
|
70
|
+
4. Confirm the database provider
|
|
71
|
+
5. Then decide the correct ORM workflow
|
|
72
|
+
|
|
73
|
+
## Where AI should look
|
|
74
|
+
|
|
75
|
+
For Prisma PHP ORM tasks, AI should read:
|
|
76
|
+
|
|
77
|
+
- `06-prisma-php-orm.md`
|
|
78
|
+
- the official Prisma PHP ORM docs for the installed version
|
|
79
|
+
- `schema.prisma`
|
|
80
|
+
- `prisma.config.ts`
|
|
81
|
+
- `.env` when the datasource uses `env("DATABASE_URL")`
|
|
82
|
+
|
|
83
|
+
Do not use general Prisma TypeScript habits alone. Prisma PHP has a PHP-specific workflow and generated PHP classes that must match the actual database state.
|
|
84
|
+
|
|
85
|
+
## Important separation of responsibilities
|
|
86
|
+
|
|
87
|
+
There are three different workflows that AI must not confuse.
|
|
88
|
+
|
|
89
|
+
### 1. Framework or project update workflow
|
|
90
|
+
|
|
91
|
+
Use this only when the task is about updating the full Prisma PHP project, syncing framework files, installing enabled features, or refreshing dependencies:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx pp update project -y
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This is a project/framework update command.
|
|
98
|
+
|
|
99
|
+
It is **not** the normal Prisma ORM schema migration workflow.
|
|
100
|
+
|
|
101
|
+
### 2. Prisma ORM database migration workflow
|
|
102
|
+
|
|
103
|
+
Use this when the database must be initialized or when `schema.prisma` changes and the database structure must be updated.
|
|
104
|
+
|
|
105
|
+
Typical development workflow:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx prisma migrate dev
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
This is the migration step.
|
|
112
|
+
|
|
113
|
+
### 3. Prisma PHP class generation workflow
|
|
114
|
+
|
|
115
|
+
Use this after migration succeeds, so the generated PHP ORM classes match the updated schema:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx ppo generate
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
This is the PHP class generation step.
|
|
122
|
+
|
|
123
|
+
## Required AI workflow for ORM tasks
|
|
124
|
+
|
|
125
|
+
Whenever a task depends on Prisma ORM, AI should follow this order:
|
|
126
|
+
|
|
127
|
+
1. Confirm which database provider the project uses.
|
|
128
|
+
2. Confirm whether the task is working against SQLite, MySQL, PostgreSQL, or another user-requested provider.
|
|
129
|
+
3. Inspect `schema.prisma`.
|
|
130
|
+
4. Inspect `prisma.config.ts`.
|
|
131
|
+
5. If the datasource uses `env("DATABASE_URL")`, inspect `.env`.
|
|
132
|
+
6. Decide whether migration is required before generation.
|
|
133
|
+
7. Run migration first when required.
|
|
134
|
+
8. After migration succeeds, run `npx ppo generate`.
|
|
135
|
+
9. Only then generate or update PHP code that depends on the Prisma PHP classes.
|
|
136
|
+
|
|
137
|
+
## Critical rule
|
|
138
|
+
|
|
139
|
+
`npx ppo generate` only generates or refreshes the PHP ORM classes.
|
|
140
|
+
|
|
141
|
+
It does **not** prove that the database migration ran.
|
|
142
|
+
|
|
143
|
+
It does **not** update the database schema by itself.
|
|
144
|
+
|
|
145
|
+
If the migration output is missing, failed, or was never executed, AI must say that clearly.
|
|
146
|
+
|
|
147
|
+
Correct wording:
|
|
148
|
+
|
|
149
|
+
- migration not confirmed
|
|
150
|
+
- generated PHP classes may exist
|
|
151
|
+
- database schema may still be out of sync
|
|
152
|
+
|
|
153
|
+
Incorrect wording:
|
|
154
|
+
|
|
155
|
+
- migration completed, if only `npx ppo generate` ran
|
|
156
|
+
- database is synced, if there is no confirmed migration output
|
|
157
|
+
|
|
158
|
+
## Confirm the database provider first
|
|
159
|
+
|
|
160
|
+
Before running migration or generation commands, inspect the Prisma schema and determine the active provider.
|
|
161
|
+
|
|
162
|
+
Typical provider examples include:
|
|
163
|
+
|
|
164
|
+
- `sqlite`
|
|
165
|
+
- `mysql`
|
|
166
|
+
- `postgresql`
|
|
167
|
+
|
|
168
|
+
AI should not assume the provider.
|
|
169
|
+
|
|
170
|
+
It should read the datasource block in `schema.prisma` or follow the user’s explicit database request.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
|
|
174
|
+
```prisma
|
|
175
|
+
// prisma/schema.prisma
|
|
176
|
+
datasource db {
|
|
177
|
+
provider = "sqlite"
|
|
178
|
+
url = env("DATABASE_URL")
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## SQLite workflow
|
|
183
|
+
|
|
184
|
+
When the provider is `sqlite`, AI must do more than just read the provider name.
|
|
185
|
+
|
|
186
|
+
It must also verify the SQLite connection target.
|
|
187
|
+
|
|
188
|
+
Use this flow:
|
|
189
|
+
|
|
190
|
+
1. read `schema.prisma`
|
|
191
|
+
2. read `.env` if the datasource URL comes from `env("DATABASE_URL")`
|
|
192
|
+
3. confirm that `DATABASE_URL` exists
|
|
193
|
+
4. resolve the SQLite file path from `DATABASE_URL`
|
|
194
|
+
5. confirm the path is valid for the project
|
|
195
|
+
6. if the SQLite database file is missing, invalid, or not initialized yet, run:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
npx prisma migrate dev
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
7. after migration succeeds, run:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npx ppo generate
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Important SQLite rule:
|
|
208
|
+
|
|
209
|
+
- if Prisma PHP reports that the SQLite database file was not found or could not be created, AI must not stop at `npx ppo generate`
|
|
210
|
+
- in that situation, the database initialization or migration step is still required
|
|
211
|
+
|
|
212
|
+
## MySQL and PostgreSQL workflow
|
|
213
|
+
|
|
214
|
+
When the provider is `mysql` or `postgresql`, use this flow:
|
|
215
|
+
|
|
216
|
+
1. confirm the provider in `schema.prisma`
|
|
217
|
+
2. confirm the environment connection values
|
|
218
|
+
3. run `npx prisma migrate dev` on first setup
|
|
219
|
+
4. run `npx prisma migrate dev` whenever `schema.prisma` changes
|
|
220
|
+
5. after migration succeeds, run `npx ppo generate`
|
|
221
|
+
|
|
222
|
+
This keeps the database structure and generated PHP classes aligned.
|
|
223
|
+
|
|
224
|
+
## `prisma.config.ts`
|
|
225
|
+
|
|
226
|
+
Prisma PHP ORM also uses `prisma.config.ts` at the project root.
|
|
227
|
+
|
|
228
|
+
This file is part of the ORM configuration workflow and should be reviewed when the task involves Prisma ORM setup, migrations, or generation.
|
|
229
|
+
|
|
230
|
+
AI should treat it as part of the ORM source of truth alongside `schema.prisma`.
|
|
231
|
+
|
|
232
|
+
## Example ORM workflow for AI
|
|
233
|
+
|
|
234
|
+
Use this pattern when the user asks to update models or add ORM-backed features.
|
|
235
|
+
|
|
236
|
+
### Correct sequence
|
|
237
|
+
|
|
238
|
+
1. Read `schema.prisma`
|
|
239
|
+
2. Confirm database provider
|
|
240
|
+
3. Read `.env` if needed for `DATABASE_URL`
|
|
241
|
+
4. Decide whether the database must be initialized or migrated
|
|
242
|
+
5. Run migration
|
|
243
|
+
6. Run PHP class generation
|
|
244
|
+
7. Then write route, page, or server logic
|
|
245
|
+
|
|
246
|
+
Example:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npx prisma migrate dev
|
|
250
|
+
npx ppo generate
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Incorrect sequence
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
npx pp update project -y
|
|
257
|
+
npx ppo generate
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
That sequence may refresh framework files and generate classes, but it does not by itself prove the database schema was migrated.
|
|
261
|
+
|
|
262
|
+
## Development vs prototype note
|
|
263
|
+
|
|
264
|
+
Prisma CLI also documents `db push` for prototype-style workflows.
|
|
265
|
+
|
|
266
|
+
AI should not treat `db push` as the default migration flow when the intended workflow is migration-based development.
|
|
267
|
+
|
|
268
|
+
For normal tracked schema changes, prefer the documented migration flow first, then class generation.
|
|
269
|
+
|
|
270
|
+
## First-time generation rule
|
|
271
|
+
|
|
272
|
+
`npx ppo generate` should be executed:
|
|
273
|
+
|
|
274
|
+
- the first time generated PHP ORM classes are needed
|
|
275
|
+
- whenever `schema.prisma` changes
|
|
276
|
+
- after the database migration or initialization step succeeds
|
|
277
|
+
|
|
278
|
+
Do not run generation alone and describe the database as ready unless the migration step was also confirmed.
|
|
279
|
+
|
|
280
|
+
## Using Prisma PHP in application code
|
|
281
|
+
|
|
282
|
+
After the ORM classes are generated, Prisma PHP code should use the documented PHP access pattern.
|
|
283
|
+
|
|
284
|
+
Example:
|
|
285
|
+
|
|
286
|
+
```php
|
|
287
|
+
<?php
|
|
288
|
+
|
|
289
|
+
use Lib\Prisma\Classes\Prisma;
|
|
290
|
+
|
|
291
|
+
$prisma = Prisma::getInstance();
|
|
292
|
+
|
|
293
|
+
$users = $prisma->user->findMany();
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Do not invent TypeScript-style Prisma usage in PHP files.
|
|
297
|
+
|
|
298
|
+
For normal application code, read ORM results directly as Prisma PHP model-shaped objects. Do not describe a manual serializer as required unless the code is intentionally shaping a frontend-facing response.
|
|
299
|
+
|
|
300
|
+
## `findMany` example
|
|
301
|
+
|
|
302
|
+
Prisma PHP queries are written with PHP arrays.
|
|
303
|
+
|
|
304
|
+
Example:
|
|
305
|
+
|
|
306
|
+
```php
|
|
307
|
+
<?php
|
|
308
|
+
|
|
309
|
+
use Lib\Prisma\Classes\Prisma;
|
|
310
|
+
|
|
311
|
+
$prisma = Prisma::getInstance();
|
|
312
|
+
|
|
313
|
+
$users = $prisma->user->findMany([
|
|
314
|
+
'where' => [
|
|
315
|
+
'active' => true,
|
|
316
|
+
],
|
|
317
|
+
'orderBy' => [
|
|
318
|
+
'createdAt' => 'desc',
|
|
319
|
+
],
|
|
320
|
+
'take' => 10,
|
|
321
|
+
'skip' => 0,
|
|
322
|
+
]);
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Common query options include:
|
|
326
|
+
|
|
327
|
+
- `where`
|
|
328
|
+
- `select`
|
|
329
|
+
- `include`
|
|
330
|
+
- `orderBy`
|
|
331
|
+
- `take`
|
|
332
|
+
- `skip`
|
|
333
|
+
|
|
334
|
+
## AI warnings for ORM tasks
|
|
335
|
+
|
|
336
|
+
When working with Prisma PHP ORM, follow these rules:
|
|
337
|
+
|
|
338
|
+
- do not use `npx pp update project -y` as the ORM sync command
|
|
339
|
+
- do not claim migration ran unless command output confirms it
|
|
340
|
+
- do not treat `npx ppo generate` as a migration step
|
|
341
|
+
- do not assume SQLite unless the schema or user request confirms it
|
|
342
|
+
- do not skip `.env` and `DATABASE_URL` checks when SQLite is used
|
|
343
|
+
- do not write raw guessed ORM wrappers if the documented generation workflow should be used
|
|
344
|
+
- do not copy Prisma JavaScript or TypeScript examples directly into PHP
|
|
345
|
+
|
|
346
|
+
## Best-practice AI wording
|
|
347
|
+
|
|
348
|
+
When migration succeeded and generation succeeded, AI may say:
|
|
349
|
+
|
|
350
|
+
- the database migration completed successfully
|
|
351
|
+
- the Prisma PHP classes were generated successfully
|
|
352
|
+
|
|
353
|
+
When only generation succeeded, AI should say:
|
|
354
|
+
|
|
355
|
+
- `npx ppo generate` completed
|
|
356
|
+
- generated PHP ORM classes are present
|
|
357
|
+
- database migration was not confirmed
|
|
358
|
+
|
|
359
|
+
When SQLite is configured but the file is missing or unusable, AI should say:
|
|
360
|
+
|
|
361
|
+
- SQLite `DATABASE_URL` was checked
|
|
362
|
+
- the SQLite database file is missing, invalid, or not initialized
|
|
363
|
+
- `npx prisma migrate dev` is required before relying on generated PHP ORM classes
|
|
364
|
+
|
|
365
|
+
## Summary rule
|
|
366
|
+
|
|
367
|
+
For Prisma PHP ORM tasks, the correct mental model is:
|
|
368
|
+
|
|
369
|
+
- confirm provider first
|
|
370
|
+
- inspect `.env` when `DATABASE_URL` is used
|
|
371
|
+
- for SQLite, verify the database file path and initialize or migrate when needed
|
|
372
|
+
- for MySQL and PostgreSQL, migrate on first setup and after schema changes
|
|
373
|
+
- generate PHP classes after migration
|
|
374
|
+
- only use `npx pp update project -y` for full project/framework updates
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Project structure and organization
|
|
3
|
+
nav_title: Project Structure
|
|
4
|
+
description: Learn the folder and file conventions in Prisma PHP, and how to organize your project.
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This page provides an overview of the folder and file conventions in **Prisma PHP**, and recommendations for organizing your project. It follows the Prisma PHP routing model and mirrors the mental model of a Next.js App Router style project structure, adapted to how Prisma PHP actually works.
|
|
8
|
+
|
|
9
|
+
## Folder and file conventions
|
|
10
|
+
|
|
11
|
+
### Top-level folders
|
|
12
|
+
|
|
13
|
+
Top-level folders are used to organize your application's source code, configuration, database schema, and public assets.
|
|
14
|
+
|
|
15
|
+
| Folder | Purpose |
|
|
16
|
+
| ---------- | ----------------------------------------------------------------------------- |
|
|
17
|
+
| `src/app` | File-system based routing, pages, layouts, loading states, and route handlers |
|
|
18
|
+
| `src/Lib` | Application libraries, generated Prisma classes, auth, middleware, utilities |
|
|
19
|
+
| `public` | Public web root, static files, CSS, JS, favicon, and public entry point |
|
|
20
|
+
| `prisma` | Prisma schema, migrations, and seed scripts |
|
|
21
|
+
| `settings` | Project configuration such as paths, BrowserSync, and related setup |
|
|
22
|
+
|
|
23
|
+
### Top-level files
|
|
24
|
+
|
|
25
|
+
These files are typically used to configure the app, manage dependencies, and define environment values.
|
|
26
|
+
|
|
27
|
+
| File | Purpose |
|
|
28
|
+
| ---------------------- | -------------------------------------------------------------- |
|
|
29
|
+
| `composer.json` | PHP dependencies and autoloading |
|
|
30
|
+
| `package.json` | Frontend tooling and development scripts when used |
|
|
31
|
+
| `.env` | Environment variables |
|
|
32
|
+
| `prisma/schema.prisma` | Main Prisma schema file |
|
|
33
|
+
| `public/index.php` | Public entry point |
|
|
34
|
+
| `bootstrap.php` | Application bootstrap and middleware registration when present |
|
|
35
|
+
| `prisma-php.json` | Project capability manifest and local Prisma PHP configuration |
|
|
36
|
+
|
|
37
|
+
### `prisma-php.json`
|
|
38
|
+
|
|
39
|
+
Prisma PHP projects should place `prisma-php.json` in the **repository root**.
|
|
40
|
+
|
|
41
|
+
This file is the best place to declare enabled project features and local environment metadata because it is easy for tools, scripts, and AI agents to discover next to the rest of the top-level project configuration.
|
|
42
|
+
|
|
43
|
+
Typical values include:
|
|
44
|
+
|
|
45
|
+
- `tailwindcss`
|
|
46
|
+
- `backendOnly`
|
|
47
|
+
- `swaggerDocs`
|
|
48
|
+
- `websocket`
|
|
49
|
+
- `mcp`
|
|
50
|
+
- `prisma`
|
|
51
|
+
- `typescript`
|
|
52
|
+
- BrowserSync target configuration
|
|
53
|
+
- PHP executable path
|
|
54
|
+
- component scan directories
|
|
55
|
+
|
|
56
|
+
If an AI agent is working on the project, it should inspect `prisma-php.json` before deciding whether Tailwind CSS, TypeScript, Prisma ORM, Swagger docs, MCP, or websocket-related code should be generated.
|
|
57
|
+
|
|
58
|
+
### Full-stack vs backend-only routing decision
|
|
59
|
+
|
|
60
|
+
One of the most important capability flags is `backendOnly`.
|
|
61
|
+
|
|
62
|
+
- When `backendOnly` is `false`, the project is a **full-stack Prisma PHP app**. In that mode, normal route UI should be implemented with `index.php`.
|
|
63
|
+
- When `backendOnly` is `true`, the project is a **backend-only Prisma PHP app**. In that mode, route behavior will usually center on direct handlers such as `route.php`.
|
|
64
|
+
- If a `route.php` file exists at a route segment, it acts as the direct handler entry point for that route and should be treated as the API-style or no-view path for that segment.
|
|
65
|
+
- In full-stack projects, if the user asks for a normal route or page, prefer `index.php`. If the user asks for an API route, JSON endpoint, form-processing endpoint, AJAX endpoint, or direct handler, prefer `route.php`.
|
|
66
|
+
|
|
67
|
+
This helps AI and contributors choose the correct file without guessing based on other frameworks.
|
|
68
|
+
|
|
69
|
+
### Framework-managed generated files
|
|
70
|
+
|
|
71
|
+
Some files in a Prisma PHP project are framework-managed and should not be manually maintained as part of normal route work.
|
|
72
|
+
|
|
73
|
+
#### `files-list.json`
|
|
74
|
+
|
|
75
|
+
Prisma PHP automatically generates the route list in `files-list.json`.
|
|
76
|
+
|
|
77
|
+
Do **not** create routes by editing this file. Do **not** manually add, remove, reorder, or “sync” entries in it.
|
|
78
|
+
|
|
79
|
+
Instead, create or update the correct folders and route files in `src/app`, then let Prisma PHP regenerate `files-list.json` automatically.
|
|
80
|
+
|
|
81
|
+
When an AI agent is asked to create a route, the correct change is in the route tree itself, not in `files-list.json`.
|
|
82
|
+
|
|
83
|
+
## Routing files
|
|
84
|
+
|
|
85
|
+
Prisma PHP uses file-system based routing. Folders define route segments, and special files define how those segments behave.
|
|
86
|
+
|
|
87
|
+
Routes are defined by the route tree under `src/app`. Prisma PHP then derives route metadata from those files. Because of that, AI agents should never treat `files-list.json` as the place where routes are declared.
|
|
88
|
+
|
|
89
|
+
| File | Purpose |
|
|
90
|
+
| --------------- | -------------------------------------------------------------------- |
|
|
91
|
+
| `index.php` | Public page entry point for a route and rendered UI |
|
|
92
|
+
| `layout.php` | Shared layout for a route subtree |
|
|
93
|
+
| `loading.php` | Loading UI for a route or subtree |
|
|
94
|
+
| `route.php` | Direct route handler for APIs, JSON, forms, and logic without a view |
|
|
95
|
+
| `not-found.php` | Not found UI |
|
|
96
|
+
| `error.php` | Error handling UI |
|
|
97
|
+
|
|
98
|
+
## Nested routes
|
|
99
|
+
|
|
100
|
+
Folders define URL segments. Nesting folders nests segments. A route becomes publicly accessible when an `index.php` file exists inside that route folder.
|
|
101
|
+
|
|
102
|
+
| Path | URL pattern | Notes |
|
|
103
|
+
| -------------------------------- | --------------- | ----------------------------------------------------- |
|
|
104
|
+
| `src/app/layout.php` | — | Root layout wraps the application |
|
|
105
|
+
| `src/app/index.php` | `/` | Public home route |
|
|
106
|
+
| `src/app/blog/index.php` | `/blog` | Public nested route |
|
|
107
|
+
| `src/app/blog/authors/index.php` | `/blog/authors` | Public deeply nested route |
|
|
108
|
+
| `src/app/blog/route.php` | `/blog` handler | Direct handler for API-style or programmatic requests |
|
|
109
|
+
|
|
110
|
+
## Dynamic routes
|
|
111
|
+
|
|
112
|
+
Dynamic segments are created with square brackets and are available through `Request::$dynamicParams` in `layout.php`, `index.php`, and `route.php`.
|
|
113
|
+
|
|
114
|
+
| Path | URL pattern | Notes |
|
|
115
|
+
| ------------------------------------ | -------------------------- | ---------------------- |
|
|
116
|
+
| `src/app/blog/[slug]/index.php` | `/blog/my-first-post` | Single dynamic segment |
|
|
117
|
+
| `src/app/shop/[id]/index.php` | `/shop/42` | Single param by id |
|
|
118
|
+
| `src/app/docs/[...slug]/index.php` | `/docs/a/b/c` | Catch-all route |
|
|
119
|
+
| `src/app/users/[username]/route.php` | `/users/jefferson` handler | Dynamic route handler |
|
|
120
|
+
|
|
121
|
+
## Route groups and private folders
|
|
122
|
+
|
|
123
|
+
Prisma PHP supports route groups and private folders to help you organize code without exposing everything as a route.
|
|
124
|
+
|
|
125
|
+
| Path | URL pattern | Notes |
|
|
126
|
+
| ------------------------------------- | ----------- | ---------------------------------- |
|
|
127
|
+
| `src/app/(marketing)/about/index.php` | `/about` | Route group omitted from URL |
|
|
128
|
+
| `src/app/(dashboard)/users/index.php` | `/users` | Grouping without changing URL |
|
|
129
|
+
| `src/app/blog/_components/Card.php` | — | Private implementation detail |
|
|
130
|
+
| `src/app/blog/_lib/helpers.php` | — | Non-routable colocated helper code |
|
|
131
|
+
|
|
132
|
+
## Middleware
|
|
133
|
+
|
|
134
|
+
Middleware in Prisma PHP is convention-based. Middleware classes live in `Lib/Middleware` and are registered in `bootstrap.php`.
|
|
135
|
+
|
|
136
|
+
| Location | Purpose |
|
|
137
|
+
| --------------------------------------- | --------------------------------------------------- |
|
|
138
|
+
| `src/Lib/Middleware/AuthMiddleware.php` | Route protection and auth checks |
|
|
139
|
+
| `bootstrap.php` | Register and invoke middleware |
|
|
140
|
+
| Route matching logic | Apply middleware based on pathname or request rules |
|
|
141
|
+
|
|
142
|
+
## Redirects
|
|
143
|
+
|
|
144
|
+
Redirects are handled with `Request::redirect()`, which sends an HTTP `Location` header and stops execution.
|
|
145
|
+
|
|
146
|
+
| Pattern | Purpose |
|
|
147
|
+
| ----------------------------- | --------------------------------------------- |
|
|
148
|
+
| `Request::redirect('/home')` | Temporary redirect after an action |
|
|
149
|
+
| `Request::redirect('/login')` | Redirect unauthenticated users |
|
|
150
|
+
| Redirect with 3xx semantics | Standard browser navigation via HTTP redirect |
|
|
151
|
+
|
|
152
|
+
## Example project structure
|
|
153
|
+
|
|
154
|
+
```txt
|
|
155
|
+
prisma-php-project/
|
|
156
|
+
├── prisma/
|
|
157
|
+
│ ├── migrations/
|
|
158
|
+
│ ├── schema.prisma
|
|
159
|
+
│ └── seed.ts
|
|
160
|
+
├── public/
|
|
161
|
+
│ ├── assets/
|
|
162
|
+
│ ├── css/
|
|
163
|
+
│ ├── js/
|
|
164
|
+
│ ├── favicon.ico
|
|
165
|
+
│ └── index.php
|
|
166
|
+
├── settings/
|
|
167
|
+
│ ├── bs-config.ts
|
|
168
|
+
│ ├── paths.php
|
|
169
|
+
│ └── restart-websocket.ts
|
|
170
|
+
├── src/
|
|
171
|
+
│ ├── app/
|
|
172
|
+
│ │ ├── layout.php
|
|
173
|
+
│ │ ├── index.php
|
|
174
|
+
│ │ ├── loading.php
|
|
175
|
+
│ │ ├── not-found.php
|
|
176
|
+
│ │ ├── error.php
|
|
177
|
+
│ │ ├── (marketing)/
|
|
178
|
+
│ │ │ ├── layout.php
|
|
179
|
+
│ │ │ └── about/
|
|
180
|
+
│ │ │ └── index.php
|
|
181
|
+
│ │ ├── dashboard/
|
|
182
|
+
│ │ │ ├── layout.php
|
|
183
|
+
│ │ │ ├── index.php
|
|
184
|
+
│ │ │ ├── users/
|
|
185
|
+
│ │ │ │ ├── index.php
|
|
186
|
+
│ │ │ │ └── [id]/
|
|
187
|
+
│ │ │ │ └── index.php
|
|
188
|
+
│ │ │ ├── reports/
|
|
189
|
+
│ │ │ │ └── route.php
|
|
190
|
+
│ │ │ └── _components/
|
|
191
|
+
│ │ │ └── StatsCard.php
|
|
192
|
+
│ │ └── blog/
|
|
193
|
+
│ │ ├── index.php
|
|
194
|
+
│ │ └── [slug]/
|
|
195
|
+
│ │ └── index.php
|
|
196
|
+
│ └── Lib/
|
|
197
|
+
│ ├── Middleware/
|
|
198
|
+
│ │ └── AuthMiddleware.php
|
|
199
|
+
│ ├── Prisma/
|
|
200
|
+
│ └── Auth/
|
|
201
|
+
├── bootstrap.php
|
|
202
|
+
├── composer.json
|
|
203
|
+
├── package.json
|
|
204
|
+
├── prisma-php.json
|
|
205
|
+
└── .env
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Organizing your project
|
|
209
|
+
|
|
210
|
+
Prisma PHP is flexible about how you organize your project files, but its routing system gives you a clear structure for colocating route-specific code.
|
|
211
|
+
|
|
212
|
+
### Component hierarchy
|
|
213
|
+
|
|
214
|
+
In practice, Prisma PHP route rendering usually follows this hierarchy for a given request:
|
|
215
|
+
|
|
216
|
+
- root `layout.php`
|
|
217
|
+
- nested `layout.php`
|
|
218
|
+
- `loading.php` when applicable
|
|
219
|
+
- `error.php` when applicable
|
|
220
|
+
- `not-found.php` when applicable
|
|
221
|
+
- route `index.php` or `route.php`
|
|
222
|
+
|
|
223
|
+
Nested layouts wrap their child segments, so layouts compose naturally as you go deeper in the route tree.
|
|
224
|
+
|
|
225
|
+
### Colocation
|
|
226
|
+
|
|
227
|
+
Because routing is based on special files such as `index.php` and `route.php`, you can safely colocate route-specific code inside route folders as long as those files are not themselves routable entry files.
|
|
228
|
+
|
|
229
|
+
This makes it practical to keep related files close together:
|
|
230
|
+
|
|
231
|
+
- components near the route that uses them
|
|
232
|
+
- helpers near the route logic
|
|
233
|
+
- route-specific services or validators in private folders
|
|
234
|
+
|
|
235
|
+
### Private folders
|
|
236
|
+
|
|
237
|
+
Private folders are prefixed with an underscore, such as `_components` or `_lib`.
|
|
238
|
+
|
|
239
|
+
Use them when you want to:
|
|
240
|
+
|
|
241
|
+
- separate UI logic from route entry files
|
|
242
|
+
- keep helper code close to a route
|
|
243
|
+
- avoid accidental routing
|
|
244
|
+
- keep naming conventions consistent across a project
|
|
245
|
+
|
|
246
|
+
### Route groups
|
|
247
|
+
|
|
248
|
+
Route groups use parentheses, such as `(marketing)` or `(dashboard)`.
|
|
249
|
+
|
|
250
|
+
Use them when you want to:
|
|
251
|
+
|
|
252
|
+
- organize routes by section, team, or concern
|
|
253
|
+
- apply a layout to a subset of routes
|
|
254
|
+
- keep the URL clean while improving folder organization
|
|
255
|
+
|
|
256
|
+
Be careful not to create two grouped routes that resolve to the same final URL.
|
|
257
|
+
|
|
258
|
+
### Suggested organization patterns
|
|
259
|
+
|
|
260
|
+
#### Keep routing in `src/app`, shared code in `src/Lib`
|
|
261
|
+
|
|
262
|
+
This is the clearest default for most Prisma PHP applications:
|
|
263
|
+
|
|
264
|
+
- `src/app` handles pages, layouts, route handlers, and route-local files
|
|
265
|
+
- `src/Lib` handles framework-level helpers, auth, middleware, and shared utilities
|
|
266
|
+
|
|
267
|
+
#### Split route-specific code by feature
|
|
268
|
+
|
|
269
|
+
For large applications, keep shared code near the route that owns it:
|
|
270
|
+
|
|
271
|
+
```txt
|
|
272
|
+
src/app/dashboard/
|
|
273
|
+
├── layout.php
|
|
274
|
+
├── index.php
|
|
275
|
+
├── users/
|
|
276
|
+
│ ├── index.php
|
|
277
|
+
│ ├── [id]/
|
|
278
|
+
│ │ └── index.php
|
|
279
|
+
│ └── _components/
|
|
280
|
+
│ └── UserTable.php
|
|
281
|
+
└── _lib/
|
|
282
|
+
└── dashboard-helpers.php
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Use groups for multiple application sections
|
|
286
|
+
|
|
287
|
+
This is useful when marketing pages and app pages need different layouts:
|
|
288
|
+
|
|
289
|
+
```txt
|
|
290
|
+
src/app/
|
|
291
|
+
├── (marketing)/
|
|
292
|
+
│ ├── layout.php
|
|
293
|
+
│ ├── index.php
|
|
294
|
+
│ └── about/
|
|
295
|
+
│ └── index.php
|
|
296
|
+
└── (app)/
|
|
297
|
+
├── layout.php
|
|
298
|
+
├── dashboard/
|
|
299
|
+
│ └── index.php
|
|
300
|
+
└── settings/
|
|
301
|
+
└── index.php
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Prisma PHP mental model for Next.js App Router users
|
|
305
|
+
|
|
306
|
+
If you are coming from Next.js App Router, this is the closest mapping:
|
|
307
|
+
|
|
308
|
+
| Next.js concept | Prisma PHP concept |
|
|
309
|
+
| --------------- | ------------------ |
|
|
310
|
+
| `app/` | `src/app/` |
|
|
311
|
+
| `page.tsx` | `index.php` |
|
|
312
|
+
| `layout.tsx` | `layout.php` |
|
|
313
|
+
| `loading.tsx` | `loading.php` |
|
|
314
|
+
| `route.ts` | `route.php` |
|
|
315
|
+
| `not-found.tsx` | `not-found.php` |
|
|
316
|
+
| `error.tsx` | `error.php` |
|
|
317
|
+
| `(group)` | `(group)` |
|
|
318
|
+
| `_folder` | `_folder` |
|
|
319
|
+
| `[slug]` | `[slug]` |
|
|
320
|
+
| `[...slug]` | `[...slug]` |
|
|
321
|
+
|
|
322
|
+
The main difference is that Prisma PHP uses PHP entry files and server-rendered route handling instead of React component files, but the route-tree organization model is intentionally very similar.
|
|
323
|
+
|
|
324
|
+
For route choice, remember this practical rule:
|
|
325
|
+
|
|
326
|
+
- use `index.php` for normal full-stack pages and route UI
|
|
327
|
+
- use `route.php` for API-style, JSON, AJAX, webhook, or no-view handlers
|
|
328
|
+
- if a segment has a `route.php`, treat it as the direct handler entry point for that route
|