-
-
Notifications
You must be signed in to change notification settings - Fork 5
Database
WebEngine uses phpgt/database as its database layer, so the ideas here are the WebEngine way of working with queries and migrations.
If you want the lower-level component details, the full Database docs live at https://www.php.gt/docs/database/.
In a plain phpgt/database project we construct Settings, instantiate Database, and call the migrator ourselves.
In WebEngine, much of that wiring is already handled:
- configuration is read from
config.ini - query files live in the project
query/directory - the database service is available in page logic
- migrations are exposed through
gt migrate
That means we can focus mainly on query organisation and application logic.
Database settings belong in the [database] section of config.ini.
SQLite example:
[database]
driver=sqlite
schema=app.sqliteMySQL example:
[database]
driver=mysql
host=localhost
schema=app_db
port=3306
username=app_user
password=app_passUseful keys:
driverschemahostportusernamepasswordquery_pathmigration_pathmigration_tabledev_migration_pathdev_migration_table
For the full component-level explanation of connection settings, see https://www.php.gt/docs/database/configuration-and-connections/.
Query files normally live in query/.
For example, if we add:
query/user/getById.sql
we can call it from page logic like this:
public function go():void {
$row = $this->database->fetch("user/getById", 42);
}This keeps SQL out of page logic and makes the query easy to find on disk.
For more about collections, naming and PHP query classes, see https://www.php.gt/docs/database/query-collections/.
The same two binding styles are available in WebEngine:
- positional placeholders with
? - named placeholders with
:name
Example:
$row = $this->database->fetch("user/getByEmail", [
"email" => "dev@example.com",
"isActive" => true,
]);query/user/getByEmail.sql:
select
id,
email,
name
from
user
where
email = :email
and
isActive = :isActive
limit 1For the full rules around special and dynamic bindings, see https://www.php.gt/docs/database/parameter-binding/.
The database service returns the same Row and ResultSet objects as the standalone package.
That means we can use helpers such as:
fetch()fetchAll()fetchString()fetchInt()fetchDateTime()
For a full explanation, see:
- https://www.php.gt/docs/database/raw-sql-and-result-sets/
- https://www.php.gt/docs/database/type-safe-getters/
WebEngine exposes database migrations through gt migrate.
The default migration directory is:
query/_migration/
And branch-local dev migrations can live in:
query/_migration/dev/
Common commands:
gt migrate
gt migrate --force
gt migrate --reset
gt migrate --dev
gt migrate --dev-mergeThis gives us a clean workflow:
- use
gt migratefor normal schema updates - use
gt migrate --devwhile a feature branch is still changing - use
gt migrate --dev-mergewhen the branch-local migrations are ready to become canonical
For the full migration rules and integrity checks, see https://www.php.gt/docs/database/database-migrations/.
Tip
If you are new to the framework, keep the WebEngine view simple: write queries in query/, call them from page logic, and let gt migrate manage schema changes. The lower-level Database docs are there when you need more detail.
Next, move on to Page logic to see where this database service fits into the wider request flow.
- Request-response lifecycle
- Running your application
- Project layout
- Application architecture
- Web servers
- URIs
- Page view
- Dynamic URIs and pages
- Headers and footers
- Page logic
- Protected globals
- User input
- Cookies
- Sessions
- DOM manipulation
- Custom HTML components
- DOM templates
- Binding data to the DOM
- Database
- Client side assets
- API Webservices
- Security
- Configuration
- Build system
- Coding styleguide