I don't have much to say on that besides that I feel it's a great idea and if that can be built with parametrized type streams (not limited to strings only) then I'd be even more thrilled with such functionality.
Thanks for this idea and I hope it get materialized soon. Cheers, Michał Marcin Brzuchalski pon., 21 mar 2022 o 18:10 Larry Garfield <la...@garfieldtech.com> napisał(a): > On Mon, Mar 21, 2022, at 10:23 AM, Sara Golemon wrote: > > 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 > > What you're proposing here is: > > 1. An overloadable operator on objects (via a new magic method or > whatever) that takes one argument and returns another a new instance of the > same class, with the argument included in it along with whatever the > object's existing data/context is. > 2. Using that for string manipulation. > > If you spell the operator >>=, then point 1 is adding a monadic bind. > This has my full support. > > Using it for string manipulation is fine, although there's a bazillion > other things we can do with it that I would also very much support and can > be done in user space. Whether or not it makes sense for some of these > operations to be done in C instead is up for debate. Once an arbitrary > object can have a socket, that plus monads can push most stream operations > to user space. > > Building a "stream wrapper" like thing, or a filter, then becomes some mix > of object composition and binding. > > > $s = new StripTagsStream(new ZlibCompress(FileStream($fileName)) >>= > $htmlString; > > Which... feels kinda Java clunky. It would be better if we could chain > out the wrapping levels. Which could potentially just be done in the > implementation to allow a stream on the RHS to mean that. > > public function __bind(Stream|string $s) { > if ($s instanceof Stream) { > return $s->wrapAround($this); > } > // Whatever this object does with a string. > } > > $s = new FileStream($fileName) >>= new ZlibCompress() >>= new > StripTagsStream() >>= $htmlString; > > I'm... not sure which direction we'd want them to go in. Just > spitballing. Some way to automate that pattern would likely be good. > > But yeah, a native bind operator has my support. :-) > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >