TL;DR - Yeah, PHP, but what if C++? Feel free to tell me I'm wrong and should feel bad. THIS IS ONLY IDLE MUSINGS.
I was reading the arbitrary string interpolation thread (which I have mixed feelings on, but am generally okay with), and it got me thinking about motivations for it and other ways we might address that. I spend most of my time in C++ these days and that's going to show in this proposal, and the answer is probably "PHP isn't C++" and that's fine, but I want you to read to the end, because XSS is perennially on my mind and this might be one extra tool, maybe. PHP internal classes have the ability to handle operator overloads, and one use for overloads I quite like from C++ is streaming interfaces. Imagine the following: // Don't get hung up on the name, we're a long way from bikeshedding yet. $foo = (new \ostringstream) << "Your query returned " << $result->count() << " rows. The first row has ID: " >> $result->peekRow()['id']; At each << operator, the RHS is "shifted" into the string builder, and the object instance is returned. At the end $foo, is still that object, but when it's echoed or cast to string it becomes the entire combined string. As implementation details, we could keep the string as a list of segments or materialize completely, that could also be optimized to not materialize if we're in an output context since the intermediate complete string is unnecessary. Don't worry about this for now though. That by itself is... curious as an option, but not terribly interesting as we DO have proper interpolation and it works just fine, right? The reason I'm bothering to introduce this is that we could also build contextual awareness into this. During instantiation we could identify the context like: $forOuput = new \ostringstream\html << "You entered: " << $_POST['textarea']; $forURIs = new \stringstream\uri << BASE_URI << '?'' foreach ($_GET as $k => $v) { $forURIs << $k '=' $v << '&'; } These specializations could perform automatic sanitization during the materialization phase, this could even be customizable: $custom = new \ostringstream\user( landonize(...) ); We wouldn't be giving arbitrary operator overloading to the user, only arbitrary sanitization. Alternatively (or in addition), the point of materialization could be where we make this decision: echo $stream->html(); ------ I'd build this in userspace, but of course we don't have operator overloading, so the API would be a somewhat uglier function call: $stream->append("This feels ")->append(FEELING::Sad); Maybe the right answer is open the door on user-defined operator overloads, but my flame retardant suit is in the shop and I don't really need to open that mixed metaphor. -Sara