Closed johannesschobel closed 6 years ago
Update:
My best so far, is to override the __get(...)
method from your DTO
like this:
public function __get($name)
{
$field = parent::__get($name);
$type = $field->getStorageType();
$value = call_user_func([$field, 'to' . Str::ucfirst($type)]);
return $value;
}
What do you think about this?
Sorry -- I just saw this (my Github notifications went AWOL). Oiy... no hacks like that should be required. You can access object properties using arrow notation or using the "get" method. For example:
class GenericDTO extends \Dto\Dto
{
protected $schema = [
'type' => 'object',
'properties' => [
'additionalProperties' => true,
],
];
}
And then you may instantiate it as such:
$dto = new GenericDTO(['foo' => 'bar', 'some' => ['deep' => ['nested' => ['data']]]]);
You can retrieve an object attribute using arrow notation, or the get()
method
print $dto->foo; // bar
print $dto->foo->toScalar(); // bar
print $dto->get('foo'); // bar
The trick is that each node in the DTO is also a DTO. PHP objects implicitly have a toString method, so PHP will figure out how to handle something like $x = "The foo is " . $dto->foo;
because from the context, it is clear that a string value is required. PHP doesn't have a toInteger or __toBoolean etc. methods, so sometimes you need to really get the scalar value out of your DTO, so that's what the toScalar()
method is for.
You can access the other attributes by name as well, but remember: you are always getting another DTO object in return.
So this returns a huge result with lots of recursion:
print_r($dto->some); // !!! big object with lots of recursion
But using the toArray()
method gives you what you probably want:
Array
(
[deep] => Array
(
[nested] => Array
(
[0] => data
)
)
)
Similarly, toObject
formats the output as an object (think of these as "views" since PHP is a bit ambiguous with its associative arrays and object syntax):
stdClass Object
(
[deep] => stdClass Object
(
[nested] => stdClass Object
(
[0] => data
)
)
)
Finally, you can access deeper items in your structure by using the arrow notation (for objects) and bracket notation for accessing elements from an array.
print $dto->some->deep->nested[0]; // prints "data"
Hope that makes things more clear. There are some examples on https://github.com/fireproofsocks/dto/wiki/GettingStarted to help get you started.
Hey there, I just stumbled upon your DTO implementation and i really, really, really love it! That is so easy to use! Really great job on this one!
However, i have one question, you may be able to answer me straight away..
Consider the following example. I have a
GenericDTO
that may be used, if no other one is specified. In order to make it generic (i.e., usable in all kind of situations, i have the following schema:Now i create a
GenericDTO
with my data to be passed..While this certainly works, how can i now access the
data
of an attribute? For example, if i want to get thename
, i would like to call$dto->name
. However, calling this, outputs the object itself - with the "storage" where my data is located in. If i run$dto->name->toScalar()
i get "John Doe". However,toScalar()
is not always possible, as i may access arrays or objects as well (because it is generic).Do you have an idea how to solve this properly? Or am I missing something crucial here? Thanks a lot for your awesome work..