On Tue, Mar 22, 2022 at 10:41 AM Michał Marcin Brzuchalski < michal.brzuchal...@gmail.com> wrote:
> 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 > > > > > But why can't we have generic operator overloading in which case this could be completely built by libraries in userland?