0:02 please welcome Ryan [Applause]
0:24 Chandler uh hello welcome to LaRon EU
0:27 and welcome to my talk from zero to
0:30 static analysis hero
0:31 uh let's start off with a little bit
0:33 about me in case you don't know who I am
0:35 uh my name is Ryan I'm a software
0:37 engineer and recently joined the laravel
0:40 team uh where I'm working on Forge Vapor
0:43 envoyer I think this is my third week
0:45 fulltime in the role so it's all still
0:48 very fresh uh I'm from Essex in the UK I
0:50 don't expect you all to know where that
0:52 is uh so I typically just say it's right
0:53 outside of
0:55 London uh if you want to follow me on
0:58 Twitter SLX or blue sky you can follow
1:00 me using that handle uh or if you want
1:02 to do some light reading while you eat
1:04 lunch you can visit my website where I
1:07 publish blog posts and write about programming
1:09 programming
1:13 stuff so static analysis uh put your
1:15 hands up can hardly see you but put your
1:17 hands up if you think you know what
1:24 is okay mix bag we've got a few a fici
1:26 nardos here getting ready to fact check
1:32 so for those of you who don't know what
1:34 it is already I've come prepared with
1:36 this wonderful statement from Wikipedia
1:38 uh that says static analysis is the
1:41 analysis of computer programs performed
1:44 without executing them or to put it into
1:46 simpler words static analysis tells you
1:48 things about code but doesn't actually run
1:50 run
1:52 it now when we say the words static
1:55 analysis most of us tend to think about
1:58 PHP Stan or some but it's actually a
2:00 generic term that covers quite a wide
2:02 range of
2:04 tools and I actually like to describe
2:06 the different types of tools uh with a
2:09 scale one that focuses on spice levels
2:12 uh do we have any fans of spicy food
2:15 anyone again yeah mix bag
2:18 cool so on one end of the spectrum
2:20 you've got your mild sort of plish
2:22 levels of spice things like syntax
2:25 Checkers they make sure your PHP code is
2:28 actually valid PHP code uh tools that
2:29 count the number of lines of code in a
2:32 project uh or even documentation
2:34 generators for your apis or even your
2:36 code uh they're just looking at your
2:38 code and figuring out what's what from
2:40 dog blocks these tools don't really get
2:42 in the way they don't make you swear or
2:45 Panic they do a really simple job and
2:47 they normally do it quite
2:49 well and then you move up the scales a
2:50 little bit and you get to your medium
2:52 spice levels you have things like
2:54 linters they do their job they do
2:56 slightly more than a regular syntax
2:59 Checker telling you about the uh casing
3:01 of method names or the placement of your
3:04 braces tabs versus spaces like silly
3:06 things that nobody ever argues
3:08 about and then you've got your code form
3:09 matters that take some of that
3:12 information uh and basically fix it for
3:14 you and they're good they typically stay
3:15 out the
3:18 way and then you have your traditional
3:21 static analyzers like PHP Stan or S uh
3:23 running in Easy Mode they're not doing a
3:25 lot just the
3:27 basics but all of these types of tools
3:28 are still relatively simple uh there's a
3:30 bit more to it when it comes to
3:31 configuring them a little bit of bike
3:34 shedding with your team about whether
3:36 variable should be snake cased or camel
3:38 cased uh but you talk about it come to a
3:40 decision and then forget about it until
3:43 someone new joins a team and questions
3:45 everything but for the most part they
3:47 put in a good shift and you never really
3:49 have to worry about them unless there's something
3:51 something
3:53 wrong and then the very end of the scale
3:56 is where you find the hot spicy and for
3:58 most people hard to manage category of
4:01 tools uh so these are things uh like PHP
4:04 St or S but running at really high or
4:07 max levels every single opinion or
4:10 feature that the tool has will be
4:12 enforced on your code and you'll either
4:15 really enjoy it like you spice lovers uh
4:16 and have a great time looking at
4:18 infinite type errors or it will slowly
4:21 drive you insane and you'll start to
4:24 suffer and then you get humans us
4:25 because we are just biological static
4:27 analyzers you know we write code but we
4:29 spend more time reading it and figuring
4:32 out what it does and we're also
4:33 incredibly opinionated for the most part
4:35 just like PHP St s when it comes to
4:37 programming uh whether we've got our own
4:39 ideas of what code should look like or
4:42 ideas that we've picked up from
4:44 others uh now I'm not a psychology
4:46 professional uh this isn't a psychology
4:48 presentation so we'll take humans out
4:50 for now but it's a good thing to keep in
4:52 mind as you listen to this talk because
4:54 you'll notice that a lot of the stuff
4:56 that static analyzers are capable of
4:58 will actually negate the human part of
5:00 the question
5:02 so we've got our Three Spice levels uh
5:04 and I think most people can relate to
5:06 the Emojis uh you know you mod spice
5:08 tools like syntax Checkers they're
5:11 easily manageable no struggles they stay
5:13 out of the way then the medium spice
5:15 tools you're still pretty happy you're
5:16 comfortable you're not fidgeting at the
5:19 dinner table but in some cases you might
5:21 think it's a little bit too much and
5:23 then the spicy ones where the majority
5:25 of people would rather avoid them
5:27 because they tend to inflict pain uh
5:29 you're constantly battling error
5:31 messages trying your hardest to suppress
5:33 them but they get a second wind and they
5:35 come back to bite
5:38 you so I've only got like 25 minutes uh
5:39 for this talk so I want to narrow down
5:41 the context a little bit because I could
5:43 be up here for hours talking about this
5:45 and focus on static analysis that falls
5:47 into the medium spicy range uh since I
5:49 think that's where most developers will
5:52 see the gains and
5:54 benefits specifically I want to talk to
5:56 you about
5:58 conformance now everything I talk about
6:00 is going to be focused around PHP stand
6:02 since I'm pretty sure this is the most
6:05 popular static analyzer in the ecosystem
6:06 uh and some of you are probably already using
6:13 it so what do I mean by conformance
6:17 well as your code executes the PHP
6:19 engine is basically going through a long
6:21 list of things that need to be checked
6:24 uh a bit like SpongeBob's list here and
6:27 this is what we call runtime or dynamic
6:30 analysis so these runtime checks are
6:32 designed to prevent these sort of things
6:34 so using a class that doesn't exist or
6:36 calling a method doesn't exist could be
6:39 something simple like a spelling error
6:41 uh we could have a method or function
6:42 where we've given the wrong number of
6:48 argument and these areas can actually
6:50 have a huge impact on your project or
6:51 product if they make it all the way to
6:53 production uh your users are going to
6:56 see 500 server error uh when they try to do
6:57 do
6:59 anything which normally leads to to more
7:02 support requests which could ultimately
7:04 end up with a loss of income because
7:05 your users aren't going to be too happy with
7:07 with
7:10 you but the exact checks that PHP
7:12 performs at runtime are the exact same
7:14 checks that a static analyzer like PHP
7:16 stand performs uh but the only
7:19 difference is PHP stand does it before
7:24 code so some of you might be saying well
7:27 you know PHP storm does that or vs code
7:29 does that and you're not wrong those
7:31 tools can can do some of or most of
7:33 those checks uh but you're assuming that
7:35 all IDs are created
7:38 equally think of the poor developers who
7:41 can't figure out how to quit Vim you
7:45 know sorry Vim users if there are any
7:47 I'm sure you would have said
7:49 something but different IDs and
7:51 developers use different configs uh and
7:53 it's quite hard to get those different
7:55 editors to behave exactly the same when
7:57 they're built fundamentally different
7:59 you could force everyone on your team to
8:01 use the same Editor to combat that uh
8:02 but then you've got the opinionated
8:04 humans in the equation again everyone
8:09 preference another group of you might
8:11 also be thinking well I've got tests
8:14 that can catch these problems and tests
8:17 are great but they normally are written
8:19 to prove correctness rather than
8:21 incorrectness so making sure that a
8:23 method Returns the right value when
8:26 given the right arguments that sort of
8:29 thing for your tests to actually Act
8:31 like a static analyzer you need 100%
8:33 test coverage which the majority of
8:36 projects won't have and shouldn't have
8:38 writing tests to cover every single
8:41 scenario or code pathway is a huge uh
8:44 time investment and honestly 99% of the
8:46 time it's not worth it uh what's most
8:48 important to us is that our code is
8:51 doing what we expect to happen uh what
8:54 most of us would call the the happy
8:57 path so a tool like PHP stand should
9:00 work in addition to your IDE and test
9:02 it does the same checks that PHP does
9:04 just without running your code is
9:07 capable of inspecting and analyzing your
9:09 entire codebase all at once you could do
9:10 this yourself but you'd have to go
9:13 through every file and every dependency
9:15 and and remember those details as you go
9:18 along and I mentioned that not all Ides
9:20 are created equally if you have a
9:23 separate dedicated static analyzer like
9:25 PHP stand you only need one config file
9:28 and that same config is used by all
9:30 developers on your team regardless of
9:32 their editor or
9:34 IDE but more importantly a static
9:36 analyzer doesn't need to be executed
9:39 manually uh you can just like your tests
9:41 make it part of your commit hooks or
9:44 your CI build pipelines so if it fails
9:46 and produces an error you can prevent a
9:49 problematic PR from being merged in the first
9:54 place the static analyzers aren't just
9:57 about conforming to PHP set rules uh
10:00 they're also about flexibility and being
10:01 able to customize the tools to follow
10:04 your own personal
10:07 rules things like making all classes
10:10 final by default anyone do that in
10:14 here oh yeah that's a small
10:16 crowd uh injecting class dependencies
10:18 instead of using
10:21 facades uh injection over facades yeah
10:24 okay yeah fair enough uh nothing too
10:27 controversial the problem with these
10:29 sort of checks is that unless you're in
10:31 incredibly consistent when you're
10:34 writing or reviewing code they often go
10:37 unnoticed uh so by adding PHP stand or a
10:39 similar tool to your belt you can go
10:40 back to focusing on the more important
10:42 stuff like architecture or design
10:45 decisions in the code uh the tool
10:47 essentially becomes a team member it
10:49 takes that load off of you and handles
10:55 background uh but but Ryan how do we do
10:56 these things well I'm glad you asked
10:58 thank you um we're going to get a little
11:00 bit more technical uh but hopefully you
11:03 can follow along and learn something
11:06 new so to to customize things to our
11:09 likin we need to understand how PHP uh
11:11 PHP stand itself performs its analysis
11:14 or more specifically how it processes
11:17 your code the first step in the process
11:19 is taking your code your PHP files and
11:23 sending it through a parer now the parer
11:24 is the thing that's responsible for
11:27 taking a string of spaghetti characters
11:29 that otherwise have no meaning and
11:35 meaningful uh in this context something
11:37 something meaningful is the as or
11:40 abstract syntax tree so this is a
11:44 structured representation of your
11:47 code so let's imagine a class in our
11:48 project called Fu hopefully that's big
11:50 enough uh it's got a deprecated
11:52 attribute something that was recently
11:54 added to PHP a food property a
11:57 Constructor and a save method pretty simple
12:00 simple
12:02 when that piece of code is sent through
12:05 the passer the as that's produced might
12:07 look something like this so we've got a
12:10 class statement node that's the the top
12:12 level node in this case and that node
12:14 itself forms like a small tree where
12:18 each branch in the tree is another node
12:20 so you'll have a node for the class name
12:22 since it's meaningful you might have a
12:23 list of nodes for the properties and
12:26 methods and then another node for the attribute
12:26 attribute
12:29 list and this tree like structure is the
12:33 entire basis of the abstract syntax tree
12:36 every single thing that is Meaningful in
12:38 your code has a dedicated as node and
12:44 connected so once you've got that as
12:47 it's been generated PHP stand can then
12:49 start to Traverse it so this is a
12:51 process where you start from the root
12:53 node uh that could be a class statement
12:56 a function statement or an expression
12:58 and you visit each node in the sube you
13:00 work your way down the
13:03 branches so going back to the as for our
13:05 example food class we start at the top
13:06 with a class
13:09 statement you'd see that it has a name
13:11 child node so you'd visit that node and process
13:12 process
13:16 it you might then process the attribute
13:18 list and then you can go through each of
13:20 the class member nodes too so the
13:23 Constructor then the save method and
13:29 property now what tools like PHP stand
13:33 do during this build process is uh build
13:35 up a repository of information so that
13:37 it can be referenced later on or when
13:38 actually performing the
13:42 analysis every class interface enum uh
13:44 function method property trait
13:46 everything in your project will be
13:48 stored somewhere in this
13:50 repository PHP stand then adds like a
13:53 reflection API on top so that you can
13:55 query for certain things uh like
13:57 retrieving a particular class or getting
13:59 a function so that you can look up as
14:02 return type that sort of
14:05 thing then when you configure PHP stand
14:07 you normally Define a list of paths that
14:09 needs to analyze uh so this will be your
14:11 application code config database
14:13 migrations everything that's important
14:14 in your
14:17 project and then it repeats those steps
14:20 and traverses every PHP file found in
14:22 those paths the traversal step here is
14:24 slightly modified so instead of looking
14:27 for classes or functions instead it
14:30 tries to apply analysis rules to the
14:33 code so this is where things like type
14:39 place so now that we've got that out of
14:41 the way let's actually look at what it
14:44 takes to write a custom PHP Stam rule uh
14:46 let's write a rule that prevents you
14:49 from calling the value helper in a laral
14:51 project when you don't really need to uh
15:00 is no can I not see hands
15:02 let's cheat
15:04 it uh if you're not familiar which most
15:06 of you aren't apparently um it's a small
15:07 helper function provided by the
15:10 framework that Returns the value that is
15:13 passed to it or if you provide a closure
15:16 it invokes that closure and will return
15:18 the value that the closure returns so in
15:19 this instance a string has passed
15:21 through so the function is just going to
15:23 return that string uh but in this case
15:26 we're passing through a closure so it
15:28 will call that closure and return the
15:31 result of one + 2 which is
15:34 three uh our custom PHP Stam rule is
15:35 going to tell you off for doing
15:37 something like this uh there's no need
15:38 to call Value here since we're not
15:40 passing through a closure we could just
15:42 use the hello string directly it could
15:45 be a variable or a function call but we
15:47 don't need to call Value uh I'm going to
15:49 do this live so hopefully it all goes to
15:51 plan um but I think it's nice for you to
15:53 follow along as I actually write the
15:54 code instead of just reading it to you
15:55 from a
16:00 slide so uh I'm going to need to change
16:02 my display over
16:04 quickly there is a keyboard shortcut for
16:08 this but I cannot remember
16:11 it are we mirroring Perfect all right
16:19 safe cool right so I've got more or less
16:22 an MC larab Project here um I've done
16:25 two things I've installed PHP St already
16:26 because I didn't want to rely on the
16:29 Wi-Fi that's when live coding goes wrong
16:32 uh and I've also added a value call so
16:34 if we go to composer file is this big
16:35 enough for you can you see it or do you
16:36 want me to make it a bit
16:40 bigger bit bigger all right no worries better
16:42 better
16:46 bigger yeah that'll do right uh you'll
16:47 have to zoom in later and watch it
16:50 back so we've got PHP stand here uh
16:54 version 2.1 so pretty much the latest
16:56 and we've also got a PHP stand. neon
16:59 file which is the configuration file now
17:01 I've preconfigured this I've got all of
17:04 the meaningful uh laravel PS here minus
17:06 tests you can put tests in there if you
17:08 want and I've set PHP stand to level
17:11 five which is sort of like the mid level
17:13 uh it does enough to be useful but it's
17:16 not too extreme that you're going to go
17:18 crazy uh and then if we head over to the
17:22 console routs uh I've got a command here
17:24 called LaRon and I'm echoing out the
17:27 result of value hello uh so we can
17:28 actually go ahead and run this in the
17:31 terminal so PHP arts and
17:34 Lon and we can see
17:37 hello so what we want to happen now is
17:40 PHP stand to find that call to value and
17:42 tell us that we shouldn't be calling
17:44 value because it's pointless it's not
17:45 really doing
17:47 anything the first step there is going
17:50 to be creating a new class so I'm going
17:53 to do this inside of app uh we'll do PHP
17:56 stand rules and I'm going to create a
18:00 file uh let's call it unne necessary
18:01 value call [Music]
18:03 [Music]
18:06 rule cool so this is a PHP
18:09 file so we need to give it a name space
18:10 uh which is going to be something like
18:13 this uh I've got some form of AI trying
18:16 to help me out I'm going to ignore
18:19 it we're going to need a class so we'll
18:20 call it
18:25 unnecessary value call rule if I can
18:27 type and we're going to implement an
18:30 interface so so the exact interface here
18:34 oh wait AI is helping out is that one so
18:36 this interface is used by PHP stand
18:39 internally uh it needs us to implement
18:42 two methods the first one AI is just
18:44 better it's it's just doing my job for
18:47 me is get node type so as I said we're
18:51 traversing the As and for every node in
18:53 the as PHP stand's going to check to see
18:56 if there are any rules that apply to
18:58 that node uh so in our case we want to
19:01 check check function calls which is the
19:03 funk call
19:05 node so that's our first method we're
19:07 saying we want this rule to apply to all function
19:09 function
19:12 calls we also need to add a process node
19:15 method now this is going to accept two
19:18 uh parameters the first being a node uh
19:21 from the PHP passer package and the
19:23 other one is a
19:25 scope and we need to return an
19:28 array uh here's an example of my editor
19:30 not working properly because it's not
19:34 autoc completing the import for
19:36 scope so I'm going to add in an empty
19:38 array here because I want to make sure
19:40 that we've got this configured properly
19:42 with PHP stand first before we start
19:44 implementing our rule so I'm going to
19:47 head back over to PHP stand. neon uh
19:50 neon is like kind of like yaml uh I
19:52 think there are some differences but for
19:54 the most part is the same so I'm going
19:57 to add a top level key here called rules
19:59 and then using a hyphen I'm going to put
20:02 the fully qualified class name for our
20:05 rule into here so PHP stand rules and we
20:07 called it
20:11 unnecessary value call Ru just like
20:15 that okay so uh I should be able to run
20:18 vendor bin PHP stand and I'm going to
20:20 set the memory limit here to minus one
20:22 so that we don't run out of memory uh
20:25 let's make this apparently not very
20:28 big cool so we don't get any errors uh
20:30 which hopefully means our rule is
20:32 configured properly if it wasn't PHP
20:34 stand would tell
20:37 us so let's actually Implement our
20:40 rule uh the first thing we need to do
20:43 here is double check or triple check
20:45 that what we've received is indeed a
20:47 funk call uh so I'm going to do
20:48 something really simple here and just
20:51 say if node isn't an instance of funk
20:55 call return an empty array this is you
20:57 know preventative it shouldn't ever
20:58 happen uh but if something goes wrong
21:00 wrong in PHP stand it's better to be
21:02 safe than
21:05 sorry now if we head back to the console
21:07 file here uh hopefully you can see that
21:09 fine side by
21:12 side we're looking for function calls to
21:13 the value
21:16 function now the fun call node itself
21:19 has a name property that's part of the
21:22 so we can grab the name by getting the name
21:23 name
21:25 property and name could be a couple of
21:27 things we could be calling a variable
21:30 like this don't care about those here so
21:33 we want to make sure that name is an
21:36 instance of name so that's a PHP node uh
21:40 if it's not an instance of name uh or if
21:44 name to string is not equal to value now
21:45 so let's close that window
21:48 there so if we're not calling a named
21:52 function like value or if the name of
21:53 the function that we're calling isn't
21:55 value let's just return an
22:05 the next thing is the arguments since
22:08 we're only interested in calls to value
22:10 that aren't passing a closure we're
22:11 going to grab the arguments from the
22:14 node there's a get args
22:17 method if we're not passing through any
22:19 args so if it's an empty array we'll
22:21 return an empty array we can't do
22:24 anything with that we don't have enough
22:26 information otherwise we should be able
22:28 to grab the first argument so that will
22:32 be be ar zero now ARG itself is actually
22:35 an as node uh so to get the expression
22:38 from that node we need to access the
22:41 value property and if we hover here you
22:43 can see there's an expression that's
22:44 what we
22:47 want so if you remember back to the
22:50 function signature there's a scope
22:53 parameter now scope is a way for PHP
22:57 stand to keep track of contextual stuff
22:59 so where we are in a HP file uh the
23:02 variables that are defined the class
23:04 that we in uh the function that we're in
23:07 even uh so we can use that to infer the
23:09 type of certain
23:11 Expressions so in this case I can say uh
23:16 type is scope get type
23:21 value now PHP Stan has an internal sort
23:24 of type system uh so what we could do
23:27 here is say if type is not closure uh
23:30 but that doesn't really work well if you
23:32 think about it you could have something
23:35 that is closure or string this is a
23:38 union type it is actually kind of
23:40 compatible with closure there are cases
23:43 where it could be a closure or a string
23:46 so we can't just check if type is a
23:48 closure or not uh instead we actually
23:52 need to see if it's compatible anywhere
23:54 in that chain with closure uh so what
23:59 I'll say here is if type is super type
24:02 of uh it's a it's a superh hero
24:04 type I'm just going to refer back to my
24:06 notes to make sure I don't get this
24:11 wrong yeah so if type is a super type of
24:12 and then we want to see if it's
24:15 compatible with a closure so we'll pass
24:16 through closure
24:19 type I'm using fully qualified class
24:21 names here just that you can see
24:23 things and I'll break it across multiple
24:29 lines uh if that works there we go so
24:31 closure type itself is like a function
24:34 so we could pass arguments to it uh for
24:37 now I'll pass an an empty array of
24:39 arguments uh it also has a return type
24:41 because it's like a function I don't
24:43 really care what the return type is so
24:45 I'm going to just say mixed type since
24:52 types uh and then we can call a method
24:56 on this result so I go back to when I
24:57 said that you could have Union types so
25:01 a closure or a string the reason that we
25:03 can't just say yes or no to that is
25:05 because there is a middle ground you
25:07 know if it is a closure or a string it
25:09 might be a closure so PHP stand uses
25:12 something called a trary system uh so
25:14 yes maybe or
25:17 no up until I think it's level six in
25:20 PHP Stan it doesn't actually care
25:22 whether it's yes or maybe it treats them
25:23 as the same thing so I'm on level five
25:26 I'm going to do the same thing uh so if
25:28 it's not compatible with a a closure
25:30 type or no is
25:34 false we just return an empty
25:36 array so what we're saying here it's not
25:39 very readable is it like that but if
25:41 type is a super type of closure is it
25:44 compatible with the closure type in some
25:46 way shape or form uh if the answer to
25:51 that is um no uh then we'll return an Mt
25:55 array otherwise we know for a fact that
25:58 it's something uh like a string uh in
26:01 which case we can return an error
26:03 message so we could just return a string
26:06 here but uh PHP stand has a nice API for
26:11 building rules so we'll do rule error
26:13 Builder we call a static method on this
26:17 and I'm going to say unnecessary call to
26:20 Value helper so that's our error message
26:22 that's what we'll show up in the
26:24 terminal we need to tell PHP stand where
26:28 that's happening so we'll do line and
26:31 the node has get start line method
26:35 that's where in the file it
26:38 starts PHP stand also has error
26:41 identifiers so instead of ignoring every
26:43 single error you can ignore specific
26:46 ones uh so I'll give this an identifier
26:49 of custom and let's go with unnecessary
26:53 value call and then we call the build
26:56 method so uh from the top very
26:59 quickly uh we should have a function
27:02 call if we don't we return we should be
27:05 calling a named function where the name is
27:06 is
27:08 value that function call should have some
27:10 some
27:12 arguments and the type of that argument
27:14 should be something that's not
27:16 compatible with a
27:18 closure if it isn't then we produce an
27:22 error message so moment of truth let's
27:26 uh run this again so vendor bin PHP
27:30 stand and the memory Li set to minus
27:33 one uh I have a syntax error somewhere
27:36 I'm missing a left parentheses
27:42 there there like
27:45 that so let's run
27:47 again you see it's analyzing the files
27:49 it found one error
27:51 error
27:54 um PHP stand types mixed type not found
27:58 while analyzing file have I made a typo
27:59 I have it should be type
28:01 type
28:03 classic I was really hoping this would
28:06 go smoothly like no issues but there we
28:07 go right we've got an error message so
28:10 in Roots console. PHP we have an
28:12 unnecessary call to the value helper so
28:15 it's doing what we expect and to triple
28:18 check that we can go back and if we uh
28:21 change this to a short closure so a
28:24 function that returns hello and run that
28:26 again that error should go away because
28:29 PHP stand knows that the thing that
28:31 we're passing through to value is a
28:34 closure and that's basically it this is
28:36 a really simple case uh you can
28:38 obviously take this a lot further uh and
28:41 what I would actually recommend
28:44 is uh do I have to change my display
28:46 back to stoping
28:48 stoping
28:51 yeah there we go uh what I would
28:53 actually recommend is that you a check
28:57 out laran uh I discovered that laran
29:00 actually has this rule built in um it's
29:02 implemented slightly differently it does
29:05 a much better job at at catching cases
29:06 um but check out laran if you're using
29:09 laravel I assume you are you're here uh
29:11 it handles a lot of the nuances around
29:13 like eloquent models and accessing model
29:15 properties your database casts those
29:17 sort of things and if you're
29:19 specifically interested in learning more
29:22 about what you can do with PHP stands
29:24 extension API I would recommend you head
29:27 over to the PHP stand website uh you'll
29:29 find documentation on basically
29:32 everything uh it's very well written uh
29:35 very deep um so if you need something
29:37 you will find it
29:39 there uh hopefully you learned something
29:41 new uh and can walk away from this talk
29:43 with some cool ideas uh if you want to
29:44 come and chat with me over lunch please
29:46 feel free I'll be more than happy to
29:48 talk to you about this stuff uh but yeah
30:09 what I have what questions go so Neils
30:14 is asking do you install PHP stand in every
30:15 every
30:18 project yeah more or less uh unless it's
30:22 like a proof of concept yeah if it's a
30:25 serious project I would um I think it's
30:27 one of those things where it's better to
30:28 have it than not have it
30:30 makes sense it it will help you in some
30:32 way shape or form but do you live
30:35 without it for example uh yeah cuz
30:37 there's other tools right but if it's
30:40 just PHP stand specifically you've got s
30:42 uh which is implemented slightly
30:44 differently has different
30:47 apis so yeah you could live without it
30:49 you could rely on other things but but
30:52 better have it than exactly yeah yeah
30:58 okay our dear friend Anonymous user yeah
31:03 is asking why don't you like
31:05 Marmite I wonder who the anonymous user
31:08 is uh just not for me it's not for you
31:11 not for me simple as have you tried to
31:13 sprinkle with the sprinkles that we have
31:16 here in Amsterdam could be good yeah the
31:19 Sugar Sprinkles tastes like
31:22 rainbow still enough oh I'll stick to
31:27 one hour okay yeah tough crowd yeah okay
31:29 thank you so much for this thank you