League CSV (and URI & Period), with Ignace Nyamagana Butera

Matt Stauffer:
All right. Welcome back to The Laravel podcast season five, where every single episode is about a particular package that's commonly used in the Laravel ecosystem. And today we're talking about a package that is not Laravel specific, but it's still something that we really love and use very commonly. And it was one of the things when I asked people, hey, what do you often use? This was one of the ones that came up the most, and that is the League, PHP League's CSV package. And before I introduce the maintainer of that package, I want to talk really quickly about what the PHP League is.

Matt Stauffer:
So the PHP League, if you go to thephpleague.com, and we'll put it in the show notes, is basically a group of PHP programmers that want to create high quality packages that have some specific standards. So they follow all the PHP fig guidelines, and they have a couple other things that they say we want to make sure that all of ours can be used this way. And they kind of created their own set of a few packages and then invited to other people who are maintaining or creating high quality packages that seemed like they would really fit within that kind of mindset to also kind of brand them as PHP League packages.

Matt Stauffer:
So, we've had some folks on the podcast before, we've definitely had Frank de Jonge on the podcast before. And I think we may have had Jonathan Reinink on the podcast. Yeah, we had Jonathan Reinink, Barry vd. Heuvel. I think that's it who's been on the podcast before. So those are folks making these great PHP packages. They're not Laravel specific, but they are very useful for Laravel. So today we're going to talk primarily about CSV, but a little bit about other ones. And so I want to introduce the host. So today with me is Ignace Nyamagana Butera. And Ignace is going to talk to us a little bit about the CSV package. But before we go there, Ignace could you just say hi to the people and introduce yourself a little bit?

Ignace Nyamagana Butera:
Yes. Hi to everyone. So my name is Ignace Nyamagana Butera. So I am currently living in Belgium, but I was born in Africa, in Rwanda, and then I travel a lot. I've been in couple of countries in Africa. And I've been in Switzerland, and in France. And now I've settled to live in Belgium. I'm married, I have two kids. Yeah, that's about it about me.

Matt Stauffer:
And is your day job as a programmer, I assume?

Ignace Nyamagana Butera:
Yes. So my day job, I've been programming in PHP since... I like to say I've been programming since Foreach was introducing PHP. Which, you know when Foreach was introduced?

Matt Stauffer:
Okay, that's been a minute. That's awesome. Very cool.

Ignace Nyamagana Butera:
And I started in college. I was doing the website for the alumnaes. From where I was, I was doing biology, molecular biology. And my brother who was a developer, but not PHP, he handed over me a book about PHP and said hey, for your website you could learn this language. And it was PHB three at that time, I think. And since then I've been coding on and off. And finally around 2010, I finally decided, okay, I'm going to make it professional now. And that's when it started.

Matt Stauffer:
I love that. I'm now looking up the PHP release timeline, because I'm wondering when I started using PHP. I don't know if it was PHP three or PHP four. So you might, you might predate me. But I had a similar experience of my brother... Well, my brother did PHP and he coded in VM on a Linux system. And so when I wanted to make websites and I learned HTML, this was pre CSS. He's like, you got to learn PHP. You got to learn VM. You got to learn to work at the terminal. So that's why I did it. And I'm trying to look at the history. Okay. So PHP forum came out in the winter of 1998. Okay. So yeah, so I started in PHP three as well. So we are similar timelines here. I love this. So PHP four came out in 1999. So yeah, I started in PHP three as well. So we're old. But I love it.

Matt Stauffer:
Okay. So today we're going to talk about the CSV package that you created and maintained. So let's talk about, so for anybody who wants to follow it, of course we'll put links to everything in the show notes. But it is basically the PHP league/CSV. So we kind of have some questions we always go through. So let's just start with, what is the elevator pitch for the CSV package. If somebody just has no idea and you got 30 seconds to tell them, what does this package actually do? What problem does it actually solve?

Ignace Nyamagana Butera:
If I had to pitch it really quickly, like in one minute, I would say that League CSV is the equivalent to JSON encode, JSON decode, for CSV.

Matt Stauffer:
Okay. Love it. Simple and easy, right? So, if you are working with CSVs... And if anybody doesn't know, a CSV is sort of like a more standardized version of an Excel document. So if you think of an Excel document, if you've ever opened up any Microsoft document in a text editor, there's just all this crap everywhere. It's very Microsoft encoded, right? Well, CSV is just the data. It's a comma separated value. Meaning for each of your rows, it's a new line. And for each of your columns, it's basically separated by commas, right? Comma separated values.

Matt Stauffer:
So CSVs are these very, very, very simple documents that just contain basically tabular data, right. And so I've found personally, and I'm curious if this is true for you as well. And yes, is that when I want to deal with programmatic data, stuff that we're interacting with in a computer, that individual humans can also consume. Because Excel can open CSV and save CSV, numbers can open and save CSV, google sheets can. CSV is by far the best way because it's so simple and structured, versus having to write something and read something at parses Excel. That's primarily why I'm working with them. Have you found that's kind of what, why people are working with CSVs as well? Is because they're kind of simple and they're not specific to any company?

Ignace Nyamagana Butera:
Yeah, indeed. There's that. And there's also the fact that, to be fair when I started looking around and trying to come up with an idea with CSV. So, outside of my day job, I usually play football. I think you call it soccer in the United States. And there I was in a small championship and they were, like every weekend they were sending the results and they were in Excel and they were containing a lot of errors. And at that time I didn't know how to correctly use Composer. I didn't know how to use spreadsheet, I think, or PHP office or something like that, it was called before.

