 Hele. Mae'r obserfant yn fawr yn mynd i'n ffordd hynny'n ffordd y byddwyr yn fawr, mae'r sgwr ar gyfer yna, mae'n gweithio o'r webis i'r ddweud i ddweud sgwrdd G2 ac mae'n ddweud i'n ddweud i'r ddweud i'r ddweud i'r ddweud. Gwybododd eich ddweud i ddweud o'r teimlo gyda ni'n tu'r aws? oedd yn ymwneud yw wedi'i gweithio'r gweithio, ond mae'n cyffinio'r gweithio gweithio'r gwahanol yn y cyd-dwylliant o fy nghymru yn ystod o'r tyn nhw i'r sefydlu'r cyflogol. Mae yna Rob Allen. Efallai'r cyffinio'r cyffinio sy'n dyfynol yn y ffyrshun. Cyffinio yw 0.1 oedd yn gweithio'r cyffinio'r cyffinio. Ac mae'r frysg ymlaen i'r newydd 48.1 wedi gwrs ydy i'r mwyaf arch. Mae'n ниw i atwm wedi'i mewn gofyn yn gwych ar llawer, ac mae gennyn nhw fydd yng ngyrsbyn gyda'u'r system. Mae enw'r plant am y ddweud, mae'r frilwyr, a rheswm am ysgol發oddiad hwn. Ond mae'r frwyd eisiau gwybod o baeth i'r sprun honau, ac mae'n gweithio hefyd. Yna'r wrth iddo y gallwch chi'n gwneudio gweithio. Yn siwer yw un oedd Llyfrinll gw Bahidraall Cymru, Llyfrinll 1, Llyfrinll 2, Llyfrinll 3. S 사건iai diolch yn y mifiau. Yn dda'r gweithio Llyfrinll Gwadraall Gwadraall Gwadraall Gwadraall Gwadraall Cymru, mae'r cair meddwl yn ddwylliant. Dydyn ni'n sullfa'r gweithiau ar gwell, ma'n dda hi ddefnyddio gyda rhoi hynny'n ddwy определol. On y cwmjoch y cwmioich, mynd i gael ffamil. Ies fel Silex, Slym, Lumn, all arall maeth yn y fforddi'r cwmio. Ry'n meddwl i gael rwynt ddweud. Ry'n meddwl i'r meddwl i'r panetaethau yn hydr Gŵr. Roedd o'r gynllun i'r trewyn sylfaenol hwn yn y cyffredin. Roedd o'r hwn ymgyrch ym Mwneud. i wneud y gwaith cyffigurau. Rwy'r rhai cyffigurau yn y ffair at cyffigurau... ..a gwneud yn y mycôl yn y r falar poemog i'r cybl Serker-όr. Yn deall, fe wnaethau'r wahabod a'r cynllun o'i tyff yn y cyffigurau... ..y mycôl yn y cyffigurau'r cyflwyts hwyl... ..o'r cyflwyts eithaf, diolch i'r cyflwyts eithaf... ..ac yr adeiladio cyflwyts yw'r adeiladio cyflwyts eithaf. things that you're going to need to flesh out your website or flesh out your API. I'm personally an AI person, so things like the API rendering components.. ..are always in my apps. Filtering and validation is required for just about every app out there, database abstraction, session handling etc. You're going to need them in your application. There are zened components that you can use that will slot straight in. However, because it is a micro-fropebook, you don't have to. Wych chi'n gweithio'r gwaith ychydig o'r ddechrau ac mae'n cymdeithasol oedd yn cael ei ysgawdd. Eysgrifio'r agnostic yw'r gwaith yw'r gwaith yn ei gwaith o'r ddau o'r ddau o'r ddau o'r ddau o'r ddau. Mae yna bod chi'n gweithio'r ddau o'r ddau. Yn ychydig, y ddau'r ddau o'r ddau o'r ddau o'r ddau yn cael ei gwaith ar gyfer FF2, ac mae'n ddau o'r ddau. Mae'n gweithio'n ddau o'r ddau. Mae'n mynd i chi'n blaen uwch i weld y dyfodol o'r ddau o'r ddau o'r ddau o ddau o'r ddau o'r ddau. Yn ddau o'r ddau o diagnosiad llun o'r ddau o'r ddau, y dyfodol o'r ddau o'r ddau o'r ddau o ddau, mae ydyllAN o hyd o'r ddau o'r ddau. A wedi'u gweldio'r ddau o'r ddau o wg. Mae oedd yn digwydd hynny mae yn isgafi gwaith. Other people prefer a PHP-based templating system so Zend-View or Plates will make more sense to them. You can pick the one that makes your project work best for you. And I know what you are thinking. You are thinking, this is a Zend framework project, Zend-Expressive. So clearly the defaults are going to be Zend-Router, Zend-Service Manager and Zend-View. And they are not. The defaults are Fastroot, Send service manager and no template whatsoever. Because a good proportion of applications nowadays are APIs and you do not need a template layer for that, so we're not even going to provide the default, pick the one you want. Fastroot is a really good router, so that is our preferred one nowadays. If you want more comfortable with the way the Zend router works then you can use it. Se agnw'n cyrathio edge, we choose Fastroot by default. Dyna ddeuig yn y bobl. Mae'r dweud yn gw 약간. Mae gennych a'ch ei oser ganwyr yn fyrwm o'rthinkytha hwnnw ymwysig yng ngholysgol yn unig. Dyna ddeuig yn cynnwys, ond mae'n bod yn gwybod nhw'n cyhoeddol arwyr. Ond oedd o'r ddeuig, ac ower o'r dweud yn gw 해줴, mae'r dweud yn gweithas. Sef na'r ddeuig wedi'u byw yn gwybaran, mae'r ddeuig o garwyr drom erbyn y mewn o'r dweud yn cyfrifiad. i'r hynw'r hiad ddau cyllid gyda'i gwybod. Ysgrifolwyr dw i'r cyd-ddeithas pan byddai'r cyllid cyd-ddeithas i'r cyllid cyd-ddeithas syddain Rheityng Lynydd, o'r Cymddiol Cymru, Cyfrwyr Arfyneddau o'r cyd-ddeithas. Ysgrifolwyr am yr cyd-ddeithas. Yn ymhaerwch, y cyfrwyr syllwyr yma oherwydd mae'n grun, gallwch ddweud y brôl ac yn ei ddiwybod ni'n gwahodd mewn gwahoddiwyledig, i gael ei gwahodd yn ogylch swydd uch yn gyntaf o'r cyd-refhaf hwnnw, a'r amddangos'r cyd-refhaf hwnnw. Rydym yn ddim yn arddangos, byddwch yn ddweithio. O'r rhodd cyd-refhaf ar y ddweithio o'r cyd-refhaf oed yn hen ac wedi bod yn cael ei hwnny yn cael ei ddweithio y mynd yna. Ac y gallwn yw'r cyfnodd cyfnodd y cyfnodd yn ymgyrch. Gyd yna'r cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd yn cyfnodd. Yn ddweud, mae'n mewn gwirionedd – mae'n gydag o'r cyflugau. Mae'r cyflugau o'r cyflugau, ac mae'n gwybod ei gwybod ei wneud. Wrth gwrs, mae'n gyfnodd y ffig – y grwp o'r gweithio. Mae'n gweithio hyn o'r gwybod. Mae Gweithiau tarot gyda pobl, polyddiad Cyllidau Cymru, yn cael ei fawr gweithio'r newid yn ei parce i niadau cyntaf o bobliannau'n gweithio. Mae archweithiolaeth sydd gennym yn gweithio'r newid yn ymgynghwrm gynhalwyd, ac y ddigon ni'n arweinydd ar gyfer bullion pern yn ymgyrch menyw i chi gyda'r siar absurd i'r ffrwng. Oedd yw'r ffordd o bryd yn gweld o gyhoeddaeth, a meddwl i'r freud charger yw'r ffordd oherwydd i chi'n gweld ar gyfer bod hi wnaw dioledd y ffyrdd o'r rhefn a dylai fod yn dod, efallai i gael eich gwaith o'r dyfodig yr cyfnodau carbolwyr yn magell-wyrfynnal. A P.S.R.0 yn y credu hynny dwi'n bwysig i'r interrupted. Byddwch chi'n gyfnodd? Mae'n gweld sydd. G Déel oedd. P.S.R.0 i'i ffordd mewn P.S.R.4 i'r ffordd yschledd gynghyddiad. mewn fflushaf o gweithio eu syrthblion AutoLedion ond ond hynny wedi gweld gan swyddfa ni. Iawaynau yr un gweithio y pethau llawnau yn meddwl honno mae'r Pes benderfyn-ynghylch, lle'r Pes benderfyn-ynghylch yn ymddir iawn yma, lle'r Pes benderfyn-ynghylch yn ymddir iawn, ac yn gweithio y ffordd yn gyflawn i wahanol. Felly mae'n ddefnydd. Eryddiad, y p parece benderfyn yn cyflawn hynny is PSR 15 compatible, so it will be the first micro-framework that supports this standard, there will be others coming. I'm the lead developer of Slim Framework, we will become PSR 15 with Slim 4, probably towards the middle of this year. Like all the PSRs, except for the Coding Standard ones, it's essentially a set of interfaces, and the one we care about is a middleware interface. PSR HTTP server is our namespace, and it is just this middleware, sorry, this interface. One function, process. So you have to implement process to implement a component in the pipeline. This function takes two parameters, a request, which is a PSR 7 request object, and a handler, which is a pointer object to the next elements in the pipeline. And as I said, you must return a response. As you can tell from this interface, we've used type-inting and we've used return type-inting, it's a PHP 7 or above interface. If you're on 5.6, you need to be upgrading. Fortunately, Wim has just told you how to. So middleware looks a bit like this. This is a really simple time in middleware, I implement the middleware interface, and I do something before anything else. So the first thing I do is some work. In this particular case, I'm just storing the current time. Then I call handle on the handler object. So that sends me down the middleware pipeline. So now I've left control of my middleware, and all the other middleware components are now being executed in turn, all the way down to my action. My action will return a response, come back through all the middlewares before they get back to here as that response return. So I now have a response object that has come from my action. I then do some more work after the rest of my application has executed. In this case, I simply get the current time it took to execute, and I write it to the body. So I can modify the response object on the way out of the middleware chain, and finally, I have to return my response. Obviously, you would never write code like this in the real world, because you might not have HTML going out of the response, so you would probably check that is HTML before you go and write an HTML comment. So that's what PSL Midware looks like. How do we get started with Expressive? We use Composer. Everyone uses Composer. We've already agreed that Composer create project, Zen framework, et cetera. Then what Zen Expressive does is it leverages a feature of Composer to act as an installer. Composer is a really, really good project. There are really clever people over there, so we've leveraged their work. What we do is, when you do your create project, we hook into the Composer system to ask you what type of Expressive project you want. There's a whole set of questions that come up that you can't read. They look something like this, so a nice blue background or cyan background. What type of installation would you like? Then you can say, well, I want a minimal one. I want a flat one. I want a modular one. However you are laying out your particular Expressive application, there's multiple choices. Then we ask you which router you want, which container you want, whether you want templates, et cetera. We just ask all the questions, and then we build up a project that matches what you are trying to do. Then we prove that we are not designers. What did we do before Bootstrap? You get a really, really simple demo HTML page just to prove to yourself that you've actually installed a project. Obviously the first thing you do is wipe all this out because nobody on the website looks like this nowadays, but you are now running your Expressive website and you are confident that the pipeline is working. This is a standard directory structure if you pick the flat format. If you choose the minimal, you will get a lot fewer directories. We have a number of stuff going on here. You can see a bin directory. The bin directory is where any scripts go that you need to run within your project. Config holds configuration. Config autoload holds application instance configuration, such as your database credentials and things like that would go into the autoload folder. They get loaded automatically for you. The ones in the root config directory, like pipeline and roots, are how you configure the way your application is structured. Public folder fairly obvious. That's going to be the folder that the web server will serve from, so you can see an index.php in there. That is your entry point. Source, that's clearly where your source code goes. Test is clearly where your tests go because you are obviously all writing tests. That source slash app directory acts as a module, so you can live in your own namespace particular code. We can create multiple namespaces within source in order to separate out our code, maybe reuse it between projects or just for organisational purposes. All your code goes in here. There's one class that lives in your app folder, which is called config provider, which enables configuration of the code within this code base. That's where you will add the IR registrations for this particular module. Looks something like that. We've got a source folder and a test folder again, and then we've got handlers. It's a word we use for actions nowadays, because it's modern, I assume. There's our home page handler. That is an action. Ping handler, that is another action. Templates, that's where our HTML code goes. This time I've chosen twig, so that's why I've got a twig extension. Handlers look like this. The other half of PSR 15 is the request handler interface. The request handler interface has a method called handling it, which takes a request, and you must return a response. This is your action. Your action is at the end of the pipeline chain, so you have to return the response containing the HTML that you want to send out to the browser. Part of the PSR7 implementation is an HTML response object. You can guess what that one does. It sets content type to HTML, sets a 200 status code, and you put your HTML in as the first parameter of the constructor. We now have the world's most simplest hello world application. Not probably the world's most simplest. Within expressive. Let's write a web page. It has come up with a demo. My normal demos are things like crowd applications. I normally use bookshelves, or in the old days I used to use CDs, but nobody knows what CD is anymore, so that one went. What's current today? You know what's current today? Bitcoin is current today. This is a Bitcoin conversion programme, which will tell you how much one Bitcoin is worth in pounds, dollars, or euros. I chose this one because there's a free-to-access API that gives me the data, which is why it's nice and simple to implement. Downside, of course, is I have to keep changing the screenshots because the value changes so frequently. So we need a route. We're going to put our new page on a URL. Our page URL is going to be slash Bitcoin. To do this, we put some code into the config slash routes.php file. Firstly, we have to specify the method. This is going to be a get request. It's good practice nowadays to be aware of which methods are accepted by your action, so this particular action only accepts get requests. We have a method for all the HTTP methods. Get, post, put, patch, delete. If you wish to have one action respond to multiple methods, you can use either any method, or you can use route, and then you pass in a list of the methods you support. It's very difficult to justify those two. You probably should not be using them. Roots have a pattern. This is the URLs that the router will look at in order to work out if this action needs to be executed or not. So the pattern can be a literal string. We're going to use fast route here because that's the same thing, and it also fits on one slide that way. Literal string slash hello. You are on match it slash hello, we're going to run this action. Placeholders, we don't want to have to create loads and loads of routes with all the possible human names in the world, so we can have a placeholder called name. I put it in braces, and now I can do app get hello slash hello, and this action will run. I can make them optional, but square brackets around it. I can nest my square brackets. So slash news, or slash news slash year, or slash news slash year slash month. I can't do slash news slash month. It doesn't work like that. It's associative left and right. Lastly, I can constrain my placeholders via regular expressions. I know you all love regular expressions because you're all developers. We're all really good at them, aren't we? Fortunately, other people are, so we just steal other people's regexes. But this sounds nice and simple. Slash d for digits, exactly four of them please. So here I specified that my year must have exactly four digits and all things work wonderfully. Roots can have a name. So I can name this route Bitcoin. Why would I name a root? I mostly name a root because SEO experts think they control the URL nowadays. So sooner or later, you've written your application, and someone comes along and says, you know that URL slash Bitcoin, we need to change it to be slash Bitcoin hyphen this hyphen that hyphen the other hyphen something else in order to make it more visible. So when they do that, you don't want all the links in your website to have to be changed as well, all the places where you refer to it. So we can use a URL helper to generate the URI based off the name. So here I'm generating user.profile, I pass in one of the parameters, requires the name, and it will generate the URL for me. So no matter how often the marketing types rename it from profile to something else, it will continue to work. And lastly, roots have a handler, which, if you remember, is the same as an action. So roots have an action, a handler, the code that is run only for this particular URL pattern. Handlers receive a PSR7 request, and they manage your business logic. Because you are really good developers, most of your code does not live in your controller. That's what we used to do, but we have learned. Most of our code now lives in our model layer, in our service classes, in our domain layer, and we have a very small action, which just operates against the PSR7 response, marshals it, deals with our business logic, and then it must return the PSR7 response. So say it's been implemented as a PSR15 request handler. If you need to create one of these, there's a tool for doing so, Composer, because we like Composer. Then the tool is expressive, handler, and it will go and create your action class for you. And as of yesterday, it will also create the template file for you as well so that you get a good start in place to create your new actions. This is what it looks like. This is a fairly typical action. They're not very big. You will notice that there is one function in the action. We don't have controllers. It's an action class. So if you're coming from Zenfra work 2, for instance, we had a controller class with multiple action methods in it. We now have one action, one class. This makes testing much easier. It makes dependency injection much cleaner. So that is the way we go nowadays. There's our handle method. As before, PSR15's handler interface. There's our actual work. All the actual work related to this particular web page is done in some service, the Bitcoin service, BTC service, and it magically gets current prices. It's really cool about this. I don't have to show you the code for that, so you can just assume it works. See, it's in the model. Someone else's problem. And then we return an HTML response. But to generate the HTML, we use a template. So we have a twig template, which is referenced by app, colon, colon, Bitcoin, hyphen page, which will render out our data and make it visible to our users. That Bitcoin service needs to be injected into our action. You'll notice that we didn't instantiate it within the action itself. We pass it in via the constructor. We do this to make everything much more testable. So dependency injection is baked into expressive. It is much easier to use it than to not use it. So you might as well use it. So we're going to create a constructor for our action. It's going to take the template interface, sorry, the template render interface for rendering our templates, and it's going to take our Bitcoin service. It doesn't do much just to assign some to variables. In order to show you how that works, I'd like you to segue quickly into expressive configuration. This is a technical term. It's a mushed up array. We start with the config provider classes from our modules, so our app config provider class, and then each PHP file that lives in config autoload is mushed on top. So any file that you put in config autoload can override the configuration created by the modules. So your modules can have default configuration that this particular application can override. That's really powerful and really convenient. And it's all PHP arrays, so it's quite easy to understand. You get a number of common top-level keys, but you can create any keys you like, so dependencies, twig, validators, et cetera, the sort of keys you expect to see. Obviously, dependencies is the key we use for configuring our DI container. And you can use the same configuration for all the different DI containers we support. So this is what a config provider looks like. It is simply an invocable class. So you use a magic method, unscore, invoke, and then we have to return an associative array. For convenience, we tend to split it out into subfunctions or submethods so that this doesn't get too big, makes it easier to reason about, and makes it easier to fit on slides when you're presenting. So guess what get dependencies looks like? It returns a subkey, factories. It also does invocables, and it does aliases and a whole lot of other stuff. Look up the DI container documentation if you care. I'm going to return a factory, so I have to tell the DI container what factory I wish to execute for a given class, an action class in this case. So I'm mapping my Bitcoin page handler, which is my action class against my Bitcoin page factory, which is a class that knows how to create the action class. Then my dispatcher, when it decides it needs to render or execute the Bitcoin page handler, will ask the DI container, please give me a fully configured action class please. And the DI container will run my factory for me. So my factory looks like this. A factory is a fairly complicated word. We use it to make ourselves sound clever. There's an awful lot of terminology in software industry. We have this terminology to make sure that we feel superior to junior developers. There's probably another reason, but I'm not quite sure it is. So a factory simply means we have to return a new instance of a class. That's all it means. We are creating classes. So again it is, I'm going to invoke method, and I return a new Bitcoin page handler. That's my action class. That's all my factory has to do. And I can pass in my dependencies that my constructor for my action needs, and I retrieve them from the container. And the reason I do that is that the container will not construct them unless we need them. So I'm avoiding creating classes that I will not necessarily need for this particular request, which is a little bit more efficient. And that's it. That's forgotten that far. We've now got our action done. We have our service class injected into our action. We're executing our service class, hitting the API. We're going all the way back. Now we need to display it to the user. We call that template in expressive. It's a view layer. You've already seen that. We have a render method, which takes the template name and the data that you wish to pass through to the template to be rendered. They're name spaced with the colon, colon tends to be the same PHP name space, but lower cased. And it maps to a directory on disk. So app, colon, colon maps to the app directory. And then the other half of the template name, Bitcoin hyphen page, maps to the file name on disk. The .html.twig is provided by expressive because we've chosen the twig renderer. Had we chosen the ZenView renderer, it would have been bitcoin hyphen page .phtml because that's what ZenView uses. So it does that automatically for you. I quite like twig. Anyone here use twig? Yeah, a few people. It's quite nice. It comes from the Sancia people. They're clever. We like the blot. They've got a fairly good manual. And that's one of the key things I use for evaluating whether I'm going to use a component or not. Can I understand the manual? So twig.symphony.com will give you the manual. Key things you need to care about. Variables are in double braces. Control statements are in brace per cent. And comments are in brace hash. So this is a typical template. Quite a lot going on there. Key things we care about. You notice there's a brace brace for rendering out a particular piece of data. So I'm rendering out the symbol. So is it dollars or is it euros or is it pounds? And then I'm rendering out the rate, which is a float. So I number format it. So I pass it through what twig calls a filter in order to make it look quite pretty. Two decimal places is plenty for normal fiat currencies. We have some control statements. There's a for loop. So for pricing prices. And that's brace per cent. And then we have template inheritance. Template inheritance is how we do layouts in twig. So any given template that we choose to render can inherit from a parent template, which can inherit from a parent template. Again, you can have a tree as deep as you like. And the key thing about the template inheritance is it provides this cohesive look and feel. So our default CSS, our default JavaScript structure around the HTML can all go in one place so we don't have to copy and paste it around. You get a base skeleton. And you pick which particular skeleton you want by that extends line at the top. So in here I'm extending the default layout. So my base skeleton looks something like this. If you go to the actual base skeleton, there's an awful lot more code in it, but the fundamentals, it looks something like that. There's some HTML. I'm not very good at HTML. There's some tags here. Key things are blocks. So here I've got a block content, which my original template can override, can provide the content for. So block content there, block head, and then block title can live within block head. So I get to choose whether to override just a title or whether I need to override everything. I get a lot of flexibility to it. I quite like it. I think it's worth investigating. And you get this, which proves that I know even less about styling HTML pages than the Zen people do. These prices were correct two days ago. Don't base your investment decisions on them. So one bitcoin is worth roughly $8,500 ish today. Unless of course there's been a massive spike in the last day and a half that I don't know about. Great. We now have a working website. You now know how to build an expressive site. It's not particularly complicated. How cool is that? Very good overview. I said that expressive had a wider ecosystem, had components from the wider Zen ecosystem. So let's look a little bit about adding some components. We're going to add the ability to enter our own amount in pounds and find out how many bitcoins there are. This time we need lots of decimal places. So 123 pounds and 45 pence is worth .0 to 0011 bitcoin. There's not many bitcoin for 100 quid. How do we do that? We need a form on our web page. That's bed easy. I don't know a lot about HTML, but even I can write a form in HTML. This is where I recommend you write a form in your websites. Use HTML, it's quite good at it. We create a form. A little bit of twig with brace, brace amount there. We have a label, input filter, a button. Finally we're going to output our results. Number format, six decimal points this time. Now we need to validate the data. You're not going to accept any data from a user in any form whatsoever without validating it. Do not ever trust a user. They are untrustworthy fundamentally. Send input filter is quite a good input and filtering and validation components, so that's one we'll use. There are other ones out there. I use this one even when I'm writing applications in other frameworks because I think this one works remarkably well. It's quite a simple system. We have our untrusted data. We pass it through a filtering layer. We pass it through a validation layer. If it is valid, we can use that data. If it's not valid, we will reject that data. We're going to install it via Composer. That's how we install every component in the world. We're going to do that. Because it's a Zen framework component, we are aware that you are installing it into an expressive application. Again, we hook into the magical composer and we thank Jordan Nils for the extra work they did for us. Not for us personally, but we are leveraging it. We can ask you, do you want to automatically install the config provider into your expressive application? You will answer yes, which is a default because that's what you will want to do. We will automatically configure the Zen component into your expressive application for you. It will automatically register the dependency injection factories required and any configuration required without you having to think about it. We create an input filter. Input filters look something like this. They're basically an array. You use a factory. As you can imagine, a factory creates a new instance. Our factory will create a input filter object for us and we pass in an associative array. The key of each element in the array matches the name of your form elements. Or if you're doing an API, the name of the keys in your JSON payload that you're accepting. Then you have your filters. Filters are destructive. They normalize the data. If you're doing telephone numbers, this is where you remove the spaces that the user has added, or the brackets, or the hyphons, or whatever else they added. Just remove them because you don't care about them, but the user types them in. So we can remove unneeded information from the user. I'm asking for a number, so long as I convert it to a number. Two inches is a really, really bad choice, mind you. Then I can validate it. Validation is a yes, no question. Does this data meet this criteria? If it doesn't, we throw it away and reject it. I'm going to say it's a number that we provided the amount greater than zero. We're not doing negative numbers in this application. This is a process that we looked at before in terms of the flow diagram. The key things here is we call is valid in point three, and then we have to retrieve the sanitized data using get values. So code wise, it looks something like this. So back into our action, there's our handle method. We retrieved the data from the user using the standard PSR7 methods, get query parameters in this case, because I would like to have URL that my users can email around. If it's post data, I would use getPalsed body. So we know where our data came from. Did it come from the query? Did it come from the post data? Set it into my input filter, and then I can call isValid. Is this data valid or not? If it is, then I'm going to retrieve the data using get values, and then I'm going to send it off to my service to do all the real work. So all the real work is still done in my domain layer. And then I can, if on a failure, sorry, if the data is invalid, like it's minus three or something like that, I can retrieve the error messages using get messages, and then I can display them to the user and say, you messed up. Try again. That's it. So to summarise what I've told you today, SendExpressive is a micro framework. It's a future of the Zend components project. We still have Zend MVC. If you're used to the Zend Framework 2 or Zend Framework 3 way of working, that is not going away. It will be supported for a long time ahead. And there's a gentleman called Zerkus who is currently working really hard to modernise our monolithic framework, so that is still in existence. I think SendExpressive and the micro framework paradigm is way more relevant today. I think you are way more likely to be creating micro services and smaller websites going forward. We see a lot more use of JavaScript on the front end that is using XHTML request, XHTTP request, sorry, to talk to back end services, and micro framework is a far better way to implement those sorts of websites. So Expressive is really good at this. It comes with a router, it comes with a DI container. The DI container is really important. You should be using DI nowadays because it simplifies testing. It also encourages you to split out your business logic from your controller actions. And that means that your main code base will and can outlast your framework usage. Depending on the type of app you write, the sort of apps I write, I've changed frameworks but kept all the core logic before now. Separation out is really important. Because Expressive comes from the framework community, we already have a wide ecosystem. Got a lot of other components that are useful for creating websites and APIs. If you are creating APIs, I highly recommend you look at the problem API component and you look at the how component. They make generating compliant and nice to use APIs. So much easier. The error handling one, one pet peeve of mine is if you are going to write an API, please make sure you supply the error messages in JSON, not in HTML. This isn't difficult stuff. It's a component installed away with Zen Expressive. Composer requires Zenfrowe work, Zen Expressive problem details and your API will always return JSON if that's what the client has asked for. Or XML because it's a nice standard. I highly recommend you take advantage of the wider ecosystem with your micro framework. You get to pick the components that work best for you. So we see a lot of Expressive applications that use illuminate and eloquent for their database or use doctrine for their database. You're not tied to using ZenDB just because it comes from the same project. Use the components that work best for you. That's what Expressive gives you. You want to learn a little bit more about this. The documentation is on docs.zenfrowework.com, fairly obviously. The actual code base, if you want to actually look at a code, is on GitHub. I write about this stuff, acrobat.com in the Zen Expressive category. The Zenfrowework people will blog if they do it on framework.zen.com. If you actually want a book, I've heard of books, apparently they're still a thing. Then Matt Setra has written Zen Expressive Essentials, which is quite good.