Value objects are one of building blocks in Domain Driven Design. They represents a value and does not have an identity. That said, two value objects are equal if their values are equal.
Other important feature is that Value Objects are immutable, i.e. they can not be modified after creation. Only valid way to create Value Object is to pass all required informations to constructor (and should be validated somewhere there). No setter methods should take place.
This post isn’t about obvious advantages of representing domain logic with support of Value Object. As well, we wouldn’t elaborate here about pros and cons of immutable objects. I’d rather would like to show an attempt to change Value Object, keeping it still immutable and using one of most bizarre, in my opinion, feature of PHP language, which is accessing private fields from outside an object.
Often times you would like to alter Value Object, by creating new one based on current (which is only valid way). Altering logic conceptually belongs to Value Object class, so should be located there. In such method, you clone current instance, set new information to given field and return the copy. And this is were accessing private fields for same class makes sense. You can do that without having additional setters which will break the design.
As illustrated above, all Value Object features are in place. This example is of course trivial, but you can imagine a lot more complicated VO’s, like values shared between bounded contexts.