Ignace Nyamagana Butera:
And I was looking, hey, if I could just convert this into CSV, then I know I can quickly fix it in PHV. And it was like I was losing time every time having to convert it and doing something like that. At some point I said, no. I'm going to do a package, because I'm also doing the same thing at work, where we are generating reports and stuff like that. And as a matter of fact, the best format to generating reports when you have to give it to other business is CSV. It's not Excel, because CSV can be opened by so many spreadsheet application. But if you start doing something in Excel, or in number, then you are restricting the people who can read your format. But if you do it in CSV, then everybody can read it.

Matt Stauffer:
Yeah. And one caveat that I would make, and I would, I want to see if you agree with this. Is CSV is the best format for containing data. But if you're worried about passing formatting, or tabs, or sheets, or formulas, those things are difficult to have in CSV. So CSV is more like a data format. Whereas Excel and the numbers are more of like a presentation format on top of the data, right?

Ignace Nyamagana Butera:
Exactly. If you want to send some data, you can do it in CSV, no problem. If you want to start adding more complexity, more logics into what you want to send, then CSV is not the best format to do it.

Matt Stauffer:
Got it. Yeah. So before we move on to the installation story, I want to say, there is some built in PHP formatting for CSV. You've got things like fgetcsv and stuff like that. So if anybody has never worked with those before, just go look up the PHP manual for fgetcsv, and now you'll have an understanding of why having a package is valuable. It's not an enjoyable syntax and it can't do many of the things that the CSV package makes very, very, very easy. So it's not as if PHP inherently couldn't handle CSV at all. This is more like, this is going to make it a user friendly experience, where it all has a very consistent API. Is that a good way of describing it?

Ignace Nyamagana Butera:
Yeah, exactly. League CSV is basically, it's a wrapper around PHP API to make it simpler, to make it friendly, and also to make it consistent.

Matt Stauffer:
Mm. Yeah. I love that.

Ignace Nyamagana Butera:
Because there's a lot of, lot of inconsistency in the behavior of the PHP functions. And I always understand people say, oh yeah, but PHP is buggy and stuff like that. And I always say, people always easily forget that PHP is an evolving language, and that there is no RFC for CSV. Which means that everyone be it Microsoft, be it Apple, being even PHP, everyone has it own definition of CSV. So what League CSV tries to do is try to normalize things so that whoever created that CSV can be consumed by us.

Matt Stauffer:
I love that. And again, I don't normally do this, but one of the things I want to note to folks is that it's like the JSON encode and decode for CSV, but there's a lot of really cool things that you can do with it. And I know I'll ask you later about like edge case things. But some of the more common things, for example, if you were working with fgetcsv, you basically get... You're reading the CSV in as a stream, and then you just foreach over the lines, right.

Matt Stauffer:
But with the CSV package, you get things like get header, and that gives you just a certain like lines of headers. Or get records. Or you can say insert one line, or insert all, and there's all these convenient things that you could do with fgetcsv, and fgetcsv and passing a raise around. But they're not all in the same object, right. There's no kind of concept of a CSV object in PHP. Whereas you have created that idea. So you got a writer that created, or you have... Basically you have an entity that represents the CSV that you're working with, that you can do all these things with, right?

Ignace Nyamagana Butera:
Yeah, indeed. And the main gist of it was like, okay, I have this CSV, it's a document. How do I access this document? And what do I do with this document? That's the basic idea. And how do I access it? How do I add something? How do I remove something? How do I play with it around? And that's how the full philosophy of the package was-

Matt Stauffer:
I love it. Okay. So let's talk about our next common question, which is how do you install it? And are there any key set steps or dependencies?

Ignace Nyamagana Butera:
League CSV feel like you said is really a bare bone package. You could even not use Composer. So you go to GitHub, you download the archives of whichever tag or version that you want. And there is an auto loader with it. So you can use this auto loader, which is PSR-4 compliant. Or you just use Composer, and there you have it, it's ready to be used. There's no, nothing more complex than that. There is zero dependencies. Because yeah, it's fully-

Matt Stauffer:
It's just PHP.

Ignace Nyamagana Butera:
Yeah.

Matt Stauffer:
Yeah. I love it. And it's not even like the fgetcsv and S put CSV require you have any special add-ons, like every version of PHP has these. And, and for those of you all who don't know this, you literally just type Composer require league, L-E-A-G-U-E/CSV, and that's it. So, yeah, totally. Are there any lesser used features that are cool? Or any just kind of cool things you've seen people do with it? Or are there any features of it that we haven't talked about so far that you want to say, oh, I really like that you can do this or that with CSV?

Ignace Nyamagana Butera:
One of the things I liked about League CSV is that when I tried to build it, I tried to build it to... So the first version that nobody should look at, because it's really filled with so much error was like, okay, I want to do a wrapper around SPL object, which is SPL class, which is within the PHP core. And that you can use to write on CSV. And the more the version goes increasing, the less I try to be, I wrap better I think, the functionality. So I had more and more the PHP system inside the code, which led me to seeing people asking me question. And when they ask me the question, I'm like, hmm. Is it really possible to do that in League CSV? And I look at the code and say, oh, yes, indeed. It's possible.

