A 'model' defines the structure and properties of a specific dataset. At the same time, it also defines methods to access this data in various ways:
- searching (querying)
- filtering
- storing/updating data
- building ad-hoc data models (e.g. joins)
It does not define a value-object on its own. Usually, datasets are kept 'PHP-native' in (assocative) arrays.
A model consists of
- a model configuration (usually a file like
config/model/<schema>_<model>.json) - a backing class (f.e. in
backend/class/model/<model>.php- note this does't contain the schema name at all)
{
"field" : [
"stuff_id",
"stuff_created",
"stuff_modified",
"stuff_name"
],
"primary" : [
"stuff_id"
],
"datatype" : {
"stuff_id" : "number_natural",
"stuff_created" : "text_timestamp",
"stuff_modified" : "text_timestamp",
"stuff_name" : "text"
},
"options" : {
"stuff_name" : {
"length": 64
}
},
"connection" : "myconnection"
}You can define a 'model' by creating a JSON file (usually placed in your project folder in config/model/ and named <schema>_<model>.json).
There's a good reason to store the model configuration as a separate file like this - to allow architect to find it, build it and not having to parse PHP classes for annotations.
The most used (and required) keys in a model are:
- field: an array of fields in this model
- primary: an array of (one) field(s) that represent the primary key
- datatype: an object that defines a datatype for a given field (see available/basic data types below)
Additionally, you have to define some more (optional) keys:
- connection (string): if you want to assign this model to an explicit connection/database in your application
- options (object): additional field properties like
lengthor DB-specific modificators - default (object): default values for fields, if they're not set during creation of a dataset
- notnull (object):
- index (array): an array of single-field or multi-component indexes
- foreign (object): and object of foreign keys
- children (object): ORM-fields
- collection (object): ORM-fields
The framework defines some basic data types. Here, we show the (My-)SQL equivalent, to improve understanding.
| Data type | PHP type | MySQL equivalent (default) | Notes |
|---|---|---|---|
| number_natural | int/integer | INT(11) |
BIGINT if primary key |
| number | float/double | NUMERIC, DECIMAL |
precision and length available as options |
| boolean | bool | TINYINT(1)/BOOLEAN |
|
| text | string | TEXT, MEDIUMTEXT, LONGTEXT |
length available as option |
| text_date | string (ISO-date) | DATE |
|
| text_timestamp | string (ISO-datetime) | DATETIME |
|
| structure | array, associative array/object | text (formatted as json) |
internally handled as regular text field |
| virtual | (none) | (none) | reserved field for ORM-use |
The available datatypes directly correlate to available validators.
text fields may also extend to types like text_timestamp, which will
be kept as a string in PHP, but as far as applicable, translated to a DB-optimized version, if any.
For example, a text_timestamp field will be created as a DATETIME
When building database structures using architect there are some default conventions that are applied, if there's no special configuration (e.g. in options).
- a primary key being a number_natural is created as a
BIGINT(20)withAUTO_INCREMENT - a text field is created as a medium-length text field - if
lengthis given in options, it will be aVARCHAR(n) - a field used as/in a foreign key constraint is automatically adapted to the datatype of the field the key references
- a text field contained in an index must have a definitive length
- Many methods on a model instance return the instance itself (
return $this;).
This allows chaining of commands, which is especially useful if you define complex filtering or join a lot of models and want to keep your code 'fluent' for instructions that belong together. - Regular filters get reset/removed after executing a query.
- ..._created and ..._modified fields are mandatory to be defined, if you bootstrap your application using architect.
This is just a short overview and explanation of the most essential and most-used methods on a model without the overhead of describing required and optional arguments.
| Method | Description |
|---|---|
| ->search () | Executes a query |
| ->getResult () | Returns the current/latest query result |
| ->load (...) | Loads a dataset by ID/primary key |
| ->addFilter (...) | Applies a filter to the next query |
| ->addFilterCollection (...) | Applies a collecton of filters to the next query |
| ->addDefaultFilter (...) | Applies a filter to all following queries |
| ->addDefaultFilterCollection (...) | Applies a collecton of filters to all following queries |
| ->addField (...) | includes a specific field (column) in the resultset |
| ->hideField (...) | excludes a specific field (column) in the resultset |
| ->save (...) | stores given data |
| ->addModel (...) | adds (joins) another compatible model, effectively making the model more complex |
| ->setVirtualFieldResult (...) | enables virtual fields in a model (and full ORM functionality) |
| ->saveWithChildren (...) | stores given data, ORM-enabled |
We assume you have a minimal core app running.
// Get a fresh instance of the model
$model = app::getModel('stuff');
// Query the data and return resultset
$result = $model->search()->getResult();
// Do something with the result, e.g. output
print_r($result);This will query all the data available in the model - in case of a MySQL/MariaDB, this is similar to querying:
SELECT * FROM stuffBy default, all fields defined in the model are retrieved for the output resultset. Manually added columns in a table that are 'unknown' to the model won't appear.
Please continue to
- Model filters for defining your data searches.
- Complex models for adding/joining models and building more complex models.