Comments (6)
Hi @foremtehan,
The framework is functioning as expected here. The issue arises from the incompatibility between your get
and set
methods.
When you access your custom cast using $user->name
, an entry is added to the classCastCache
array indicating that the class cast has been used. This utilizes your get
method to convert the value {"test"}
into new TestCast()
.
However, when you call $user
in Tinker or perform an action on the model, such as $user->save()
to persist the data into the database, the class cannot be inserted as is; it needs to be serialized.
For normal serialization Laravel uses PHP's __sleep()
magic method to prepare the model for serialization. At this point, the $this->mergeAttributesFromCachedCasts()
method is called, revealing the issue with your get
and set
methods.
A part of this method call involves using the custom cast setter to prepare your value. The resulting code essentially does this:
return json_encode(new TestCast());
Since you haven't specified how PHP should serialize your class, perhaps by implementing JsonSerializable
, it converts it as best it can, taking class TestCast {}
and converting it to {}
.
When creating a custom cast, ensure that the output value from your get
method can always be passed into your set
method and result in the expected output.
I hope this clarifies things. If you have any follow-up questions, I’d be happy to help.
from framework.
I didn't assign a value to the name column, so why would it trigger the set method on the castable class?
Additionally, note that I tested it, and the framework never invoked the set method when using ->name
.
from framework.
It doesn't trigger the set
when you access it. But when you access you add an entry to the classCastCache
array (see: HasAttributes.php:879
Then later on when it needs to serialize
your model it calls the set (see: Model.php:2387
for the main method and HasAttributes.php:1823
for the set
call).
Try it yourself. Access it with $user->name
then access it again straight after. You'll see it doesn't overwrite. It only overwrites once you serialize it.
from framework.
Overall, this is unwanted behavior. Just imagine using $user->name in your app, and then calling save() somewhere in your codebase afterward. Your data will be lost. I’ll let the maintainers decide whether to close this issue, but I have demonstrated the problem.
from framework.
You control how the set
behaves here so it's up to you to make it work how you want it to work. If you change your get to new TestCast($value)
, save that value inside the class then on your set retrieve it or implement JsonSerializable
you will have no problems.
The comment for the set method even tells you this..
Prepare the given value for storage.
from framework.
Overall, this is unwanted behavior. Just imagine using $user->name in your app, and then calling save() somewhere in your codebase afterward. Your data will be lost. I’ll let the maintainer decide whether to close this issue, but I have demonstrated the problem.
Is there a real world example of this? because in the end, get should cast to the object value you want it in, and set should use an object value to convert back to a value that can be stored in the database, which in your case isn't happening at all.
from framework.
Related Issues (20)
- Migration is not working as expected (as written in docs) HOT 5
- Potential infinite recursion when executing `schema:dump` HOT 2
- Potential infinite recursion when executing `schema:dump` HOT 11
- Custom validation rules break generated error MessageBag when custom messages are defined HOT 3
- limit() in relationship load extremely slow in Laravel 11 HOT 2
- Listeners are handled within transactions despite the ShouldHandleEventsAfterCommit interface
- Laravel 11 auto session=database throws intermittent SQLSTATE[08004] [1040] Too many connections error HOT 5
- DatabaseRule "unique" fails quietly when given an incorrect column HOT 4
- Where Query with Arrays for JSON Columns HOT 7
- Adding a batch to a chain through prependToChain/appendToChain results in serialization errors HOT 2
- Cannot override default error page with Laravel 11 Bootstrap Exception Handling HOT 2
- firstOrNew on belongsToMany doesn't work as expected HOT 3
- Accessor date casting formatting as UTC when being serialized to JSON. HOT 1
- Contextual binding resolved when it shouldn't be for LogManager HOT 5
- Using Emergency logging channel throw an exception HOT 3
- Sqlite column processing crashes when column has a "/" in its name
- Database migrations in pretend mode doesn't display insert statements to migrations table HOT 3
- Job runs longer than "retry_after" will re-run immediately once the "retry after" seconds passed. HOT 1
- Unexpected behaviour when chunking a query HOT 3
- Artisan db:show and db:table fails when database has tables in multiple schemas HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from framework.