Ignace Nyamagana Butera:
I never thought about it, but the way it is written now it's possible. And I just went, oh, that's nice. And one of the things is, I had a colleague, because he was using another CSV package. And he said, ah, but I have nine millions rows and they're zipped. So I don't know what to do. Should I first unzip it and then tried to put it in? I was like, hmm. I say, I was like, hmm, this is strange. Maybe I should do a feature where I can unzip and do stuff. And then I look at the code and I said, hmm, wait. And I see that in PHP you have this function called just open. That basically opens zip file on archive file.

Matt Stauffer:
I had no idea.

Ignace Nyamagana Butera:
If you open it, you get a stream.

Matt Stauffer:
You can just stream it. Yeah.

Ignace Nyamagana Butera:
And then if you use like reader, create from stream. You open your stream, and then League CSV we can automatically work on with your zip archive. So don't even need to unzip.

Matt Stauffer:
Yeah. That is very cool. And if anybody's not familiar with Streams, basically, if you imagine the vast majority of the time that you're working with League CSV, you've got these smaller documents and you just read the document, the whole thing's in memory. And you got this kind of PHP object that represents that document you're passing around. But, like Ignace mentioned what happens if you've got a document that's so big that you maybe don't want to open the whole thing at once because you might want to stop when you hit the right row. Or you don't want to open the whole thing at once because it's going to use up so much memory and slow everything down or whatever else.

Matt Stauffer:
Streaming is something that's built into the core of PHP that allows you to basically just pull things one line at a time. So it knows where you are in that file. But at any given moment, it's not holding the whole file on memory, it's only holding that particular line in memory. So whether or not you're dealing with zip files, League CSV makes it really easy for you to just say, this is a massive document and I want you to stream it to me. And you basically end up in a foreach loop. And that foreach loop, each one is only the one... It's the only one that's been read at that point. And you can do whatever you want with it. You can also stop it if you... Let's say you find the one you want 150 rows in, it's not going to read the remaining five million or whatever. So, but what you just introduced is the idea of streaming out of something that's in a zip file without actually unzipping it on the file system, is that right?

Ignace Nyamagana Butera:
Exactly.

Matt Stauffer:
That's wild. I had no idea you could do that at all.

Ignace Nyamagana Butera:
I know, but at the moment I was like, hey, but yeah, I can do that. That's nice. And boom, it was done.

Matt Stauffer:
That's so cool.

Ignace Nyamagana Butera:
I don't know if I... Yes. I told my colleague, I said, yeah, you can do that with League CSV. But I should mention it somewhere in the documentation. I don't know. But yeah, you can practically use an archive file without even opening it. Then boom-

Matt Stauffer:
That's very cool. Okay. Well that's a great answer to cool things people can do with it. So the next question I have for you is, do you have any development roadmap? And do you need help from people? Because you know, like in my experience League CSV is kind of done. But do you have any vision for the future? Are you kind of like, no, it does what it needs to do and I'm happy with this?

Ignace Nyamagana Butera:
There is one thing I need to note is like, if you look at the code base of the moment I tagged 9.0 0. And the code base of today, which is I think 9.8 something, you will see that there has been a lot of free writes. So for the end user, nothing has changed. But for me, a lot of things has changed. A good example is, when in PHP 7.4, a new argument was added to fgetcsv. And that argument, which was welcomed is something that says the scap character can be empty.

Matt Stauffer:
Okay.

Ignace Nyamagana Butera:
Because prior to that, it was not empty by default. I think it was the slash, or the other. I don't know how you could say it in English. Not the backward slash-

Matt Stauffer:
Yeah, back slash.

Ignace Nyamagana Butera:
Yes, the back slash. And it was mingling and it was not good for interoperability with, between CSV.

Matt Stauffer:
Oh okay. Got it. Okay.

Ignace Nyamagana Butera:
So, it's not a bug for me. It's like they fixed the issue by removing this back slash.

Matt Stauffer:
Got it.

Ignace Nyamagana Butera:
But, if you do that, you need to be able, in League CSV to understand that after 7.4, it can be empty, but before it cannot.

Matt Stauffer:
Got it.

Ignace Nyamagana Butera:
So, when that feature was discussed on the PHP mailing list, someone came to me and say, hey, can you do this in League CSV, because I'm using it a lot. And I say, hmm, let me think. And I build a whole polyfill.

Matt Stauffer:
Very cool.

Ignace Nyamagana Butera:
So, since PHP 7.2 up to 7.4, it was only polyfill. But nobody could see it. And in the newer version, because I stopped supporting everything below 7.3, the polyfill is gone. But nobody can see it.

Matt Stauffer:
Yeah.

Ignace Nyamagana Butera:
You see. So, the public API, I agree with you, is done.

Matt Stauffer:
Yes. But the internals you're still doing the-

Ignace Nyamagana Butera:
But, the internals are continuing to be maintained, so that it can always do whatever it needs to.

Matt Stauffer:
I love that. Yeah. So you're continuing to do work silently that allow us to all, to ignorantly continue using the same public API. I love that.

Ignace Nyamagana Butera:
Exactly.

Matt Stauffer:
And I just pulled up the commit log between 9.8, which was January of this year to today, and there's 52 commits. So you're clearly... As recently as three days ago. So you're clearly still working on this.

