====== Request for Comments: Boxing and Unboxing ====== * Version: 1.0 * Date: 2009-07-06 * Author: Josh Thompson * Status: Under Discussion * First Published at: http://news.php.net/php.internals/44616 This RFC discusses a new feature for PHP called boxing and includes discussions of related RFCs that would complete the implementation of boxing and unboxing. ===== Introduction ===== Boxing and unboxing is a concept from the C# language. The basic idea of boxing in C# is that a value type is implicitly converted to an object type. Unboxing is the opposite and is done explicitly to convert the object back to a value type. ===== Boxing: Implicit Conversion To Objects ===== The most obvious use for boxing is function and method type hints. The object type hints could be used to do implicit boxing of variables. Either a new magic method (''__box'' for example) or a new interface (''Boxable'' for example) would need to be added to PHP. The boxing method would accept the scalar value and set its internal representation (similar to ''__wakeup''). The method could either return false (and let PHP handle the failure) or throw an exception (''BoxingException'' for example) when the supplied value is not valid for the boxing operation. It would be best for PHP to include as many object versions of scalar types as possible. The boxing functionality could be added to the SPL Types (([[http://php.net/manual/en/book.spl-types.php|SPL Types]])) to provide for standard representations of the scalar types. The power to box variables would also be available in userland classes. It could also be possible to try to perform implicit conversions from one object type to another, but the overhead of this feature may be too much. Consider it as an option only. ===== Unboxing: Or, Casting To Scalar ===== The unboxing of variables would need to occur on an explicit cast or on a call to an internal function. The unboxing could be implemented as the RFC for class casting to scalar (([[http://wiki.php.net/rfc/class_casting_to_scalar|RFC: Class casting to scalar]])). It already discusses some examples for a new magic method or interface. I propose some more to relate to the unboxing concept (''__unbox'' for a magic method, and ''Unboxable'' for an interface). ===== Benefits ===== The benefits to boxing and unboxing include: * Only minor modifications required to the current type-hinting implementation (I am only assuming this part). * The boxing and unboxing ability can be used in userland classes to accomplish "cool things". * Get SplTypes and scalar casting in PHP core. ===== Examples ===== Example of different int object classes: value = $value; } public function __unbox($type, $class = null) { switch ($type) { case (Unboxable::INT): return $this->value; break; case (Unboxable::FLOAT): return (float)$this->value; break; case (Unboxable::STRING): return (string)$this->value; break; default: throw new UnboxingException('StrictInt cannot convert to type: ' . Unboxable::getTypeString($type)); break; } } } class FuzzyInt //implements Boxable, Unboxable { protected $value; public function __box($value) { $this->value = (int)$value; } public function __unbox($type, $class = null) { switch ($type) { case (Unboxable::INT): return $this->value; break; case (Unboxable::FLOAT): return (float)$this->value; break; case (Unboxable::STRING): return (string)$this->value; break; default: throw new UnboxingException('FuzzyInt cannot convert to type: ' . Unboxable::getTypeString($type)); break; } } } function testStrict(StrictInt $value) { $test = (int)$value * 2; echo $test, ' ', $value; } function testFuzzy(FuzzyInt $value) { $test = (int)$value * 2; echo $test, ' ', $value; } testStrict(1); // '2 1' // testStrict(1.5); // error // testStrict('1'); // error // testStrict('one'); // error testFuzzy(1); // '2 1' testFuzzy(1.5); // '2 1' testFuzzy('1'); // '2 1' testFuzzy('one'); // '0 0' ===== Proposal and Patch ===== No patch exists for Boxing. The casting to scalar has some patches on its RFC page. ==== Rejected Features ==== //None// ===== Changelog ===== 2009-07-06: Initial Draft