 So welcome all of you to probably your last session for this conference. Yeah, later there will be of course like a closing session but if you wanna go to Dewey's, feel free to go to Dewey's. Yeah, maybe the room there is quite full. Anyway, so I gonna talk about the HTTP Wonderland in PHP. So what I want to cover in the talk is a little bit of history how HTTP, like what the idea of HTTP actually is, a little bit of how you deal with it currently in PHP, how you deal with it probably in duplicate and how to deal with it in the glory future. So a quick summary or question, like who of you are like of typical developer back-end-ish or front-end-ish? Okay, so pretty much everyone, all right, that's good. I mean, everyone of you heard what HTTP basically is, probably, yeah, all right, yeah, I'll continue. Okay, so first, a few words about me. My name is Daniel Wiener, I'm a core contributor. I'm working with the, as you see with the duplicate people, with the people contributing there. I work for Tech One, coinciding. And I also work for Chapter Three. And in general, I'm a really curious person. That means that I got sidetracked and tried to find out about a particular technology and I will suffer from doing it because it will lead or steal so much time. And that's why I'm kind of interested in that talk because I did a lot of research going on with how you can properly use HTTP and PHP and how you can design your application around that. Anyway, let's start it with HTTP. So what HTTP stands for is written down here. It's the Hypertext Transfer Protocol. So a protocol is way how computers or general stuff communicates with each other. Transfer is because it transfers data from one computer to the other one. And the interesting one is actually the Hypertext. You know all the Hypertext. HTML is a typical Hypertext. It's a document with some links between pointing to other documents. But it's not the only Hypertext you can think of. You probably all use Windows at some point and their help system is also a Hypertext because their help system in Windows has links to other help systems. So HTTP allows you to deal with Hypertext in general because like one primary entity of HTTP or one thing you can use there are URIs or URLs in general and with them you can refer to different documents. So here's another example of a Hypertext. Anyone know what this screenshot is about? Anyone know that game? Just curious. Yeah? Exactly, that's Moost. So it was a game in the 90s and you see a 3D graphic but that's all fake because it's pre-rendered graphics and it's basically a render that was kind of an island where maybe you see some water on the left side and it was a pre-rendered game basically and that game consisted of multiple images with layers on top of that but these images have been connected using kind of URLs. So there was a thing called Hypercard which was like a stack of images connected to each other and you could build something like that pretty easy over HTTP as well these days. So HTML is really just a special case. Another example is a thing called Halljason. Halljason is a common format how computers communicate with each other so like if you want to export a user you can do it via Halljason because the other computer also knows how to read in Halljason. So yeah, don't think that HTML is the only thing that's actually just a special case. A little bit of HTTP history. So here you see kind of one of the first computers which is what's called a next computer. This is in CERN so the collider is there and a guy called Tim Berners-Lee invented the web back in 1989 and his idea was that it should be easy for people to document what they do like and to write documents about their work at CERN and their research and his primary idea was that idea of linking documents together because that actually makes information helpful. Then there has been a couple of steps in that process how HTTP was constructed like all of you use probably HTTP 1.1 these days but that came out like this year a new version of it which is the 2.0 version. Maybe you have heard of it but there are a couple of misconceptions about it. So for example, people said that encryption is built into HTTP 2 but that's actually not true. It's just the case that every browser requires it but you could still use your little Raspberry Pi and talk with your foot over HTTP without encryption. But for user stuff like your browser it should be secure. That's what people like Firefox think. So here's a basic model how HTTP works. There's someone doing a request. So here you see not that popular browser anymore. Sending a request to a different server in this but it's always just computers to computers. It sends a request and that server tries to answer that request with a response. And so what is in that response? So here you see a command line tool called Curl. You might have heard of it. You can basically give it a URL or any kind of thing but you can for example ask for the tuple.org homepage and by default it will give you the HTML which is part of tuple.org. But HTTP response and request contains a request of more than just the HTML for example. Here you see the HTTP header and a response is separated into two pieces. This first the header which is meta information about what is requested or what is sent and then there's the actual content. Like in the blue you see the actual content called body and there you see the HTML. And in the header there's, there are quite a lot of interesting information. For example cookies are stored in there or also stuff like the content type which explains what kind of data do I send? Like also information like is that, was that response cached or can the browser decide that this response is cached? So that example is used for images so that if you go to a page and click to a link you don't want to download the site logo again. If you want to see that kind of information because it might be helpful for debugging purposes you can use curl-i and that will print out just the header but in general I would recommend to play a little bit around with curl. One question bit is the URL. That's basically the resource. What do I want to fetch? And that consists of a little bit more. So here you see a split of what is possible inside a URL. So a URL is split up in the scheme. Here's HTTP but it could be also HTTPS for for example secure connections. Then it's the authority which is basically the host like tuple.org but also authentication data like the username and the password and other stuff like the network port. And then that's the path which is slash user slash one which is interesting because in Drupal like in six and seven it was always like user slash one without the slash at the beginning. So for example if you install Drupal in a directory it was the path in Drupal was user slash one always but HTTP doesn't know about that. It thinks of slash slash my directory slash user slash one and that's kind of a thing which people struggle in Drupal eight that distinction between what HTTP defines and what PHP thinks about it and what especially Drupal thinks about it. And there are other stuff like the query parameters. So we have seen the header but what can be in the body? In the body it can be the HTML but there could be also form data. So if you click on the submit button on a page additional data will be sent to the server. But you can put in pretty much everything. You can even stream videos over it if you really want to. Yeah. So we have seen a quick overview of what is possible inside HTTP itself how it looks like a little bit. But we can then also have a look like how we deal with it in PHP which all of us at least somehow used. There are a couple of ways to do that. Here you see the old way like or the way how PHP does it itself without any kind of abstraction on top of it. I call it the number zero cause it's basically how you start. You might have seen something like that. So there's a couple of information exposed for you in PHP but it's all in the global namespace. So here for example you see underscore get queue and that's basically referring to the path in the URL. It's not entirely obvious why it's named like that. Because in HTTP we talked about the header. We talked about the body. We talked about the query parameters and here's underscore get. It's kind of odd. It's the language here is totally different to HTTP which is a problem for people new to it and it's a problem if people are used to that and then go to other program languages. Yeah, you can do other stuff here. It's not that important but I'm wondering whether you have seen that friend. Anyone have seen that friend? Cannot modify header information, headers already sent. Yeah, it's a fucking pain. Where the fuck is that? What does that mean? I won't fuck you. I mean it's a freaking pain because that error is basically impossible to debug. Yeah, what? All right, so what happens is that as you've seen before, the HTTP message consists of two elements. It consists of the header, then an empty line and then the body. And the thing is once the headers are sent out, you cannot send additional headers. It actually says in the message cannot modify header information, headers already sent. So everything which is before the first empty line are the headers and in case you send out the body, at least a piece of it already, you cannot do anything about it. So the problem here is that in PHP, the way to send something to the body is to say print body or print whatever string you want to send out. Once any kind of code is doing that, like print an empty string, I'm not sure whether you have seen that. Or print like a debug statement or print an error message. Once that done, the header cannot be modified anymore. So if you do it, every code which deals with the header has to be executed before the first print statement. And that makes it really hard to architect your system because if any kind of code can call out to header or to print, your entire application has to be structured in a way that it cannot, that no print statement is executed before. And that's really a big problem. This global state, it's just bad architecture. So yeah, let's summarize some problems again about PHP, the way how PHP deals with HTTP. So it's a global structure. It's a global state, like pieces interacting with each other without knowing of each other. It's that causes, for example, things like random bugs. It causes code, which is incredible how to write tests for in a proper way. Or at least causes really slow tests because you need to use HTTP rather than just call out a code and check the response of that code. And I even consider that this is not really an API what PHP exposes to us. It's rather, yeah, no words. All right, so of course many people saw the problem. And so one approach is to define additional abstractions on top of that, what we have from PHP. And one way is to use an existing library. Here's a list of some of those. You see SEND, you probably heard of SEND as the inventors of PHP or somehow the people which maintain PHP partly, it's an open source project, but there are many people which are paid to contribute in SEND. And but SEND also has a PHP framework. And that framework has its own HTTP abstraction. Another one is GASL, I will talk about GASL more. It's later, but it's basically an HTTP client. Similar to CURL, actually GASL uses CURL under the hood. It's about, yeah, being able to ask in your PHP code another web server about data. Another interesting example is OAuth server PHP. That thing, you think, yeah, I wanna write a library dealing with OAuth, yeah, let's implement HTTP abstraction because my domain in my library is OAuth, so I need to write HTTP abstraction. That's just one that you have to take care of that in your library, so what they did is to write an abstraction over HTTP library. So you have this additional level, they don't provide an HTTP library, but rather they provide a web power and yeah, it makes things really hard to deal with if you don't have a common foundation for every project. Another common example is Symphony HTTP Foundation. This is a thing which people kind of criticize a lot. It's also used by a lot of people. Here's a list of them. Some CMSs, SS28, maybe a third of that, PHP, BB, can't tell there are a lot of people using it. Why are people using that? That's an interesting question, I think. I think the primary reason is actually not that it's good. It's rather that it came out at the same time as Composer came out. And Composer came out, it is a project to manage packages in PHP and because HTTP Foundation is a package, you can use it really easy using Composer in your own project. So also Drupal just has an entry in their Composer file and fetches then HTTP Foundation. I'll try to give, here's just a code, how you deal with things in the same way how you saw before. What is interesting here, I think, is that you see request query, request request, request server. It's kind of similar information to what you've seen before. Like, so underscore get is like request query. Request request is like underscore post. And request server is like underscore server. One thing which you see is certainly is that it's object-orientated code. You have the request object, and then you can get the query object out of that, then you can ask the query object about things. How does that make things easier? I think it becomes way more obvious if we go to sending data out. So here you see a way how you create a response. So you say, okay, I wanna have a response. I want to set that particular header and I want to set that particular body. So what is the improvement over what we've seen before? The improvement is, for example, that you cannot get the headers already sent thing if you print out stuff. Because the sending out of the entire HTTP message is done when the response sent is executed. So basically the code flow afterwards is then like you have this response object and people put stuff on that. They expand the body message over time. They add additional headers over time and once the system is ready to send things out, they send things out. So that typically you have just one place in your application which sends out data. But that additional abstraction also potentially helps a little bit with the writing specific codes. Here you see an example how you can create JSON. You just create the PHP array and then you create a JSON response and then you send the data out. That additional thing also has a huge impact on people who write tests because you have those objects. You have input which is the request and you have output which is the response and your tests can just look at those objects and see whether they are constructed in the proper way. Let's build an application. So we have basically everything what we need. We have an HTTP request, there's our response, our application and then there's a response. So here you see an example. Request is coming in from the left side. We create a request object in PHP. Then we have our application in red in the middle and that sends out a response. But the interesting thing is that this architecture allows us to really easy put things on top of that. There's an architecture style which is used in quite some languages which is called middleware and middleware basically is like an onion. You see the application as the core of the onion but you have additional layers around that. So here for example you see the logging layer. In that logging layer you create a request, lock with which URL was accessed and then send out, then ask the application for the response, maybe measure the time, how long it needed, additional logging and then pass out the response to the next level. And you can do that with multiple levels. So for example page caching is implemented in that way in tuple eight. So you have this middleware which is really lightweight because that middleware just needs basically a database connection for the cache and that's pretty much it. So caching looks at the URL, checks, asks the database, do I have a cache entry? If there is a cache entry, directly serve the response from it because the cache entry contains the response otherwise asked the next level in my onion. That's the logging, okay. Next level and then logging then ask the application how to create the response. And then the caching is that layer around. So once the response is then created by the application the response bubbles up to logging, bubbles up to caching and then caching can use that response and create a cache entry. And that makes it actually really interesting because we are here talking about HTTP abstractions. So you theoretically could replace, like for example you build the application using PHP but then you realize logging is too slow but then you could build this logging layer using whatever entries or something or whatever. You can basically rip out parts in your PHP code and replace that with other things which also talk HTTP. It's really interesting people these days to actually build even the application via that style. Yeah, I will talk a little bit more about middlewares later because it's also used when, you could also use that when requesting data via HTTP. So I'll give, I mean much like another entity is asking you about your response, you could also ask another entity about some data. And the example I want to present is SCASL which is an HTTP client library. So here I want to do, here is an example, how you can, what do I get here? I get the tracing data for a particular issue on Tuber.org. So you have an URL and you have a client. That client object contains the logic how to send out an HTTP request and pass the response. So we can get the data and in the result we have an object we can deal with again. For example, get the status code or get the body out of it. So we have similar kind of objects here as well. We have a response object much like we created response object before. So you could think that you could share code between those systems and you could just learn HTTP things once. So once a request, once we learn about responses and that's all you need. Here's an example how to send out a form. Yeah, there's nothing special about it. But SCASL is actually pretty cool project because it also allows you to send asynchronous data. So asynchronous data means if you say like client get it doesn't have to directly query the other server but rather it can just make a promise that you will do it. So here's an example which is called request async. So you say I wanna get example.com and when this is done, so then, when is it done? Then I want to do something and in this particular case you just want to manipulate the response but you can do basically everything here. But with that kind of architecture which is for example used in JavaScript pretty much everywhere, it allows you to like for example bike operate on these kind of things or just create the request and then don't care about it anymore and by that architecture you can speed up your code a little bit by not necessarily execute what you need. SCASL is pretty cool because it allows you to set a couple of additional options. So for example you can do like a request which gets you a cookie and then you can like you can post to do with using the login form that gives you a cookie and then you can post another thing which gives you an issue and it can keep track of state for example. But you can also say things like yeah I want to deal with redirect, so if Tool.org decides you want to redirect to a different page it can keep track of that internally but there's many many things like presented to you out of the box like logging, history, you can build your own but there's also a really interesting thing which is called SCASL service and that allows you to integrate SCASL into whatever API service like GitHub and allows you to provide those abstractions in the domain language of that particular API and then you don't have to care about SCASL but SCASL is handling everything internally and it makes it easy to write those API webpods for GitHub for example or your own site. So we have seen, I'm sorry, we have seen the response object here as we have seen the response object in Symphony HTTP Foundation. So the question is why those are two different things. Why do I have to learn about HTTP again? Like for example the author of SCASL invented like all the things like response query, it dealt with things like query parameters, he worked on all that kind of stuff and then he realized I do exactly the same as the guy from SEND Foundation, not SEND Foundation, SEND Framework, why can't we work together? And there's one group which is called PHP FIC which is the framework group which, framework compatibility group, no, interaction group, anyway, they're working on things called PSR which are, I forgot, it's the PHP standard recommendations and there are a couple of them. One for example is the way how, in which directory is your classes exist. So PSR 7 is an idea to provide request, response, and all kind of those objects in an abstract way so that everyone can speak, so every tuple, symphony, send, word press, CASL, whatever, can speak in the same language together. It was quite a success because many, many people adopted it already, tuple 8 adopts it already, symphony adopts it already, et cetera, et cetera. So let's have a look what's inside there. You see there's a response, a request, that's typically what you think about it, there's a message interface which is kind of a more abstract thing, there's server request, yeah, and there's your interface which I will talk about later. So here's a little bit of sample code, sorry for that all kind of code, but here's a really sad thing you see here, let me show you that. Where's the mouse? Anyway, okay, so there's one way to create a request, it's using Gaffle, so you pass in the method, so get opposed, the URI, and some additional headers. Or you create a request using a library called dirac-tools, not sure why anyone invented that name, but it's the way how send deals with HEP, and there you pass in the URI as first argument, and the method as second argument, and then the body as third argument, it's the thing is that these objects are bound to a particular use domain, because Gaffle usually don't have to deal with bodies because Gaffle most of the time just sends get requests, so it doesn't make sense to have a body. But it's sad because now even you have these abstractions, you need to relearn specific things over again. Anyway, one interesting thing is that those objects, unlike symphony, are immutable. What means immutable, immutable means they cannot change at all. So here you see an example, you see request with header, and what with header does, it copies an existing object and modifies just that particular header entry and creates a new object with basically a copy of everything beside that one small change. You could really ask, why the fuck do I wanna do that? And yeah, it's kind of an academical discussion, sadly. Yeah, immutability, it's coming from functional programming in which you don't have any kind of state. The interesting thing is that at least in the functional programming world, that helps you to parallelize your computations, for example, because nothing is interacting with something else directly. But you could really argue that in PHP it doesn't make sense because PHP just have a different mind model. And yeah, but people have chosen it, but it also helps you to deal with the things. Anyway, here's an example how to deal with URLs in PSR7. So we can create a URI object, say I wanna have a different path and I want to have a query parameter and after that you can cast it to a string and use it. That's actually kind of a cool API compared to pass, how it's called pass URL which gives you an array with some entries but not always the keys. And afterwards if you want to manipulate it, you can manipulate that array and then you need to reconstruct the URL afterwards which is really hard, but you could for example in your projects just use that particular class to manipulate URLs. If we talk about immutability, so with path creates a new object and then that new object gets a function call with query which also creates a new object and this is then stored in the URI variable afterwards. Yeah, you can like it if you want. Anyway, here's an example of PSR7 middleware. It's interesting because here you don't get a request and response is sent out but rather you get passed in a request, you get passed in a response and you get passed in a next callable. So that next callable is basically in the onion, the more inner layer. So like the logging middleware gets the application as next. But you can also see that you get a response here and the reason why it's there is that's the only way how to manipulate objects by sending it continuously through the nested world. This kind of structure is used now by a couple of projects. It's maybe a good idea for you to check it out just to have a little bit of fun. Anyway, yeah, that's what it, if you want to evaluate it, here's the URL. That's more important, I think. This is a couple of cool podcasts and documents you might wanna listen to. For example, the first one is about HTTP2, like one of the inventors of it. Change log is also really interesting. And come to the sprints tomorrow if you have time. All right, that was it. Any questions? Hello. Hi, yeah, thank you for the session. One thing about PSR7 is do you have any good practical example that I could use today, for example, because it's been kind of theoretical for me at this point. So that would be great. I've maybe not really mentioned it, but Gaffle in the version six is using PSR7. So if you use Gaffle, you already deal with it. I cut it that out how to deal with PSR7, for example in Drupal. But in Drupal, you can pretty much also return a PSR7 response or ask for a PSR7 request and internally Drupal converts the normal HTTP foundation objects to PSR7 objects. So that's one way to deal with it. Another way to deal with it is to play around with those kind of frameworks. They are really lightweight frameworks, like Relay, it's built upon a different architecture than MVC, which is more suitable for the web or the Slim Framework would seem to be one of the fastest PHP frameworks ever. So that's one way how you could learn more about it. Does it answer your question a little bit? Yes, but for example, could I use a middleware to integrate the CDN, for example? Yes, I mean, in a CDN, you probably want to deal with setting additional headers, right? Yeah, you can write a middleware in PSR7, so I'm not sure whether there's some out there for specific CDNs, but you could write a middleware which manipulates the response object. Yeah, that was exactly so. So something like that you could use it for today. Yeah, I mean, today, what means today for you? I mean, if you deal with Superlate, for example, or if you deal with Symphony Framework, you could write such a thing in that project. I mean, if you click especially on Stratility, so those slides will be online and they are all links, and Stratility is a middleware framework. It's basically the thing which defines those middlewares using that particular function signature above, and that kind of project has a couple of examples already, and then probably there are links to other people implementing exactly that interface there. Yeah, so for example, if I had a CDN, it would probably be a good motivation for me to create such middleware and then give it away for free so people could use it with WordPress Drupal easily, so that's sort of framework or application-independent way. Yeah, exactly, yeah, that was a good word at the end. Middlewares are independent from your application. Here you see this logger, and logger is just a PSR3 object. PSR3 is a PSR about how to deal with locking in a framework-economic way in PHP. Yeah, thank you.