Ignace Nyamagana Butera:
Yes. Because right now I'm doing two things. First I had to battle... Let me rewind a bit. My vision of the package is that League CSV should not be coupled with... For instance, let's take the Symfony or Laravel. Whenever they release something, they need to be in line, let's just say, with the PHP version. So they need to follow 8.0 or 8.1. And if there is something that goes wrong... Like for instance, right now, I think everybody's pushing to go to 8.1 in order to fix some issue with PHP. On the other hand for League CSV, for instance, like I say, something was fixed in 7.4, but nobody knows, except for the maintainers. So, it's a question for the maintainers to say, okay, which version of PHP should I maintain?

Matt Stauffer:
Yeah.

Ignace Nyamagana Butera:
And it should not be coupled with a release version specific to PHP, because otherwise it means that I should be on League CSV. I don't know, 12 or something. But the public API did not change. What has changed is the code inside so that everything keeps on working.

Matt Stauffer:
Totally. Got it. Yeah. Okay. I love that. And I mean this... No, keep going.

Ignace Nyamagana Butera:
So right now for me, I'm like, hmm, which version should I stop maintaining? Right now I know that I will not maintain 7.4. So, that is done. So if you look at the master right now, 7.4 is done, is gone.

Matt Stauffer:
Okay. Oh yeah, I see that.

Ignace Nyamagana Butera:
8.0 is gone. So the next version probably, I don't know when it'll be up. But the next version, so 9.9 I think at the time, will be 8.1 going forward.

Matt Stauffer:
Okay. I'm looking at... At Titan, we have this website, PHP releases.com that makes it really easy for me to see when each version comes out. And so I'm seeing... So 8.0 stops getting actual new releases at the end of this year, basically?

Ignace Nyamagana Butera:
Exactly.

Matt Stauffer:
Okay. That makes a ton of sense. Okay.

Ignace Nyamagana Butera:
Yes. But at the same time, I'm not leaving user behind, because 9.8 still supports 7.4, 8.0 and 8.1. So, I'm trying to have the balance, like you said, I'm the only maintainer. So I have to be able to maintain, to make sure that all the fix are correct, and that I can maintain has much PHP version that I can. So in my mind, I'm like, okay, if I release the next version, let's just say in September or in October, it'll be like... 7.4 would be, I won't say dead, but more or less. 8.0 will be also on its way out. But I know that 8.1 and 8.2 will be there. So right now what I'm doing is looking at all the change logs in 8.2, to understand if there is something changed in the behavioral series. And if something is changed, then I need to come up with a strategy to add it already some polyfill or something. So that when 9.9 goes up, everything is fine for 8.1 and 8.2.

Matt Stauffer:
Well, and one of the really nice things about that is, you're finding yourself in a situation where if, let's say that people doing an old version of PHP are stuck on 9.8 of League CSV. Well, the changes you're making in later versions are not new features. They're just things that work in 8.0 and 8.1, right? Exactly. So, as long as the API that exists works on 9.8, they should be happy, right. So you can just stay there as long as you need. I love that.

Ignace Nyamagana Butera:
The only caveat is like... But that's another philosophical question is, the reader and the writer in CSV are not final. So it means that for each version, whenever I want to deprecate something which is inside, I still need to keep it.

Matt Stauffer:
Got it. That's a little bit of a challenge for you as a maintainer to just kind of remember where it is, and what's. Depending on what else and everything like that. Yeah, for sure.

Ignace Nyamagana Butera:
Yes. So that's why, if I have a roadmap, I know that at some point I want to release a 10, just to get rid of all the things that is deprecated in the interval.

Matt Stauffer:
Yeah. I love that. You're like, just so I can take all those things out of my brain and off of my shoulders, right?

Ignace Nyamagana Butera:
Exactly. But right now, even in 9.9, sometimes there's stuff that I used to have. Because if you look at some code you will see that. Or if this is a version PHP 7.3, you can do this. If it's 7.2, you cannot do this. So there's a lot of ifs everywhere.

Matt Stauffer:
And you'd just love to get rid of those and just make a nice new clean one.

Ignace Nyamagana Butera:
Exactly.

Matt Stauffer:
Totally. And I mean, I'm a very big fan of package maintainers, maintaining backwards compatibility when it doesn't cost them a lot. And that doesn't mean sometimes it doesn't cost them a lot, right. Sometimes it's just costing us a lot and that's life. But I think a lot of package maintainers just say, well, it's the new in the hotness, so I'm just going to switch to it and everyone else can deal with it. And so as a package maintainer, I can really appreciate the amount of work that you're putting in to try and make sure that people who are on a somewhat outdated version of PHP are not now just stuck because their company's constraining them to do that.

Matt Stauffer:
At the same time, at some point it's just going to make us miserable. Like at some point somebody's going to be like, hey, what about PHP 5.6? And you're going to say, sorry, man. You know, sorry, I'm not going to help you. So there's always a balance you got to walk. And I appreciate you walking that balance. And also I wish you the best in getting to 10.0. And being able to just let some of that old code go.

Ignace Nyamagana Butera:
Yeah. There's a lot of things that... I was looking at the code, I said, oh God, if I could remove that, and remove that, and remove that. But I cannot. So I need to keep it.

Matt Stauffer:
I absolutely believe you. Well, so since you do have some things that you are doing going forward, is there any help you need? Or is it all this stuff is so esoteric that really our help is just continuing to use it and love it. I mean, can you use any help on this project?

