-
Notifications
You must be signed in to change notification settings - Fork 0
Result Hydration
It is possible to use any of the WordPress WPDB return types ARRAY_A
, ARRAY_N
, OBJECT
, OBJECT_K
. BUt also to use custom models, complete with a basic constructor and simple hydration.
By default every instance of the QueryBuilder will return its results in standard stdClass
objects. This is the same as using the OBJECT
constant provided by WPDB. To change this, just use the setFetchMode
method.
$builder
->table('foo')
->setFetchMode(OBJECT_K)
->get();
// This would then return your results in an array where the primary key is set as the array key.
This is the same process as with
ARRAY_A
,ARRAY_N
You can use custom models/objects to return your results. You can even pass in constructor arguments to the class, which will be used when creating the instance (prior to hydration). While you can use the setFetchMode
method, its usually a little easier to read using the asObject
method.
class Result {
protected $something;
protected $column1;
public function __construct($something){
$this->something = $something;
}
public function setColumn1($value){
$this->column1 = $this->something($value);
}
}
For more details on setting values, please see below
In the Result
class, we need to pass in an argument when this is constructed. To do this, we can just pass the class name and the dependencies to the asObject
method.
$builder
->table('foo')
->asObject(Result::class, [new SomethingHelper()])
->get();
// This would then return your results mapped as a Result instance.
Under the hood the following will happen.
$class = $this->getFetchMode();
$args = $this->getFetchModeArgs();
$model = new $class($args);
$model->setColumn1($dbRow->column1);
return $model;
Defining with new instance of builder You can define the return type when you create an instance of the builder.
$builder = new QueryBuilderHandler($connection, Model::class, ['constructor', 'args']);
When we come to set values, there is a small flow the Hydrator
follows.
- First it will check if
PSR12
setter existssetColumnName
this will addset
to the start of the property name and capitalise the first charmyVal
would becomesetMyVal()
- Second we check if an underscored setter exists, this adds
set_
to the start of the propertymyVal
would becomeset_myVal()
- Finally we just set as a public property, if it doesnt exist it will be added as a dynamic property (which should be avoided)
- You can handle all possibilities with the magic
__set()
method.
class FooModel {
protected int $id;
public string $someValue;
protected string $someJson;
public function setId($id): void {
$this->id = (int) $id;
}
public function set_someJson($someJson): void {
$this->someJson = json_decode($someJson);
}
}
If we get the following data from a query
{"id":12, "someValue":"foo", "someJson":{"key":"some value"}}
When this is populated to the model, the following will happen.
- FooModel object is created
- id will be set using
$modelInstance->setId($row->id)
- someValue will be set using
$modelInstance->someValue = $row->someValue
- someJson will be set using
$modelInstance->set_someJson($row->someJson)