Re: [Discussion] is_string(), string type and objects implementing __toString()
| From: | Rowan Collins | Date: | Thu, 09 Mar 2017 20:09:04 +0000 |
| Subject: | Re: [Discussion] is_string(), string type and objects implementing __toString() | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-98463@lists.php.net to get a copy of this message | ||
On 08/03/2017 23:32, Andrey Andreev wrote:
For example, a Cookie object may have the cookie attributes (domain, path, etc.) as value objects, but they can easily be created from raw strings, while other types would be ambiguous. A similar effect could be desirable for HTTP headers.OK, now we have some concrete examples, thanks. I would say that in these cases, what you actually want is a much tighter contract: not just "can be converted to string", but "intended to be used in this context". It fits with what I was saying before about "if you can't name it, maybe it isn't the right abstraction". In this case, you want to accept some particular value objects but not, say, Exceptions - which are as useless for your purpose as an integer, even though (string)$foo would work fine on both. So you want objects that have promised to behave appropriately for this context; that could be as simple as: interface HTTPHeaderObject {
public function __toString();} ...with appropriate documentation that objects declaring that they implement this interface promise to behave in a specific way when cast to string. This is much clearer than detecting __toString(), which only promises "I can be cast to string" - the same promise that is made by all scalar values. In order to accept this or a string in a type hint, you need Union Types: function setHeaderValue(string|HTTPHeaderObject $value) { ... For broader use, we could perhaps have named unions: type HTTPHeaderType = union(string, HTTPHeaderObject); if ( $value instanceOf HTTPHeaderType ) { ... Meanwhile, of course, you can just use a boring old user-defined function: function is_valid_http_header_value($value) {
return is_string($value) || $value instanceOf HTTPHeaderObject;} Regards, -- Rowan Collins [IMSoP]