Ignace Nyamagana Butera:
Yes.

Matt Stauffer:
Okay. Tell me?

Ignace Nyamagana Butera:
Simple one, but effective one. Like I say, I started a... I didn't know if I said it, but I started a new job. And one of my new colleague came to me and say, hey, I love your package. What can I do to help you? I say, listen, my English is bad. So the way I write it is bad. So if you can only fix the typo, I will be the happiest man in life.

Matt Stauffer:
Oh, that's awesome.

Ignace Nyamagana Butera:
And he did it. Okay. And he went through all the documentation and he fixed the typo, and I was like, man, that's awesome. Because I would not have been able to do it myself.

Matt Stauffer:
Right. So typo's, documentation, just any that sort of stuff. Okay.

Ignace Nyamagana Butera:
Yes. Another thing is like, for instance, the website, I did it I think five years ago or something. I don't know if people still love the website, how it is. But I'm not talking about the content. Hopefully the content is correct. But at least the design and stuff... I want to do some, maybe some tailoring or stuff like that, but I'm really bad at it. I'm really bad at everything front end. So if someone wants to redo the website, he's welcome to do it. I'm fine with it. So, at one point I wanted to do, to have a logo for League CSV. But yeah, again, I'm really bad at everything which is GIMP and Photoshop and stuff like that, so.

Matt Stauffer:
Got it.

Ignace Nyamagana Butera:
If people want to do that, I'm fine with it.

Matt Stauffer:
Okay. Well, I think that there's at least one listener to this podcast who regularly designs logos for open source projects. So I'm very curious whether Kaneko hears this. But yeah, so we logos, design, documentation, catching typos, anything like that? Totally makes sense. So you're going to keep maintaining the core, but if the rest of us can just help it be a little bit prettier, or a little bit better front end or whatever.

Ignace Nyamagana Butera:
Yes. And also they can submit features. I have no problems with submitting feature. Recently, so for now in the master, I finally made the League CSV a monorepo. So added something that I have built long time ago, but it was in a separate package and on a separate organization, my organization where I dump or everything, all my experiment, basically. It was Bakame something. And I added back to the main branch now, to the main CSV and I created. So hopefully I, when 9.9 goes out, I will also release something called CSV Doctrine.

Matt Stauffer:
Okay.

Ignace Nyamagana Butera:
So it's just something to improve CSV is if you already have Doctrine on your system.

Matt Stauffer:
Okay. Got it.

Ignace Nyamagana Butera:
Right now... But this is really like the baseline right now. Right now, it's just, you can use Doctrine Collection to supercharge the way you want to filter your CSV. You don't need to do that if you are in the Laravel community. Because in Laravel you have something that did not exist like I think four or five years ago, which is Lazy Collection.

Matt Stauffer:
Okay.

Ignace Nyamagana Butera:
Before, I would always say to people, hey, yes, use Doctrine. But now that you have lazy collection, full disclosure before last year, I was not using Laravel at all. So I'm starting to use Laravel for like three to four months now. But I knew about collection, and I knew that collection was based on RA, but lazy collection is based on generators. And those are more in line with League CSV.

Matt Stauffer:
Yeah, definitely.

Ignace Nyamagana Butera:
So today, for instance, if you want to filter and you don't want to use all the filtering of League CSV, you can. You just take your... For instance, go back to our Jzip file of the CSV, of nine million thingy. So you take it, you open it using League CSV, and then you give it to lazy collection. And then you have all the full Laravel filtering and stuff that you need.

Matt Stauffer:
I love that. And we actually just had an episode about lazy collections. Trying to remember exactly when, we'll try to link it in the show notes. So we actually had an episode of this pretty recently and talking about how freaking amazing they are. And I had never worked with lazy collections prior to that episode. So I'm here for this, I'm here for this iterator work. And again, it's just like you're saying, it's very similar to when you don't want the whole thing at once. And I kind of think that's the pitch that he made in the podcast episode as well, is its like, if you want to iterate over them where you only get the one at a time versus loading them all in collections. So, but I'd never even imagine being able to tie the power of lazy collections into this. So you're just making my brain do sparks right now.

Ignace Nyamagana Butera:
So yeah, but the equivalent, you can do that with Doctrine, using Doctrine Collection you can do it. And, but because Doctrine is a bit different, I had to build a small wrapper around it.

Matt Stauffer:
Okay. Got it.

Ignace Nyamagana Butera:
Another wild idea that I have right now, is that I think it was in version 9.6 or 9.7, I don't know. I added an interface, but prior to that, there was no interface in League CSV. And now there is one, which is called Tabular reader. Basically it means that League CSV, the reader. But also the results set, the one that you get after filtering, they both share the same functionality and the same feature. So it means that... But this is wild. I'm playing with it around right now, but I haven't finished with something that is stable. Which would be that you could use Doctrine to manipulate a document like if it was a table.

Matt Stauffer:
Okay. That's really cool. Wow.

Ignace Nyamagana Butera:
I'm just in early stage, it might work. It might not work, but.

Matt Stauffer:
Yeah, yeah, yeah. But it's a fantastic idea. One of the things that I've really enjoyed with stuff like CSVs, and also just a lot of other kind of things that are maybe not always at the forefront of things, is when people imagine the idea of using these syntaxes, these APIs that we're used to using all the time, like for example, Doctrine. There's also a PHP package that, or Laravel package does something very similar called Sushi, where you're using an Eloquent style thing to deal with sqlite databases, but they're in memory sqlite databases or something.

