7.12.3. DiscussionJust as array( ) returns an empty array, creating an object of the type stdClass provides you with an object without properties or methods. Show
Like objects belonging to other classes, you can create new object properties, assign them values, and check those properties: $guss = new stdClass; $guss->location = 'Essex'; print "$guss->location\n"; $guss->location = 'Orchard'; print "$guss->location\n"; Essex Orchard Methods, however, can't be defined after an object is instantiated. It is useful to create objects of stdClass when you have a function that takes a generic object, such as one returned from a database fetching function, but you don't want to actually make a database request. For example: function pc_format_address($obj) { return "$obj->name <$obj->email>"; } $sql = "SELECT name, email FROM users WHERE id=$id"; $dbh = mysql_query($sql); $obj = mysql_fetch_object($dbh); print pc_format_address($obj); David Sklar <> The pc_print_address( ) function takes a name and email address and converts it to a format as you might see in the To and From fields in an email program. Here's how to call this function without calling mysql_fetch_object( ): $obj = new stdClass; $obj->name = 'Adam Trachtenberg'; $obj->email = ''; print pc_format_address($obj); Adam Trachtenberg <> PHP Value Objects IntroductionThis library aims to provide unification of commonalities of all value objects. Additionally, it provides some features that take advantage of the unified environment:
What is a value object?Value objects are guards of validity. Once a value object is constructed, it contains valid data. And as long as that object lives, we don't have to validate it again.
Note: For simplicity, I am exposing everything in the examples as public properties which allows modifications. They should really be private with public getters. What commonalities do value objects have a how we unify them?
How can we take advantage of the unifications?Unified errorsSince value objects need valid state, they have to check it. And this inherently means that they are doing validations and they have to do it themselves. If we just let value objects throw \InvalidArgumentException and instead we do validations (with client error reporting) beforehand, we are basically doing the validation twice. Once to feed the client with reasonable explanation where he screwed up and once in the value object to make sure it's not constructed from bullocks. And if we are lazy, we omit one or the other (or both in worst case). Omitting validation outside value objects means that our value objects may throw and we end up with 500 Internal Server Error. Omitting validation inside value objects means that we will never be truly sure that they are valid. Omitting them both is just disaster. Having both is redundant and may lead to de-synchronization between the two. If our value objects do the validations (which they should anyway) and offer a unified way to describe their expectations and eventual violations of said expectations, they effectively force you to validate your data:
Unification of how value objects represent violations allows applications to incorporate value objects errors into their input validation process. However, the way this incorporation is done for specific application is outside the scope of the library. This library attempts to unify the error exception as
Having an array of violations also gives is the option to report multiple violations at the same time.
A set of implementations is provided by this library, including some violations that describe nested errors of collections. Unified conversionsOften value objects provide named constructors that allow to construct them from a primitive. And it isn't also uncommon that value objects can convert themselves to a primitive type. This library provides a set of interfaces that define how conversion from and to primitive types should look like. In the example below, they are the This gives as unified
environment. It is sure easier to work with if all value objects that can be constructed from a single string value have the same named constructor for this. And, well, in case of conversion to string, that is already covered by PHP's magic method
And it allows to automatically construct composite value objects using their own class definition. See collections section. Common value objectsNow, wait a minute! Both first name and surname check the same thing. Let's get rid of that duplication.
We have moved the responsibility for checking the value emptiness to the That is however responsibility of the caller of the constructor, because he is now creating those NonEmptyString value objects. Let's see such a caller in the form of a factory that creates the object from primitive strings. It now manages the error codes and messages and overrides the defaults, while using the same codes (violation classes).
But we have also added a new type that is now a guarantee of non empty string. And you know, if you don't care that much for all the violations, you do just this:
Anyway, we can now avoid some checks on other places.
This effectively forces the caller to validate the input at some point, while leaving the function to care only about its logic. This library provides a set of base value objects that encapsulate some common restrictions we have on our primitive data types. Note: ViolationInterface implementations should only describe the error, what it is that was violated. If consumers want to know everything that could have been violated, they have to reach for the value object type itself. Immutable TraitsThis package offers two traits that support immutability of value objects.
These traits are used by all the base value objects in this package. And you are encouraged to use them on your value objects as well. Nevertheless you are still free to create public properties. There's actually one exception in this package that relies on public properties - DataTransferObject class. But other than that, we discourage you from using them, although it is often a bit less writing if you do. You are also always free to modify your objects using reflection, etc. So to be truly immutable is basically impossible in PHP. But we try as much as we can :) Base Value ObjectsOften we need to wrap primitive values and enforce some kind of limitation, like a limit on a string length, allow only subset of all characters in a string, or limit a maximum value of a number. Simple implementations of scalar objects with these common restrictions can be found in the package. Strings
Integers
Floats
Enums
We consider several axis for enums
Each aspect has cons and pros. Currently only strong string enums are implemented. CollectionsThe package supports 3 main types of collections
DataTransferObject
Note: If you sometimes need to construct the object not from array, but directly from separate variables, consider not extending DataTransferObject, implement your object, with own
constructor and use ArrayList
ArrayMap
FromArrayConstructorThis is not a value object, it is a static helper class which simplifies construction of objects from associative array of named parameters for their class constructor.
This helper also supports upcasting and downcasting. See upcasting/downcasting sections. Constructor parameters must have a default value to become optional in the input array. The parameters also must have a typehint. By default the
method reports any unexpected properties of the input through Basically, this method throws the same violations as DataTransferObject. The The Note: writing these value objects will become even easier with PHP8's constructor promotion. If you only need your object constructed from array and the constructor itself seems like a burden, you should consider DataTransferObject instead. DataStructureThis is basically a wrapper for FromArrayConstructor capabilities, which also provides from and to array upcasting/downcasting capabilities. This is the most solid base for an immutable data structure, if you are willing to write the constructor with all its properties. If you are not willing, use DataTransferObject. However with PHP8's constructor promotion feature, this will become equally simple and the DataStructure class will become the choice #1.
StandardsAdditionaly we provide a set of standard value objects for common things, like email, etc. But this sections is currently not ready and in future this may probably be in a separate package.
UpcastingWhenever a collection expects a value object type and it receives a primitive type, it will look for the appropriate upcasting interface on the target value object class. If it exists, it will automatically construct the value object using the interface.
Existing upcasting interfaces are:
DowncastingWhenever a collection expects a primitive type and it receives an object, it will look for the appropriate downcasting interface on the value. If it exists it will be used to obtain the primitive value.
Existing downcasting interface are:
FAQIs this only usable for validationNo. That's only a side effect that it allows to enhance and integrate with your validation system. What other use cases are there.This is basically for any use case where you would use a value object. It just helps you write them in unified way and simplifies some of its concerns. How about contextual validation? Some field must be an email if another field has a specific value?That is up to the constructor of the value object. Such a rule cannot be attributed to either of the fields alone. It's absolutely fine to define your own violation class for that and eventually reuse it in multiple value objects. How about nested validation rules? A client (user/api consumer etc) is sending data to your app and it gets back some errors? How do I communicate back "hey, addresses[5].state is not a valid state"?The communication of invalid state to the client is under control of your application. You can take advantage on unified violations environment, but you still have to be aware of what kinds of violations your value objects throw and represent each of them accordingly. Although violations are represented as classes, they really are just simple error codes with additional features leveraging the PHP class system. The violations from Collections namespace should make it easy enough to create nested violations for nested value objects. See the code of the collections to see how they are used. And you can also check their tests to see how we check for what happened in the nested violations tree. How about custom validation messages?Validation messages provided by ViolationInterface::getMessage() are not meant to be communicated to the client directly. They represent an immediately readable explanation of the violation for a developer. But if the violations are to be communicated to a general user, the messages should be generated within your application's validation system, based on the error codes and eventually other violation properties. You can use the default messages probably only on API where devs are the only ones who is going to read them. Chances are though, that in future the ViolationInterface::getMessage() method will be removed entirely. Some component that simplify this task of integrating the violations into validation systems may be created in future. At this point this is out of the scope of the library, and it would probably become a separate package anyway. How about validation that requires dependencies (eg: a database connection)?It is of course possible to throw the unified ViolationExceptionInterface from any factory you want. But this cannot happen within the automatic upcasting, since it happens through static named constructors. But there is no problem passing an already created value object to an automatically constructed value object from this package. And that makes it irrelevant whether the passed-in value object needed database to be created or not. Similar projects and inspiration
Thank you, guys! What is stdClass object in PHP?The stdClass is the empty class in PHP which is used to cast other types to object. It is similar to Java or Python object. The stdClass is not the base class of the objects. If an object is converted to object, it is not modified.
How do I reference a variable in PHP?Pass by reference: When variables are passed by reference, use & (ampersand) symbol need to be added before variable argument. For example: function( &$x ). Scope of both global and function variable becomes global as both variables are defined by same reference.
Are objects in PHP 5 passed by value or reference?In PHP, objects are passed by references by default. Here, reference is an alias, which allows two different variables to write to the same value. An object variable doesn't contain the object itself as value.
How do you access the properties of an object in PHP?Within class methods non-static properties may be accessed by using -> (Object Operator): $this->property (where property is the name of the property). Static properties are accessed by using the :: (Double Colon): self::$property .
|