 I just thought probably more people will come in but that's okay. So welcome. I think I'm the first talk of a brand new track on Drupalcom, so yay. Either I make it or break it this track. So rediscovering the SPL. Today, obviously I'm gonna talk about the SPL for those who don't know me. My name is Joshua Tyson. I'm a freelance consultant and trainer at my own company Techademy. I am the founder of Techanalyze.io, a startup because everybody has to have a startup nowadays. If you have any questions about this presentation or me in general, that's okay too. You can find me on my blog, on my email and my Twitter if you want to. The Techanalyze startup, if you want to check it out, what we do is we assess people on their technical skills, so mostly PHP, but we hope to have Drupal in there very soon. You can actually try it out if you like to. So this is all the advertisement you get for today. Well, not quite, but I want to start with a question for you. Who have you has ever used the SPL? So that's a fair amount of hands. Okay, rephrase a bit. Who have you used the SPL without going nuts? That's a whole lot of less hands going on. Okay, so let's assume that you want to start with SPL, where are you gonna check for? SPL documentation. And where can you find SPL documentation? And don't say stack overflow, because many of you would probably look there. It's on php.net. Very, very good documentation normally, but if you go to slash SPL, you get something like this. It's one sentence in the introduction, there's one comment, but people say that's not fair because they changed the layout and everything. Yeah, that's true, because nowadays it looks like this. And there's not only one, but there are actually two comments. So we doubled the amount of comments on the SPL. Yay. Still, not very helpful if you want to start. And this is basically the problem with dealing with the SPL. There is not enough documentation. There are very few examples, even on the php.net website. You can find some examples on blogs all over the internet, but some of them are even wrong or missing stuff in some cases. And this is what really, really gets us going with SPL because the SPL, in fact, is already 10 years old and nobody is still using it the way it should be used. Now, normally every SPL talk you will visit, including mine, will talk about five different chapters like interfaces, iterators, data structures, exceptions, and all the miscellaneous functionality that comes with the SPL. I'm going to talk about that too, but I'm not going to talk about the awesome things because pretty much everything is awesome. I'm going to talk about all the scary stuff that happens in SPL, and there's a lot of that too. Now, the thing is don't get scared because whatever I'm going to tell you, because this is like a tough love thing. I really like the SPL, but there are lots of things that can, where you can trip over, where you can trip over. So I'm going to try to explain to you the things you have to be taken to consideration when you're dealing with the SPL. But the SPL by itself is really awesome, even if I'm bashing it the whole talk. So, let's talk about interfaces. Does anyone know the Travisible interface? Some of you do, okay. Actually, this is not considered an SPL interface in terms of PHP. If you're going to take a look at the SPL, you won't see it in there. It's actually in another category. Whoever tried to implement the Travisible interface. Okay, who succeeded? Okay, well, the thing is Travisible cannot be implemented directly. You can implement it, but you always need something else, like an iterator or an iterator aggregate. So what's the point of having a Travisible? Well, a Travisible can be detected. So you can use, if something is an instance of Travisible, you can also use it as type-hinting. Now, if something is of a Travisible interface, you can do all kinds of cool stuff with it, especially where you're dealing with for each. Because what for each can do is not only iterate objects and arrays, but it can also iterate Travisible instances. So if you have a Travisible interface, it can do and will do magic things. Now, obviously, when we cannot implement Travisible directly, how do we do that? We actually use the iterator interface for that. Still, the iterator is not really considered an SPL interface, but the iterator is a user-land interface to make an object Travisible. So if you want to use the Travisible stuff, you should use iterator. There are exceptions, even in the Drupal code, but that's another thing. So an iterator interface looks pretty easy. There are only five methods you have to implement. So the current and key are the values you get from each iteration in for each. And then there's next, rewrite and valid, which are used internally by for each. So in all, it's a pretty simple interface to implement, but it has really, really lot of power. When we talk about iterators, there's actually a few groups of iterators. So first of all, there are the normal iterators and there's something called a filter iterator. And a filter iterator implements the same interface, but it actually gets another interface of another iterator as an input and it can filter out elements. So you can do all kinds of filtering based on other iterators and still use it in for each. I will show you an example. Cool thing with filter iterators is that you can chain them together as well. So you can chain multiple filter iterators together. Now the last one is actually not an iterator interface, but iterator aggregate interface. And this looks pretty much the same as an iterator, but it's not by itself an iterator, but it has an iterator. This is what you would use if you want to separate the iterator code from your actual object. So if you have a class that would be iteratable, but you don't want to have all the iterator stuff inside, you can have it an iterator aggregate. Now, as an example on why we would use iterators, just take a look at this code. Does this look familiar? Anyone ever written code like this? Probably you would have somewhere in the sense. So what this does is it opens the current directory, it reads all the files, so it basically iterates over all the files, and it will print the file name that is actually being iterated. So this is like one line of business logic. Now normally your business logic will be much, much larger and do much more, but this is for an example. Now, suppose you have an application like this and you went to Silicon Valley and have some startups and have lots of money to invest in an application like this, somebody comes over and says, well, this is really nice because now I can iterate over all my files in my directory, but I would like to see only my mp3 files, my music files. So okay, you go hacking and you do something like this. So what we did is we basically checked to see if the file ends with .mp3, and if so, then we print the file, otherwise we continue with the loop. Looks familiar? I probably think it does, and if you say, no, no, no, I don't do it this way, yeah, you do. Okay, so this is all nice, so we have now our mp3 hack, but all kinds of other things will happen now. What if we want to filter mp3s and JPEG files? What if we want to filter mp3s that are larger than six megabytes, or if we don't want to filter at all, or if we want to search subdirectories or maybe even multiple directories? Can you imagine how that inner loop would look like? Well, like your code probably, and mine code. But how can we test such thing? Pretty much we can't. How can we maintain it? Well, we can't, but we don't really bother because the next guy is in charge of maintaining my stuff. And how do we reuse it? Well, we can't really because everything was copied in one big loop, and now we have to maybe copy that loop over other places. It's a horrible mess. So let's do it a little bit different with iterators. So it's something like this, and even if you don't understand anything about iterators, this probably makes sense to you. So we create a new directory iterator, which most likely will iterate over a directory. And now for every file in that iterator, we get an object back, an SPL file object to be precisely, and it has all kinds of cool things like get part name, get their name, and all kinds of information about the file. So this will be the same thing as we saw before. But now let's add that mp3 hack. We can do something like this. So we have our directory iterator, and now that directory iterator gets into a regx iterator, which is a filter iterator. And what it does, it will return only the things that matches the given regular expression, which is it must end on dot mp3. Anyone spot the difference between this thing and my hacked version? Exactly, so what the difference is here is that the business logic, the inner loop basically, does not change. The only thing that change is the way how we get our values, our iterator object. And we can do all kinds of cool stuff because we could do something like this. So we can change that regular expression iterator into a file size iterator. Actually, it doesn't exist, but it shows you that if you create something like this, everybody knows what's going on. And you can change that again to a limit iterator. So what happens now is that the directory iterator will get all the files in the current directory. The regx iterator will filter it on everything that starts or that ends with mp3. The file size iterator will filter out everything that is between zero and six times 1024 times 1024 is six megabytes of file. And the limit iterator gives us actually the 10th value and then the next five. So it's like an offset limiting. And everything is done outside of your business loop. So the business loop can stay the same. The only thing that changes is the way how you fix the values. Now, if everything else from here will be blurry, this is the most important thing you need to remember. This is how you can really, really create a nice code. Not bad, right? I don't think so. Because now it's reusable. We can use the iterator everywhere we want because that limit iterator is not only for the directory stuff we did. We can do it for all kinds of other stuff like records from a database or maybe even objects in an array of entities in an array. They're testable because we can test the regx iterator separately from the limit iterator. We don't need to test everything at once. And it's maintainable. And this is especially important if you are the same guy who needs to maintain it. So there's no need to adapt our business logic as well. Cool, huh? I think so, okay. So the next one I want to talk about is the countable interface. And this is actually an SPL interface. This is in the SPL. Now to demonstrate, this is an iterator class that implements our standard iterator. I just skipped all the implementations. So, let me have to take my word for it. This takes an array, an online five. I add that array to my iterator. And now instead of looping over the iterator, I just say print count iterator. What will be the output? Any guesses? Any guess is okay. Actually, it is one. And the reason why it's one is because you are counting an object. And count function says, okay, this is an object. It's only one object, so I'll just return one. This works for everything that you do in count. Now, let's change it a little bit. Let's implement the countable interface on my previous iterator. And if you implement the countable interface, you have to implement the count function. And what this does is just return the number of elements that are stored inside the iterator. Now, I get an array again with five elements. I create my iterator, I print count it, and now my output will be five. And the reason for this is that the count function in PHP, or actually, yeah, the count function, is like, behaves a little bit with some black magic. What it does, if it sees that there is an object inside, it will actually take a look to see if it implements the countable interface. And if it does that, then it don't return only one. It will return the output of your custom count function. So this is a way to create your own custom object that behaves differently when you run it in count. So it could be five, but you could multiply it by two, or whatever you want. Whatever makes sense for your system. So instead of calling the count function or the count method from your class, you can just use the basic count function from PHP, and it will do all the black magic for you. And because we have an iterator now, what we can do as well is we can chain it together. So the same class, the countable iterator, we have five elements, I create my iterator, and now we're gonna chain it into the limit iterator. The limit iterator says I want from the zeroed element to the third element, so it will turn only three elements. So what will print count will do at this point? What will it return? Three? One? It will return one. Okay, so welcome to the confusing parts of SPL. And the reason is actually quite simple, because we are counting not my countable iterator, we are actually counting a limit iterator. And the limit iterator does not implement the countable interface, hence it will only count one object. This will, just by remembering, this will probably save you hours and hours of debugging on why your code doesn't work with SPL. Trust me, because I've been there, I don't want you guys to be in there, so. Take a look at things like this. So let's talk about the iterators. So we can create our own iterators, fairly easy to create, but you don't have to. Actually, I don't really create a lot of iterators at all because there's a lot of iterators already defined by the SPL. And it do mean a lot. If you don't have something that suits your needs, you can actually use things like a callback filter iterator, which just gets a callback. So the only thing you have to give it is a callback, a closure or whatever, and then it will work straight out of the box. If you go to the SPL documentation, you will see a lot of information about them, but not everything that happens. Another way of finding out on how they work is actually go to this website. Anyone familiar with LXR? If you go to this website, please not now. It actually gives you the internal source code of PHP. It will give you the C code. But this directory actually has some modeling of iterators in PHP. So when they created the SPL, or at least the iterators, they created the iterators in PHP first, and then when they were satisfied with it, they pretty much converted it to C. But the molds where they were made on, they are actually still there in this site. So if you take a look at that, you can see something like this, but this is for the append iterator. So if you have no idea what the append iterator does, and you get really confused by the documentation, you can take a look inside and you can see actually the PHP code and what it does. Might not make sense all of the time, but sometimes it's really nice to figure out how it works internally, especially because the documentation can be really bad. So there are all kinds of really cool iterators, things like iterator, iterator. Yeah, that sounds recursive, right? So wouldn't they have called it recursive iterator? Well, they could, but actually there is something called a recursive iterator already. And you can even have a recursive iterator, iterator. And what about recursive callback filter iterator? If you start with this for the first time in SPL, it's really hard to explain why these are here and why they are useful, but I will try. So bear with me. So let's start with the iterator, iterator. So what does it do? It iterates over iterators. Makes sense. Actually, what it does is it turns traversable things into an iterator. It doesn't have to be an iterator, it doesn't have to implement the iterator. It can also implement iterator aggregate or basically anything that implements traversable to begin with. If you take a look in PHP, there are other things that implements traversable, like datetime interval, for instance, and there are some simple XML stuff that implements the traversable as well. And you can turn them into an iterator. It's not always, it doesn't always make sense, but you can. Because what happens, if you take a look at any filter iterator, you have something like this. Because the filter iterators, like the limit iterator, expects you to have an iterator interface. So you cannot add something that is an iterator aggregate. So let's assume that my iterator could be something like an iterator interface or could be an iterator aggregate interface. We might not know. So what we can do is we can say, okay, if the iterator is an instance of the iterator aggregate, we want to fix the iterator because an iterator aggregate isn't an iterator, but it has an iterator. And at that point, we can use the iterator inside the limit iterator. Now, this code, you don't want to write that for every time you want to change something. So you can actually use the iterator iterator in between. So when you see something like this, it's most likely that they convert something that may or may not be an iterator into an iterator before they limit it. Confusing, I know, but welcome to the SPL. What about all the recursive stuff? Example, we have an array iterator and that array iterator has an element, full bar has an array with crux and walks, and element best. Now, if I'm gonna iterate over that array iterator, what would be the output? But what are your guesses? Okay, so it will be full bar array best. Why? Because it iterates over the elements and it doesn't matter if the element is an array internally. In the new PHP versions, you actually get a notice as well that you are converting an array to a string, but pretty much this is what happens. So, okay, it cannot do recursive by default, so let's add the recursive array iterator. So we're all done, and you get something like this. By now, you're probably throwing your Macbook out of the window. No, what you actually have to do is this. Create a recursive array iterator and then add it to a recursive iterator iterator, and then we can actually, yeah. Okay, I have no time to explain this to you. No, this is because the naming actually is wrong. There are not recursive array iterators. They actually add the possibility to recursively iterate over data. You still need to implement it yourself. So it would have been better if they called it like recursive or bold iterator or something like that, because at least you have some hints about it. It doesn't do it, but it adds the possibility. And the thing is that the recursive iterator iterator actually implements that behavior itself. You can write your own, but it's already there, so we are not using it for converting something to an iterator. We actually use it for the recursive that actually recurs. Yeah, funny stuff, I know. So recursive callback filter iterator, what would it do? So we already know that the recursive part doesn't really recursive. It adds the possibility. Callback means you need to specify a callback for it, closure or function or whatever. It is a filter iterator, so it expects another iterator in between and it can return the elements based on the callback. Yeah, SPL iterators. The thing is it has quirks, but they are easy solvable, but it will be backward compatibility breaks. If we change the naming of recursive error iterator, which I think we should, it will break a lot of code. The documentation is not really up to date. The naming can be very, very confusing. There's actually something called a caching iterator, which does pretty much everything except caching. Trust me on that one. There's something called a seekable iterator, which isn't an iterator, but is an interface again. Yay! But in the whole, the iterators are really worth it. Even if you only use things like an error iterator and use a filter iterator for regular expressions or callback or the limit iterator, that's fine enough. Then at least you're still using the iterators. Okay, the data structures. There's all kinds of data structures inside the code as well. To be honest, if I need to talk about data structures, I would spend the rest of Drupal Con explaining it to you, and still you don't know how. It's really, really hard to explain. What you really need to know is that the PHP arrays are actually quite good. There are really good general data structures. And to be honest, if you need to use another data structure, really, really considerate why you want to do it, and always test to see if it works out the way you expect it to. Because a lot of people think that if I use an SPL fixed array, then hooray, everything is very quick and doesn't use a lot of memory. This is absolutely not true. Actually, the benchmarks show you that on some occasion, SPL fixed arrays are more consuming in ways of memory or CPU time than normal memory. Or CPU time than normal arrays. And you actually are also missing all the association part because you can only use numerical indexes. So don't use things because you think they may be better because most of the times they are not. They have their own strengths and their own weaknesses. There's a thing called a big O notation. I don't know if you know that, even from school or something. You probably heard about it. These things will be important when you deal with data structures. Normally a data structure is really a balance between time, like CPU and space memory. So a large data structure can be fast, but a small data structure could be slow. It depends on what you need. So again, PHP arrays are really quite good. Internally in PHP, it uses the same data structure for things like having all your global variables for all classes, all your properties and methods are stored in something that is similar to a PHP array internally. So PHP uses it internally. So, but sometimes other data structures are better. Now, there is a talk I really want to recommend for you. That's from Patrick Allard, which does a data structures 102 or 201. I don't know which one. But it actually has a pub quiz in it. So he shows you a picture visualizing data structure. You have to guess it. I found it so funny, I want to do it here as well. So there are no prizes, I'm sorry. So first of all, what do you think a stack? Yeah, it's actually the SPL stack I'm looking for. What is this? Yeah, it's not a nice queue, but it is an SPL queue. I apologize for all the Dutch people in this one. It's a linked list while they are using two hands. So I consider it a doubly linked list, which is actually the one that SPL implement. What's this? Object storage. My favorite because I travel a lot. Priority queue, exactly. This is a bit of a, no, it's actually SPL heap, because SPL heap internally uses a tree structure. I could have a picture of a heap, but that would be suitable for this presentation, I think. This one, it's a fixed array. Yeah, people said no, it's fixed because they can actually move the satellites of the dishes a bit, but you're not going to take it home with you. So fixed enough for me. The thing is, use them wisely. If you're going to do a lot of random reads, so index one, index thousand, index five, index three million, don't use the SPL stack for SPL queue because they are used for quick sequential reads, but not for random reads. Same thing, don't use fixed arrays when you need a speed boost because you probably won't get it and you will actually don't gain a lot from it. Okay, exceptions. Anyone uses exceptions in their code? There are still people who don't. That's okay, but from now on, please do. The SPL defines a lot of exceptions, but they don't tell you what they are for, literally. Nobody can tell you exactly what each exception is for. Everybody has a theory, but it's a bad thing, I think. But the thing is you have to realize that the exceptions are grouped into two different groups, the logic exceptions and the runtime exceptions. Now, this makes sense in languages like Java, for instance, and PHP a little bit less, but they try to group it into two blocks like this. And the logic exception and the runtime exception actually extends the normal exception as a parent. Now, as an example, suppose I have a function foo, I get a string, and if the string is called the Spanish Inquisition, then you throw an unexpected value exception because nobody expects an Inquisition, exactly. This is actually wrong because it shouldn't be an unexpected value exception. It should be an invalid argument exception. Wasn't expecting that, right? That's because the invalid argument exception is based on the logic exception while the unexpected value is based on the runtime exception. Now, why does this make sense? I'll show you a little bit here. So in this case, the invalid argument exception is something from a string that the programmer, me, could actually influence. I'm the one who actually is calling foo with a certain string, even if that's user input, I could sanitize it before or do anything else before it, but I'm in charge of it. I can actually make sure that this exception does not happen. So this is what happens with logic exception. You can see it a lot, like filtering or sanitizing input. Now the thing is, suppose we have a database and we're gonna save a record, doesn't matter what it is. All kinds of things could happen, like bad things. The network could be down, the database could be full, the database could be on fire, anything could happen, but it's outside of our control. At that point, you'll have a runtime exception. So in this case, we throw a runtime exception, but we could do all kinds of cool stuff now. So for instance, we could say, let's try and sleep for half a second and we try to save again because it might work this time. If the network connection had a hiccup, maybe after a half second, it might work. So if somebody is filling out a form for like 10 minutes on your page and it presses enter and save records, returns a runtime exception, you're saying, oh, sorry, try everything over again. It's not really a good user experience. But what you can do now is actually say, okay, let's try, let's try again, let's try again, and let's do it 10 times. And after 10 times, you say, well, sorry, I tried 10 times, we really can't do it. But maybe in the meantime, it actually worked. That's a really, really good user experience. So exceptions are not always the way out. They're also there for actually retrying and recuperating from it. And in this case, if something really bad happens, so that's like a logic exception or the exception class, that's something else occurred beyond our control. And we say, okay, we cannot do anything with it. Okay, so fair enough. The thing is, and I take this as pretty much the baseline is never throw an exception or never throw the main class exception, always catch the main exception class. Now, never throw exception. What I mean is if you throw an exception to whatever that is gonna catch that exception, you are actually the same guy, probably a customer that goes into your book database and says, my code isn't working, enter, send. And you're there, okay, so what's not working? I know something is wrong, but you don't explain anything to me. Now, if you have something like a database not reachable exception or database full exception or even runtime exception, at least you know how to recuperate from it. So this is what I mean with never throw exception, but always take care of stupidity of others who might throw exception, so always catch them. Clear? Who is doing this already? Everybody's raising their hand now. Okay, so there's all kinds of miscellaneous stuff inside. Really cool stuff. There is things like auto-loading. Nowadays, we don't really care about auto-loading because everybody is using PSR0 stuff with Composer and everything. I showed you before, things like a directory iterator actually emits SPL file info classes, which are like classes wrapped on files. There are file objects, temporary file objects, array objects, which are nice, I will talk about as well, and some things like an observer pattern like SPL observer and SPL subject interfaces, which you can implement as well. Let's talk about the auto-loader because I really love this example. My jaw dropped when I actually figured this one out. So the SPL auto-loader has got a default auto-loader class, which is of a function, which is SPL auto-load call. It's by default, it is there. Now you can add your own auto-loaders on top of it with SPL auto-load register. So what happened if I SPL auto-load register the SPL auto-load call function? Anyone dare to take an attempt on what it does? Yes, it actually throws an exception. And I was amazed by the fact that it throws an exception. I think, well, okay, so they use their own stuff in SPL, but it throws a logic exception, which is okay. I would suspect something like an invalid argument exception or something, but logic exception is okay too, because we are in charge of changing the SPL auto-load call to something else. Now, what would happen if you SPL auto-load unregister the SPL auto-load call? Will it throw an exception? Well, if it's in the slides, you probably already know the answer is no, probably not. What it does, it removes all the auto-loaders that you registered. It destroys the complete auto-load stack, and if you let it, it probably will set your house on fire. I kid you not, this is internally, and I can show you later on, internally inside the source code, it will check to see if SPL auto-load call is called, the string is called, and if so, it will remove all the auto-loaders. So it's, I don't even think it's an Easter egg. I think it's debug left over. I don't know, but it's there for almost 10 years now. And please don't do this, because you will let other people have a whole lot of fun trying to debug it. I see it once or twice in real life, and these are the things that can get you. Nowadays, hopefully you don't have to worry about this one so much because of the composer and the SPL auto-loaders in there, but still, might save you some time. Okay, so I talked about the array object, which is a miscellaneous class, but it's really cool because array objects are objects that behave like arrays, but at the same time, there are not objects that behave like arrays. Confusing, it will become more confusing. So as an example, I have an array with full and bar elements in it. I say my value B becomes A, and I add an element B to B. So when I print the values of A and B, what do you think I get? Any dares? Yeah, so the A will become full bar, the second one become full bar best. Yeah? Okay, this is pretty common knowledge. If you don't, try and brush up a little bit because this is pretty common. Now, I do the same thing, only I'm using array objects with it. And you notice that I still can use the square brackets on that one, that's how they can operate. So they still look from the outside the same as normal arrays. So I have A with full and bar, B becomes A, and then B, I add an element best. So the thing is they are iterable as well. So I use iterator to array to actually convert it to an array. So what would I put B now? The same? Yeah, so what it will be is full bar best, full bar best. So when changing something in B, it will reflect on A. Anyone has an idea on why? Yeah, it's copied by reference. So B equals A, so everything you change in A will change in B as well. On the difference, when you deal with objects, objects, sorry, arrays, arrays are copied on right. So when you change something in B in an array, it will actually duplicate the value and only change it in B and not in A. There's a really, really big difference between that. And sometimes, even in some frameworks, you cannot even distinguish anymore between arrays and between array objects, but the way how you treat them can be really, really different. Anyone have an idea how to make sure that this doesn't happen? Clone, exactly. So you see B is clone A in this case and then everything will happen the same thing as before. Nasty stuff, right? But on the whole, SPL is really cool. So how about SPL and Drupal? To be honest, I'm not a Drupal guy. I had to download Drupal for the first time and see how it works. I tried Drupal 8, the latest version, and actually it's not that bad at all. It actually, it is quite good. I wasn't expecting this much use of the SPL inside the Drupal core. It makes heavy use of iterators, which is a good thing because you can do all kinds of filtering with it in your own code if you want to. The exceptions that they are used are okay too. However, they are still throwing too many global exceptions. So I would really get rid of that because a lot of times they can use things like invalid argument exceptions in those cases. So still things changed. Data structures, they don't really use it that much, but that's okay too because probably it's not even useful in lots of cases. I think there's one or two times they use SPL stack internally, but that's it, not really that much more. So how can we make the SPL easier for us? Because, well, I can talk the whole day, but apparently you want to try it yourself and see how it works. This is the hard thing. Actually, there is a really good way. There's a book written by me about SPL at Amazon, at O'Reilly, and at PHP Architect. It's really good because all the tricks I showed you before I explained as well, also the good things. It's a small book, so it's not like this. But adaption of the SPL only will happen when developers can't become familiar with them. And since there is no real way to familiarize yourself with the SPL, you have a catch-22. So if you're gonna use the SPL after this talk, hopefully you will, do things like block about it. If you find stuff that doesn't make sense or you think like, I'm not sure how this works, add a post to either stack overflow to the SPL, documentation at psp.net. You can update it yourself nowadays. You can even vote for comments. So that's a really cool thing. Be the third one to actually put a comment in and you will be on the slides next year. And find the quirks. Find the things that you say this does not make any sense in the SPL because if we don't get the feedback, we cannot fix it. There's a lot of things we can fix, but we need more input from the people. And from that point on, we can actually solve those problems. Any questions? Like a lot. Yes. Are they willing to break back to compatibility psp7? They probably will. I don't think they will do it a lot for the SPL because quite frankly, there is no current active maintainer for SPL stuff. So everything that gets fixed in SPL right now is basically bug fixes. There are not really that many people will say, I'm gonna implement new features inside the SPL. So if somebody is volunteering for becoming an active contributor to the SPL, I know the people who you can talk to. But this is one of the issues with the SPL as well. So I reckon there will be some changes even in the SPL that breaks PC, but not a lot. But it might, but I don't think so. Okay. Any more questions? The SPL was written in, originally was written in PHP as a model and then it was converted to C code. So the reason why they did it is because to make things much, much faster. You can write the whole iterator interface, everything in PHP and that will probably work, but you won't gain that much speed as you can do with some of the iterators. The iterators actually hook into one of the really deep course of the system because it has to hook in into things like for each and everything. So there's a lot of tricky things going on and this is why they were written in C. Okay. But nowadays because you have the iterator interface and iterate aggregate, you can write your own iterators on top of that in PHP, obviously. So one more? Talked a lot about how people misuse data structures or how you shouldn't use them in all use cases, but can you give a few examples of when you should use them? Which ones you should use? Use cases for SPL data structures. Well, this is really hard because it really depends on not only what you want to do with it, but it also depends on how fast you want, how much memory you are willing to spend on some things and how much data that you have because some of these structures work very well with 10 million items, but work less efficient with only 100,000 items, for instance. So if you know that you're already going to 5 million or 10 million items, you might use data structure A while if you know that you are only going to be at max 100,000 or maybe 200,000, then you might use data structure B. So it really, really depends on what you want with your code. So there's no flowchart that you can say, oh, if you want to do this, then you must use that. What I showed you before is that you have to take into consideration that things like an SPL stack internally uses the SPL doubly linked list, which is really good for, for instance, sequential reads. So one, two, three, four, everything iterating is possible, but if you want to jump until randomly from one index to another, to another, to another, then it will be slower than what you can do with normal arrays. So there is no guide for you to tell you what can happen. The only thing, if you're gonna implement data structures, you have to benchmark it. You have to benchmark it with real data. You have to benchmark it with data that will be in the future to see if it actually makes sense and keeps making sense. So data structures can be high maintenance. Yeah, but I cannot say these cases, you should use them. Okay, sorry for that. There are some really cool benchmarks on the website. I forgot, Matthew Turland, I don't know if you know him. You have to look him up. He's written some benchmarks on different data structures, how they work with speed versus memory, and there's all kinds of information on that one as well, so you can take a look at it. Okay, any more questions? Think a few of the last ones? Cool, okay, if you have any questions and you don't dare to ask them here, just come and see me. With this, I would like to say thank you.