Matt Stauffer:
So it's sort of like, you have all the value of working with Eloquent. So Laravel's Eloquent database system without actually having to worry about having your database set up. Because it's using it either in memory or just a file system that's in storage or something. Whatever it is, it's so simple that you're not actually setting up your database or anything like that. So it reminds me of this a lot. It's like just because we're working with a data store other than a traditional database, doesn't mean we can't still have these really nice expressive modern interfaces like you're talking about. So I think that's a really cool idea.

Ignace Nyamagana Butera:
But like I said, it's an infant idea. Right now I'm just playing around. Will it work? Will it not work? I don't know.

Matt Stauffer:
Okay. Well I know we have a few more to talk about, so let's move onto those real quick. So, normally each of these is only about one package, but when we're talking the beginning, you mentioned two other packages that you maintain. That I just figured, why don't you just... We won't do the whole set of five questions about them. But can you just tell us a little bit about your two other packages that you wanted to share about?

Ignace Nyamagana Butera:
Yes. So the first package is a League URI. So it's also a package on the league package. And that one was built... What happens that the first company I worked in was more or less an advertising company, and they were receiving like thousands of URI, and they needed to rewrite them every time. And even though PHP is a web application language, it doesn't have a URI class.

Matt Stauffer:
Right.

Ignace Nyamagana Butera:
So I try to model in iteration, what I would call the perfect URI class. And I had one version, and between I think version two and three, there was PSR-7, which come with its own URI. But because I disagree a bit with how PSR-7 is working, I still continue with my package. But I added in that package, PSR, URI compliant.

Matt Stauffer:
Got it.

Ignace Nyamagana Butera:
But still I have my URI, which is independent. So the signature is identical to the one of PSR-7, but we disagree on what I, what most people would say it's detailed, but for me it's not details. So the main detail is for me, any component can be knowable except for the part. But in the PSR-7, they are all string every time. So you cannot make that distinction between a component which is empty and a component which does not exist or is not present.

Matt Stauffer:
Okay.

Ignace Nyamagana Butera:
That's the first distinction. And the second distinction is that the URI from PSR-7 is only requiring to support HTTP and HTTPS. All the other schema are not required.

Matt Stauffer:
Okay.

Ignace Nyamagana Butera:
But my URI support all the possible schema that you want.

Matt Stauffer:
Okay. Things like FTP and mailto, I guess? And other stuff like that?

Ignace Nyamagana Butera:
Yes, exactly. Mailto, FTP, FTPS and stuff like that. All those are supported.

Matt Stauffer:
Oh, very cool. And if you... We'll link at the show notes, but if you go take a look, you can... If you've ever worked the URI management in JavaScript, that's going to look very familiar for you. For example, that you can give it a string and you can say, give me the scheme, or give me the host, or give me the value of Q. And it'll either give you nothing or give you the value, whatever. I love that.

Ignace Nyamagana Butera:
A fun fact is that... I don't know if it's the beauty, is that you have the RFC for the URI, and then you have the definition of the URI from the W... What is the name?

Matt Stauffer:
The WhatWG, the web working group or whatever that one is?

Ignace Nyamagana Butera:
Yes. But those two are not, they're not compatible. Or they're more or less compatible, but they have differences.

Matt Stauffer:
Right. And you're trying to cover both of them, right? In yours?

Ignace Nyamagana Butera:
Exactly. So if you try to cover both of them, then sometimes you end up in a situation like, huh, okay. What should I do?

Matt Stauffer:
I have to make a decision here, right?

Ignace Nyamagana Butera:
Exactly.

Matt Stauffer:
Love that.

Ignace Nyamagana Butera:
Exactly. So.

Matt Stauffer:
But again, this is another one of these examples where like, for the really simple aspects of URL parsing, I'm like, oh, I could just do that myself. But then I understand, anytime I've looked at any of those, the RFC or anything like that, I go, oh, there's aspects of URLs that I've never considered. And some of them are often very simple. For example, the idea of having an array of entries. I know about that, but I wouldn't always think about it until later. But some of them are even more complex, things that I don't even know exist. And so for you to be an expert who fully has internalized all of these RFCs and the PSR-7, and you did it. And now I just have to, I get to benefit from your work. That's what I love about open source packages, is I don't have to become an expert now, right?

Ignace Nyamagana Butera:
Yeah, indeed. And another thing that I think... But that's, for me, maybe it's because I'm curious. But I think that one thing that I like, because I maintain all those packages, is that every time I do, I also learn something. So you start saying, okay, I'm going to be well, okay. Whatever PHP is doing is bad. I'm going to do it better. But then you realize that your better is not that better. And that what PHP does, even if it had some shortcoming, you see that the people who did it had thought about a lot of things.

Matt Stauffer:
Yeah.

Ignace Nyamagana Butera:
So you become a bit humble first. And then you realize that the world is like, it's not only PHP, it's all the other languages and how all the other languages interpreted you, right. I was like surprised the first time when I said, huh. So Java did like this, and Python do like this, and PHP does like this, and Ruby does like this. You have four ways of understanding a query string.

Matt Stauffer:
Yeah. And again, the fact that you've done that means I don't have to now. Thank you.

Ignace Nyamagana Butera:
Yeah. But if you... Like I say, I was working in advertisement and we were receiving... In advertisement you have your URI, and then in the query string, you have another URI, which is uncoded. And then you have another one which is uncoded in the uncoded. And then you are like, hey, which one? How do I decode all that? At that moment, you will say, okay, I will use URI. Because URI handle all that for you.

Matt Stauffer:
Very cool. Now I should've named this before, but just like the last package, just like CSV, PHP does have a native function for parsing URL, parse_url. So that's what you were referencing when you said the way PHP does it. But again, it's... Now I guess I should ask, is the URL package built on parse_url or no?

Ignace Nyamagana Butera:
No. It used to, it no longer does. Why? Because parse_url is a fast parser. Meaning that, for instance, if you have a router, yes. I would say, definitely go with parse_url. Because the router will only deal with the path. But if you really want to have something which is valid, then I would say don't use parse_url.

Matt Stauffer:
Got it. Okay.

Ignace Nyamagana Butera:
Because parse_url, it's parsing, it's not validating.

Matt Stauffer:
Okay. That's helpful. That makes a ton of sense actually. Thank you for that. Yeah.

Ignace Nyamagana Butera:
And another thing, parse_url was built prior to the RFC.

Matt Stauffer:
Oh, okay. Got it.

Ignace Nyamagana Butera:
Most of the shortcoming of parse_url is because it was built prior to the RFC.

Matt Stauffer:
Okay. And if anybody wants to know about these RFCs, if you just go to URI.thePHPleague.com, which we'll link in the show notes, you can see a link to the RFC. You can see a link to the URL living standard, and you can see a link to the PSR-7 interface. So all these things that Ignace is talking about, you can... If you really want to nerd out about those things, there's link to all of them there.

Ignace Nyamagana Butera:
Exactly. And again, if you want to change the website to make it better, I'm open for PR.

Matt Stauffer:
Got it. Love it. All right. So let's move on to the last package of the day and then wrap it up, because we're getting close on time. So what's your last package you want to share with us?

Ignace Nyamagana Butera:
The last package is Period, which is another package that I built based on my previous work. Which was basically, I have a report and business saying, I want the report for the last month. And I had a big debate with business when I said, what do you define last month? And some say last month is the first day of the month up until the last one included. And I was saying and, last month is the first day of the last month until the first day of the current month. And there was a big debate. And they were like, yeah, but why are you thinking like that on this? And I say, yes, but if you include the last day of the previous month, then you are living out maybe a microsecond, or a second or something.

Ignace Nyamagana Butera:
You need to include the first and validate dates, let's call it like that. So that you are sure that whatever you do, you will always have the correct period, the correct interval. And based on that, I created a simple value object, which has the first date and the last date. And that can do a lot of calculation around that. And now the value objects got increased with a lot of methods and a lot of things like a template, and Gantt Chart to visualize the period and stuff like that.

Matt Stauffer:
Got it.

Ignace Nyamagana Butera:
Yeah. It's really powerful. And the one thing that I like about it is, it works with datetime immutable only, and it works with any type of datetime implementing object. So it can work with Carbon. It can work with Chronos, it can work with whatever daytime package that you want, because it only cares about the interface and PHP base functionality.

Matt Stauffer:
Love it.

Ignace Nyamagana Butera:
And both Chronos and Carbon just increase those functionality, but they will work.

Matt Stauffer:
Okay. And for anybody who's not familiar with these, there is like an inherent PHP, once again. So there's inherent PHP class for date intervals. There's an inherent PHP class for datetime, stuff like that. And even for periods. But once again, if you go to the documentation period.theleaguephp.com, you're going to see the fact that working with those systems is often very difficult. And many of us have never run into a circumstance where we need them. So I built a couple calendar type tools, so I really need to deal with them. And once you need them, you're very grateful that they exist, right.

Matt Stauffer:
You're like, oh my gosh, how could I imagine possibly saying one hour before and after this thing, or one date before and after this, when you... How are you going to handle the beginnings and ends of months? Like you said. How are you going to handle the beginning ends of years? It becomes very complicated when you think about those things. So this package is really a wrapper around a PHP function that many of us don't even know exists. But if we did work with them, we would see, like many of these other ones that's very difficult to work with. And the benefit of this is you're basically giving us a very easy and reasonable syntax for common tasks that you would do if you're dealing with these date periods, or sequences to make it very easy as possible. While you're not re recreating the wheel, right. You're just giving us access to easier ways to work with the existing PHP versions, right?

Ignace Nyamagana Butera:
Exactly. The thing is, what I try to do with my package is, I don't try to hide PHP functionality, I just want to make it easier for accessibility. Which means that someone wants to have something more complex and stuff. Oh, go, please go ahead. You can use my package, because they will expose everything PHP has to do. But if you just want to, like we always say to answer to the 80% questions. But yeah, you can use this package, and 80% of your answer will be there and you don't have to think too much about it. And like I said, for each of those package, I learn. So it's not just me saying, okay, I know everything. No, that's why there are iteration. That's why there it's not version one it's version five or version 10. Sometimes people laugh, is like oh yeah, version 10. Like in node community where you can have version 12 or something like that. No, it's nine because I had to go to version nine to get to a stable API with something which resemble how people will use it.

Matt Stauffer:
Yeah, totally.

Ignace Nyamagana Butera:
So it's trial and error. And I think that most maintainers, I think they're humbled enough to say, oh yes, okay. I made some... But sometime people may think that, yeah, they think that they're higher. No, no, no. We try to stay humble. And there are mistakes. And if you look at the code, and yes, there are mistakes sometimes, that's why there are bug trackers. And we try to improve and that's all. We just developer like everybody else. So that's all.

Matt Stauffer:
Mm-hmm. Well, it's interesting because you and I didn't know each other prior to this, but I've used your packages, and I can tell this is someone who's creating packages in a way that I value. And therefore I was like, oh, we got to get this in. And then granted people also all said, let's bring the CSV package in. But I got excited because I think you can often tell a lot about the mindset of the person who's creating a package by using it. Because you see, oh when X, Y, Z needs to be handled, has it been handled. Or when you go to the issues and somebody's asking, can you really help me with this thing? How does this person respond? And time, after time, and after time, I would see you interact with the community or with the API, whatever, in ways that show that you have these thoughts where you'd say, oh, I can make a mistake. I might need to do it a little bit better. Or I need to consider both this RFC and this other one.

Matt Stauffer:
So I just want to say thank you for being an example of how to be a package maintainer that really walks all of these balances that we're talking about really well. Between making sure you implement every single technical standard. You build something that's really manageable and easy for people to use. And you're constantly asking the question of, what's the best thing I can do today to basically make it the best for the people today and tomorrow. So, totally appreciate that. Thank you for any... And I think that if anybody else is a package maintainer or an aspiring package maintainer, they should just listen to the way you're talking about this, because I really love your approach to these things, so.

Ignace Nyamagana Butera:
Thanks.

Matt Stauffer:
So I know we're like super, super, super late. We're way past time. So before we cut, is there anything else you want to share about this or anything else? And if not, how can people follow you and support you?

Ignace Nyamagana Butera:
They can follow me on Twitter. Mostly, I am on Twitter. They can just subscribe to the packages, look at how the packages are involved. And like I say, the best compliment I can have is people opening question, sending PRs. Is not because your PR is not accepted. That what you did is not worthwhile. Because I know that there is a contribution guideline that say, oh yeah, your PR needs to have, needs to follow this, and to needs to be green everywhere and stuff like that. But I have a couple of occasion except some PRs that were not green. I put myself in the shoes of someone submitting a PR, because I also do submit PRs to other packages and to other things. And one of the best compliment that you can have is someone that say, hey, I see what you try to do. I think I could make it better. But I will merge your PR, so that in the history of the package, we know that you are the one who introduced it.

Matt Stauffer:
I love that.

Ignace Nyamagana Butera:
I remember sometime I was telling to people, I will merge your work and work with it. I will maybe improve it or make it different, but I want your commit to stay in the history.

Matt Stauffer:
Love that. That's really cool.

Ignace Nyamagana Butera:
Because it's a way also to show people gratitude, because they try to do something. Sometimes, okay, you are forced to say, oh no, this will not go into the packet because X, Y, Z. But if it can go, but I won't say no because he forgot a coma or something like that.

Matt Stauffer:
Right. Totally.

Ignace Nyamagana Butera:
Because a coding style is not passing. Hey, it's not a big deal for me.

Matt Stauffer:
Once again, yet another reason why I appreciate you, so. Well last question, because there's one thing you didn't cover here. If people want to give you money, is there a way for them to give you money?

Ignace Nyamagana Butera:
Yes. I think I have a sponsorship on GitHub. I'm really bad at all that. So, like I always say I'm bad at marketing myself. So I have one. So yeah. What I would say is, that if you sponsor me, you're not sponsoring only CSV, you're sponsoring all the packages. We didn't talk about the... For instance, the PHP domain parser, that was built by Jeremy Kendall. At some point he told me, hey, can you take over the maintenance? I said, yes, why not. Because I was using it for URI. And I'm still maintaining it. Up until now I even released, I think, a version six last year or something. But like I say, if you sponsor me, you're not just sponsoring League Csv, you're sponsoring all the packages that I'm maintain.

Matt Stauffer:
Wow, I love that. And we'll make sure that the link to your sponsorship page is in the show notes. But for anybody just listening who wants to type it's github.com/sponsors/nyamsprod. N-Y-A-M-S-P-R-O-D. Which is also the same username for Twitter. And all of these links will be in the show notes.

Ignace Nyamagana Butera:
Yeah.

Matt Stauffer:
Awesome. Well, I cannot thank you enough for the work you've done on all these packages, the things you've shared with us about these packages. But also the things you've shared with us about how to be a good open source maintainer. I think this is a really fantastic episode that I'm going to really kind of encourage people to listen to just for, hey, what does it look like to be a great person and open source? So thank you Ignace for being that for us, I really appreciate you.

Ignace Nyamagana Butera:
Thank you for having me.

Matt Stauffer:
All right. And for the rest of you guys, we'll see you all next time.

Ignace Nyamagana Butera:
Okay. Bye, bye.

Creators and Guests

Matt Stauffer
Host
Matt Stauffer
CEO Tighten, where we write Laravel and more w/some of the best devs alive. "Worst twerker ever, best Dad ever" –My daughter
League CSV (and URI & Period), with Ignace Nyamagana Butera
Broadcast by