├── episodes ├── 001.md ├── 002.md ├── 004.md ├── 005.md ├── 017.md ├── 023.md ├── 027.md ├── 030.md ├── 033.md ├── 034.md ├── 035.md ├── 037.md ├── 038.md ├── 039.md ├── 040.md ├── 041.md ├── 042.md ├── 044.md ├── 046.md ├── 047.md ├── 048.md ├── 049.md ├── 050.md ├── 051.md ├── 053.md ├── 054.md ├── 055.md ├── 056.md ├── 057.md ├── 058.md ├── 059.md ├── 060.md ├── 061.md ├── 062.md ├── 064.md ├── 065.md ├── 066.md ├── 069.md ├── 073.md ├── 075.md ├── 84.md ├── 85.md └── 86.md └── readme.md /episodes/001.md: -------------------------------------------------------------------------------- 1 | * Everyone goes bonkers over PHP elephpants 2 | * Problems with PHP user groups in Chicago & advice from Cal 3 | * [WurstCon 2014](http://wurstcon.com/) is coming to Chicago! 4 | * Reminiscing about coding on old [Tandy computers](http://en.wikipedia.org/wiki/Tandy_Corporation) 5 | * How [Ruby](https://www.ruby-lang.org/) & [Ruby on Rails](http://rubyonrails.org/) influenced the PHP community 6 | * PHP has lead the pack with a [streams I/O layer](http://php.net/manual/en/intro.stream.php) 7 | * Some talk about [PHP stream filters](http://php.net/manual/en/filters.php) 8 | * [PHPNG](https://wiki.php.net/phpng) gets a mention 9 | * Stuff about [HHVM](http://hhvm.com/) 10 | * It has a [JIT](http://en.wikipedia.org/wiki/Just-in-time_compilation) 11 | * Should we implement it for our project? 12 | * It pushed PHP core team to get back in-gear 13 | * PHP new features and performance 14 | * [Elizabeth Smith](https://twitter.com/auroraeosrose) is awesome 15 | * [Contributing to PHP internals](http://www.phpinternalsbook.com/) ([the internals wiki](https://wiki.php.net/)) 16 | * PHP from the command line - why would we? We're lazy. 17 | * Testing in PHP 18 | * [Test-driven development](http://en.wikipedia.org/wiki/Test-driven_development) is neat but we confess that we don't always do it 19 | * Build an API-first with [apiary.io](http://apiary.io/) 20 | * Grumpy has some [great books on testing in PHP](https://leanpub.com/u/chartjes) 21 | * Various type of tests: unit, functional & integration; oh my! 22 | * Why Cal focuses so much on the community around PHP 23 | * Advice: be part of a local user group 24 | * Learn from the community & pay it forward 25 | * The PHP community is awesome and approachable 26 | * The business of PHP 27 | * Developers are not resources 28 | * The disconnect between managers and developers 29 | * Managing expectations in the context of a web project 30 | * Something old, something new, something borrowed, something deprecated 31 | * Old & Awesome: PHP streams are still awesome 32 | * New & Cool: [PHP variadics](http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list) & [the splat operator](http://www.lornajane.net/posts/2014/php-5-6-and-the-splat-operator) 33 | * Borrowed: [PHP generators](http://php.net/manual/en/language.generators.overview.php) 34 | * Deprecated: [Globals need to be deprecated](http://php.net/manual/en/language.variables.scope.php#language.variables.scope.global) 35 | * [Michelangelo van Dam](https://twitter.com/DragonBe) is amazing -------------------------------------------------------------------------------- /episodes/002.md: -------------------------------------------------------------------------------- 1 | * Sammy's B.S. in Linguistics does not help him pronounce [Jeremy](https://twitter.com/jmikola)'s last name properly. 2 | * How to wrap our heads around functional programming: 3 | * "Functional programming is to imperative programming as a curve is to a derivative." 4 | * There is no such thing as a point on a curve, but there are approximations. 5 | * "State" doesn't exist in real life so we don't use it in functional programming 6 | * SammyK has amazing show notes. 7 | * What is state? 8 | * State is holding data around in memory 9 | * Mutable vs Immutable 10 | * Mutable: can be changed 11 | * Immutable: cannot be changed 12 | * Unix piping in the command line is an example of functional programming 13 | * Closures are [anonymous functions](http://php.net/manual/en/functions.anonymous.php) that can be assigned to a variable 14 | * Functional programming 15 | * Functional programming can be done with an imperative programming language like PHP, but there are native functional programming languages like [Haskell](https://wiki.haskell.org/Haskell). 16 | * State happens in a very small context 17 | "[Functional Programming in PHP](http://code.tutsplus.com/tutorials/functional-programming-in-php--net-35043)" by Patkos Csaba says there are three guidelines to functional programming in PHP: 1. **No assignments.**, 2. **No mutable state.**, and 3. **No `while` or `for` loops**. 18 | * Glen mentions [referential transparency](http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)) and minds explode. 19 | * Persistent data sources get a "pass" in functional programming since they store state. 20 | * Immutable values 21 | * Immutable values make testing easier. 22 | * DateTime has an [immutable version](http://php.net/manual/en/class.datetimeimmutable.php). 23 | * [Primitives in PHP](http://php.net/manual/en/language.types.intro.php) are essentially value objects. 24 | * To change the state of an immutable object, create a new one. 25 | * Recursion 26 | * Recursion 27 | * [Recursion](http://en.wikipedia.org/wiki/Recursion_(computer_science)) is used instead of `while` or `for` loops in functional programming. 28 | * We take a PHP elePHPant break. 29 | * [Mojolicious](http://mojolicio.us/) has a [Failraptor](http://blog.kraih.com/post/43196557952/failraptor). 30 | * [ReactPHP](http://reactphp.org/) is an event-driven, non-blocking I/O library. 31 | * The name comes from the [reactor pattern](http://en.wikipedia.org/wiki/Reactor_pattern). 32 | * We compare ReactPHP to [Node.js](http://nodejs.org/). 33 | * [Non-blocking I/O](http://en.wikipedia.org/wiki/Asynchronous_I/O) vs [multi-threading](http://en.wikipedia.org/wiki/Multithreading_(computer_architecture)) 34 | Examples of using non-blocking I/O: q web server, a web scrapper & other apps that use other web protocols (not just * HTTP) like [Ratchet](http://socketo.me/). 35 | * PHP is a great language to run from the command line. 36 | * Some discussion on how single-threaded languages make use of an [event loop](http://en.wikipedia.org/wiki/Event_loop) to perform non-blocking I/O. 37 | * What we use ReactPHP for: 38 | * Jeremy uses it to communicate with child processes in the MongoDB PHP diver test suite. 39 | * Most common uses are web socket apps. 40 | * It's possible to use it for MySQL driver communications. 41 | * In PHP 5.6, the [PostgreSQL driver supports asynchronous connections and queries](http://php.net/manual/en/migration56.new-features.php#migration56.new-features.postgresql). 42 | * We talk about how ReactPHP can help us program functionally in PHP. 43 | * [Igor](https://github.com/igorw) has some great functionally programmed repos. 44 | * Something old, something new, something borrowed, something deprecated 45 | * Old & Awesome: PHP streams (again lol) 46 | * New & Cool: Anything off of [Nikita Popov's blog](https://nikic.github.io/). 47 | * Borrowed: PHP steals pretty much everything 48 | * Deprecated: [Pear](http://pear.php.net/) -------------------------------------------------------------------------------- /episodes/004.md: -------------------------------------------------------------------------------- 1 | All about web api's, it's a very broad term...Application Programming Interface...it covers a lot of things but today we are talking about web api's. We're going to be exploring terms like REST and JSON, what you need to do to consume an api from a php perspective, and from a client side perspective, and moving app domain logic into the client side, Single Page Applications (SPA) - tend to be very JavaScript intensive. 2 | 3 | * What is an [api](http://www.webopedia.com/TERM/A/API.html)? 4 | * Fundamentally, the way two pieces of software talk to each other. 5 | * [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) Principles 6 | * At a high level, it's like a contract, it's a defined set of rules and language. 7 | * Breaking backwards compatability, but you're breaking the contract. 8 | * Why build an api? 9 | * Everything is connecting to something else, so if you build an app, you will need to connect to some other service. 10 | * api first design 11 | * as the world grows, connection is what it's all about now. 12 | * Some developers, don't realize that they're using an api due to the api being buried in a package. Like [AWS S3 Package](https://aws.amazon.com/sdk-for-php/). 13 | * Consuming an API vs designing an API 14 | * Creating an API allows for more flexibility, you can create a mobile version that consumes an api as well as a desktop or it allows another service to connect with your app. 15 | * Consuming an api differs from a database because it forces you to account for situations where the api may fail. Apis tend to have more exceptions than a DB layer like PDO, so you need to be more aware when programming. 16 | * What does a web api look like? 17 | * [HTTP Protocol](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) 18 | * GET 19 | * POST 20 | * PUT/PATCH 21 | * DELETE 22 | * [Response Codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) 23 | * Request and Response headers 24 | * The body of the headers 25 | * The HTTP Protocol verbs are intended for specific purposes and you need to understand them and use them accordingly 26 | * Using the proper response codes. 27 | * APIs are distributed systems, meaning latency comes into play 28 | * You have to design for failure big time 29 | * Design an api based on failure cases (they're the hard ones), success cases are the easy ones. 30 | * When working with apis, error handling is no exception. (buh dum tiss) 31 | * (Give it a REST @jmikola) 32 | * The podcast descends into punfest 33 | * 16:20 - 18:00 - general discussion about how apis work (getting data, updating a resource, delete) 34 | * 18:30 - 20:20 - Good discussion about what happens in an api request. Headers are sent, the api reads the headers and determines if it can respond, then proceeds, then it processes the request and returns the content...general browser users never see the headers of an API...but basically everything is determined by the headers. 35 | * 21:20 - 24:40 - Talking through a server request, one guy acts as server another as browser and basically talk through what they want to do from the perspective of the technology that they are representing. 36 | * 24:40 - 25:00 - Talking through an invalid response, props to knowing the server code for a 'too large request' code 37 | * 25:00 - 25:40 - Talking about what the [status codes](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) 38 | * 200s - Success status 39 | * 300s - Deal with Redirecting 40 | * 400s - Deal with errors 41 | * 26:15 - 26:45 - Why is [JSON](https://en.wikipedia.org/wiki/JSON) better than [XML](https://en.wikipedia.org/wiki/XML)? 42 | * In php world, JSON is way easier to parse than XML 43 | * 26:45 - 27:30 - [URL vs URI](http://stackoverflow.com/questions/176264/what-is-the-difference-between-a-uri-a-url-and-a-urn)? What's the difference? 44 | * URI - Is more proper, stands for Uniform Resource Identifier, it's an ID, not necessarily a location 45 | * They're pretty much interchangeable 46 | * URL - Universal Resource Location 47 | * 27:30 - 32:00 - [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) - What is it? Why is it important in API design? 48 | * Different types of APIs, [SOAP](https://en.wikipedia.org/wiki/SOAP) and REST are just two of the types. 49 | * Most APIs are not RESTFUL 50 | * 28:35 - [HATEOAS](https://en.wikipedia.org/wiki/HATEOAS) - Stands for Hypermedia As The Engine Of Application State 51 | * Think of it as a "Choose your own adventure" book 52 | * Github is an example of a HATEOAS API 53 | * 32:00 - REST and RESFTUL. HATEOAS is the extreme form of REST or as REST api people say "The correct form of REST" 54 | * 32:18 - RPC style of api 55 | * 33:00 - REST was designed to give you longevity with your api 56 | * REST gives more flexibility than RPC or SOAP 57 | * 33:41 - 35:00 - [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) stands for Remote Procedure Call 58 | * local functions that map one to one with remote functions in the api 59 | * REST is more resource oriented and RPC is more function or feature oriented 60 | * 35:00 - APIs are not limited to data, although that is how most of the web thinks of them. 61 | * 36:00 - SOAP requires a lot of information in the request that doesn't seem relevant to what you need to get, making it a bit of a pain to work with. 62 | * 37:30 - JSON tends to be preferred because it is faster than XML, usually because the payload is less to transfer. Additionally SOAP has a lot of payload in the headers. 63 | * JSON is great for the mobile concern of payload, which translates to data transfer. 64 | * 39:12 - [Roy Fielding](https://en.wikipedia.org/wiki/Roy_Fielding) - father of REST 65 | * Knee slapper by @jmikola - I gave up on SOAP API, it was a wash. 66 | * 40:00 - 41:00 - [Richardson Maturity Model](http://martinfowler.com/articles/richardsonMaturityModel.html) 67 | * First level is XML of HTTP...although now JSON is probably preferred. 68 | * Nouns, thinking of your api as a series of resources that are interconnected, that have relationships that can be interacted with one at a time, like named resources 69 | * Verbs, using the HTTP verbs correctly, GET, POST, PUT, DELETE...maybe Head. 70 | * Hypermedia controls. (Choose your own adventure book) 71 | * 42:19 - Matt Frost book on oAuth 72 | * 42:45 - 45:30 - discussion about how oAuth works. 73 | * 46:00 - [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication) 74 | * Avoid probably, transmits password in plain text. 75 | * 48:30ish - Talking about using a secret key and hashing the request so that the server can decrypt based on your key. 76 | * 53:20 - [RAML](http://raml.org/) - REST API MODELING LANGUAGE 77 | * Supposed to allow the ability to wireframe an API 78 | * Advantage is that you can sort of test an api without having to write code...or invest a lot of time to begin testing an api that would require you to be committed once you begin being able to test the api. 79 | * It's basically a spec 80 | * 56:40 - [SWAGGER](http://swagger.io/) - Another API modeling language 81 | * It's darn right impossible to change an api after it's been developed 82 | * Swagger seems to be more about documenting an api that you have already created, where RAML is more about being able to spec out and prototype an API 83 | * [Semver](http://semver.org/) - semantic versioning 84 | * 58:00 - using semver to version an api 85 | * Designing an api is about solving a business problem...if you're not solving a business problem with your api, you're doing it wrong. 86 | * This is where RAML can be beneficial, so that you don't spend a lot of time writing code, and can focus a bit on what you're api does and how it should work. 87 | * [Apigility](https://apigility.org/) 88 | * [Runscope](https://www.runscope.com/) 89 | * Proxy between you and an api, helps with debugging an api 90 | * Ways to test apis 91 | * [CURL](https://en.wikipedia.org/wiki/CURL) 92 | * HTTPClient 93 | * [Postman](https://www.getpostman.com/) - Chrome extension (Mac App coming soon) 94 | * [HTTPIE](https://github.com/jkbrzt/httpie) 95 | * [Guzzle](http://docs.guzzlephp.org/en/latest/) 96 | * HTTP old, but still awesome 97 | * new [HTTP RFCs](http://http2.github.io/) - new definitions of the spec for HTTP 98 | * 1:21 - End of show, after party begins, hilarity ensues 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /episodes/005.md: -------------------------------------------------------------------------------- 1 | # Quick Description 2 | 3 | PHP Internals, trying to find out how the sausage is made. 4 | 5 | ### Guests: 6 | 7 | * Anthony Ferrara - Author of Password Hashing (added in PHP 5.5) 8 | * Sara Goleman - Huge contrubtor to PHP and HHVM 9 | * Elizabeth Smith - making bad php extensions work on Windows 10 | * Joe Watkins - author of PHP Threads 11 | 12 | ### Show Notes 13 | * 2:00 - Guest Introductions 14 | * 4:00 - Show Begins 15 | * 4:15 - Op code pops up alot in [PHP Internals](http://news.php.net/php.internals). Machine readable version of your script, it's what PHP actually steps through as it is executing your program. 16 | * 5:50 - [PECL](https://pecl.php.net/) - pronounced pickle - PHP Extension Community Library 17 | * 6:25 - [3v4l.org](https://3v4l.org/) - a site that allows you to run your code in a bunch of different versions at the same time. Also shows the op code for php and hhvm 18 | * 7:46 - [Leet speak](https://en.wikipedia.org/wiki/Leet) 19 | * 7:56 - [JIT - Just in time compiler](https://en.wikipedia.org/wiki/Just-in-time_compilation), a description follows but I can't really hear it. 20 | * 9:00 - [PHPPHP](https://github.com/ircmaxell/PHPPHP) - implementation of php written in php instead of C. Should be able to run your code by PHPPHP and get the same output as C 21 | * 10:00 - PHP with JIT is the same sort of thing, it's a separate program whose only job is to run your program. Your program is not running, JIT is running your program. JIT allows your program to run your php directly on the CPU. 22 | * 11:00 - There is discussion of included JIT in PHP, but no one seems to have a good stable one at the moment. 23 | * 12:00 - With [Zend engine](https://en.wikipedia.org/wiki/Zend_Engine), you can run extensions and configure them, with JIT it would be significantly harder to do that unless it was perfectly right. 24 | * 12:50 - [HHVM](http://hhvm.com/) allows you to do things you probably shouldn't be doing. 25 | * 13:20 - PHP is really good at running really bad code, really well. 26 | * 13:30 - Done is better than perfect. 27 | * 13:45 - PHP drinking game introduced by @jmikola 28 | * 14:38 - Userland, refers to people who write php 29 | * 15:30 - What are extensions? 30 | * Extensions are C code that ties into PHP itself. Can either add functionality, change the way the engine runs, or do other bad things that will be kept secret. 31 | * 16:10 - PHP is two things, the Zend engine, that parses the script, and the other side of that is the runtime library. Made up of all these extensions, without the extensions, php would be a really boring language. 32 | * 16:46 - 4,000 extensions ship with php 33 | * 16:55 - You can write your own extensions. 34 | * 17:50 - extensions probably not included in term "userland" 35 | * 18:00 - Talk about where php came from...basically to make writing something in C easier. 36 | * 19:00 - [PERL](https://www.perl.org/) was the only really established language. [Ruby](https://www.ruby-lang.org/en/) was there, but really young, 37 | * 20:30 - PHP - stands for Personal Home Page - first release of php was 1995 38 | * 22:15 - [PHP Museum](http://museum.php.net/) 39 | * 23:00 - Anything from php past that is still plaguing it? Parameter Order 40 | * 24:30 - Funny that php [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) requires spaces, and the code that runs php (C) uses tabs. 41 | * 25:00 - [FIG - the PHP standards group](http://www.php-fig.org/), where the [PSR-X standards](http://www.php-fig.org/psr/) come from. 42 | * Solving simple problems that are going to be generically useful, is a lot more useful to thee public than trying to build a one-size-fits all solution. 43 | * Fig should build complexity by composing simplicity 44 | * 28:30 - The people behind PHP Internals don't even use PHP. This idea turns out to be false. 45 | * 30:30 - Userland is best used to describe the code that is used to compile php vs php that runs on the process 46 | * 31:00 - Should the people who write the C code that compiles php be concerned with things like PHP FIG? 47 | * 31:20 - Internals should enable php community, but should also listen to community if there is a consensus that arises from usage. 48 | * 33:00 - Talk about [GOTO](http://php.net/manual/en/control-structures.goto.php) being added to php, and some things that surrounded that action. 49 | * The argument basically being that, if it's there and you want to use it, you can, if not, then don't use it. 50 | * An example is made that GOTO solved great, sort of a discussion about the identity of PHP. PHP vs JAVA being a designed language and very academic in its approach. 51 | * 36:00 - premature optimization is the root of evil. 52 | * 37:00 - Why aren't arrays allowed to be a constant? Constants are done at compile time (technical jargon answer). PHP's numbering model is partly to blame. Constants are limited to (what we call) scalar values (null, true, false, integer, floats, string). String is technically not a scalar, but it's close enough that PHP sort of pretends it is one. In php 5.5, the ability to dereference an array entered. 53 | * Arrays are basically mutable structures from the very concept of them. 54 | * 40:00 - [Mutable vs Immutable](http://stackoverflow.com/questions/214714/mutable-vs-immutable-objects) - Basically, mutable means you can change the value when the script runs. Immutable, you can not. Constants are immutable, so making Arrays constants is a little weird. 55 | * 41:10 - Why are [Resources](http://php.net/manual/en/language.types.resource.php) skipped when talking about primitives? Resources are pointers behind a "dark magical curtain". PHP knows nothing about them. The only thing that does are things in that same extension. 56 | * An example of a resource is the File Pointer. Changing the File Pointer to objects would require everyone to rewrite parts of their program. 57 | * If you want to get rid of resources, why not get rid of arrays and replace them with objects? Objects do everything arrays do, plus a little bit. 58 | * 44:30 - An argument is made to figure out a good way to transition from resources to objects. 59 | * 45:10 - Discussion about how to help out with PHP ecosystem that doesn't require person to know C code. PHP.net, tests, and more do not require C 60 | * 47:00 - The code that runs PHP.net is very interesting to look at...some dates back to PHP 3. 61 | * 48:50 - qa.php.net - tools to help write tests for php.net (and other usecases) 62 | * gcov.php.net - code coverage for php.net 63 | * 50:00 - all tests for php are integration tests...no unit tests 64 | * 52:30 - PHP Future - A spec for PHP. A specification that defines everything for PHP. 65 | * 53:00 - PHP's strength is that it is not an academic approach, it is driven by people who need to solve problems and provide solutions. 66 | * Since there is no spec for php, the source code is the spec...which seems to work ok 67 | * 54:30 - [PHPNG](https://wiki.php.net/phpng) 68 | * 55:50 - A PHP spec is probably a good idea, but no one wants to be in that work. 69 | * 57:00 - [0x00 + 2 = 4 in PHP 5.3](https://bugs.php.net/bug.php?id=61095), is one of the "warts" that has been found by someone writing a spec for PHP...that sounds like it was paid for by facebook (sort of). This bug was fixed in 5.3.11 70 | * HHVM has north of 12,000 unit tests. 71 | * PHPT unit tests and unit tests at the C level. 72 | * 62:45 - [RFC process](https://wiki.php.net/rfc/howto) discussed pretty quickly. 73 | * Biggest threat to PHP in terms of what would be a concern that could derail the project? First answer was Apathy. If no one puts in interest, or no new blood joins the project. Eventually, there could be no one to carry the torch. 74 | * 64:00 - The barrier to entry into PHP is both a great thing and a bad thing. You can have complete beginners and very experienced engineers, that a both write PHP. 75 | * [Hacklang](http://hacklang.org/) is a great prooving ground for PHP...but could be considered a threat if it forks compatability with PHP. So you could have an instance where things only work on Hacklang, or only work in PHP. You know would be splitting the group. 76 | * That being said though, it has also helped show how some things could work in PHP and has helped get some RFC's done. 77 | * [WordPress](https://wordpress.org/) accounts for 40% of PHP installs. 78 | * 67:00 - Continued discussion about WordPress and how it's so widely used that it can dictact some of the direction of PHP 79 | * 70:00 - beginning of the show wrap up 80 | * If you want to help out with PHP, hop onto IRC in the PHP mentoring channel and YELL! 81 | * 75:00 - End of show basically. 82 | 83 | 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /episodes/017.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We discuss practical ways of dealing with legacy codebases and address the question of, "to rewrite or to refactor"? We also talk about how we should manage client expectations when working with a legacy codebase. And finally we discuss some general strategies for refactoring a codebase to good, clean, modern PHP. 3 | 4 | # Guests 5 | * [Paul Jones](https://twitter.com/pmjones) 6 | * [Hugo Hamon](https://twitter.com/hhamon) 7 | * [Franziska Hinkelmann](https://twitter.com/fhinkel) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## What is legacy code? 15 | * Any code that doesn't have tests 16 | * Code you have inherited from someone else 17 | * Code you wrote yourself several years ago 18 | * In PHP Specifically: 19 | * Include-oriented/page-based (as opposed to object-oriented and front-controlled) 20 | * No separation of concerns 21 | * Everything sits in your webroot 22 | * Multiple rewrite/refactor attempts are obvious 23 | 24 | ## What is technical debt? 25 | * It is like taking out a loan - you cut some corners to get the feature now, but cutting those corners makes it harder to change things later 26 | * "The things that you didn't do that you should have done" 27 | * Technical debt results in duplication of code, or the same thing stored in more than one place 28 | * To fix one thing, you need to make a series of co-ordinated changes across the codebase 29 | 30 | ## What do we need to think about before modernising a legacy codebase? 31 | * Separation of concerns 32 | * Understand the business case for the application and determine some acceptance tests 33 | * High-level integration Tests - if you want to refactor, they'll help to ensure the correct functionality is maintained while changing the implementation details 34 | 35 | ## How do we deal with 'developer ego'? 36 | * Be suspicious of your own developer ego 37 | * Get a second opinion - consult with others 38 | * Look at your own code from one year ago 39 | * Get others to review your code 40 | * Use tools like [Code Climate](https://codeclimate.com/) or [Scrutinizer CI](https://scrutinizer-ci.com/) 41 | 42 | ## Are there any currently-used frameworks that we should consider 'legacy'? 43 | * Version 1 of most frameworks could be considered 'legacy' today, but for different reasons to those discussed so far: 44 | * Best-practices have changed and moved on 45 | * PHP itself has changed, particularly with respect to object-orientation 46 | * Early versions of [Zend](http://framework.zend.com/) and [Symnfony](https://symfony.com/) use singletons extensively 47 | 48 | ## How do we manage a client's expectations when dealing with legacy codebases? 49 | * It is a difficult thing to communicate 50 | * Don't make estimates without looking at the codebase - this is no different from working with any unknown codebase 51 | * In some cases, a client will know they have legacy code because they will be used to code changes taking a long time 52 | * Charge for a 'discovery' process 53 | 54 | ## What tools can we use to evaluate code/technical debt? 55 | * As already mentioned, [Code Climate](https://codeclimate.com/) or [Scrutinizer CI](https://scrutinizer-ci.com/) 56 | * [Sensiolabs Insight](https://insight.sensiolabs.com/) - symfony-oriented 57 | * [SonarQube](http://www.sonarqube.org/) - large setup process, but detailed metrics (including estimated time/cost to fix) 58 | * [phpcpd](https://github.com/sebastianbergmann/phpcpd) 59 | * [phploc](https://github.com/sebastianbergmann/phploc) 60 | 61 | ## Rewrite vs refactor? 62 | * Paul and Franziska agree: Always refactor, never rewrite. [Just ask Netscape](http://www.joelonsoftware.com/articles/fog0000000069.html) 63 | * Rewriting sounds like a good idea, but it will always take longer 64 | * It will be easier to keep evolving a product as you refactor than as you rewrite 65 | * Hugo's opinion on the rewrite is a bit more sympathetic - if you do rewrite: 66 | * Once you start the rewrite, don't touch the legacy codebase 67 | * Re-implement one feature at a time 68 | * Use some kind of 'switch' (mod_rewrite rules, a load balancer, etc) to run both systems in parallel 69 | * Dispatch some requests from the legacy system and some from the new codebase 70 | * As you rewrite and move more features over, dispatch more requests from the new codebase 71 | * This can be difficult if you need to share info like session variables 72 | 73 | ## How do the panel approach modernising a legacy codebase? 74 | Paul mentions [his book](https://leanpub.com/mlaphp). The first few steps in his process are: 75 | 1. Write integration/characterisation tests 76 | 2. Set up autoloading 77 | 3. Consolidate functions and classes so they use the autoloading 78 | 4. Remove globals 79 | 5. Move to using dependency injection 80 | 6. Write unit tests... 81 | 82 | He also brings up [Michael Feathers - Working Effectively with Legacy Code](http://www.amazon.co.uk/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052). 83 | 84 | There are tools that can help: 85 | * [XDebug](https://xdebug.org/) - useful for examining code + working out execution path 86 | * [ACK](http://beyondgrep.com/) - useful for finding all the occurrences of particular code/calls 87 | * [PHPStorm](https://www.jetbrains.com/phpstorm/) 88 | * [phpcpd](https://github.com/sebastianbergmann/phpcpd) 89 | 90 | ## Sammy Kaye wraps up with 91 | * Developer shout-out: Matthew Weier O’Phinney 92 | -------------------------------------------------------------------------------- /episodes/023.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Inspired by a lively Open Spaces session at [php|tek 2015](http://tek.phparch.com/), we discuss how PHP's ecosystem could be threatened by a not-so-obvious [bus factor](https://en.wikipedia.org/wiki/Bus_factor) and what we can all do to keep things thriving. 3 | 4 | # Guests 5 | * [Samantha Quiñones](https://twitter.com/ieatkillerbees) 6 | * [Davey Shafik](https://twitter.com/dshafik) 7 | * [Chris Tankersley](https://twitter.com/dragonmantank) 8 | * [Michelangelo van Dam](https://twitter.com/DragonBe) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | ## Intro 15 | * Definition of [the bus factor](https://en.wikipedia.org/wiki/Bus_factor) 16 | * Samantha discusses her talk at php|tek 2015 "Open Sourcing Teams", which provided the inspiration for this podcast topic. 17 | * The panel quickly decides that 'getting hit by a bus' is unnecessarily morbid. For the rest of the podcast, we can read 'getting hit by a bus' as 'retiring' or 'winning the lottery' :) 18 | * How do we measure/express bus factor - does a project with 2 crucial contributors have a bus factor of 2 or 0.5? The panel agrees on 2. A low bus factor is bad, a high bus factor is good. 19 | 20 | ## Which important PHP projects have a low bus factor? 21 | The panel discusses some popular PHP projects and their maintainers/contributors: 22 | * [Matthew Weier O'Phinney](https://mwop.net/) - [Zend](http://framework.zend.com/) 23 | * [Fabien Potencier](http://fabien.potencier.org/) - [Symfony](https://symfony.com/) 24 | * [Taylor Otwell](http://taylorotwell.com/) - [Laravel](https://laravel.com/) 25 | * [Jordi Boggiano](https://seld.be/), [Nils Aderman](http://naderman.de/) - [Composer](https://getcomposer.org/) 26 | * [Sebastian Bergmann](https://sebastian-bergmann.de/), [Stefan Priebsch](http://www.priebsch.de/), [Arne Blankerts](https://twitter.com/arneblankerts) - [PHPUnit](https://phpunit.de/) 27 | 28 | Do these maintainers represent a bus factor of one in the context of these projects? 29 | 30 | ## How does over-reliance on one individual impact developers using a framework/platform? 31 | * If we use these tools in (commercial) projects, there is risk associated with uncertain future of the project 32 | * Reliance on a single maintainer does not represent the only risk associated with building on top of open source frameworks/packages 33 | * One of the advantages of commercial software backed by large companies/organisations is greater stability in this respect 34 | 35 | ## How do we evaluate open source software for use in projects? 36 | * Quality of documentation 37 | * Size/strength of community - network effects 38 | * In a worst case scenario (e.g: the project is abandoned), could we maintain a fork? 39 | 40 | ## How can we identify projects with a low bus-factor? 41 | * This is a hard judgement to make 42 | * The majority of users/developers are not sufficiently involved in the PHP community to make this judgement 43 | * Sometimes projects fail/disappear/fall out of favour due to other reasons (osCommerce and Lithium are cited as examples) 44 | * High bus-factor does not guarantee stability 45 | 46 | ## How can we mitigate against this? 47 | * Projects with clean standards-compliant code will be easier for others to maintain 48 | * Projects where the reasoning/philosophy behind the project is well explained will be easier for others to maintain 49 | * One reason a project maintainer may be forced to step away is financial constraints. In the Ruby community, they attempt to mitigate this risk against core projects with [Ruby Together](https://rubytogether.org/) 50 | * Form/encourage community around projects and contribute to projects 51 | * [PHP Mentoring](https://phpmentoring.org/) 52 | * Companies that depend on open source projects should contribute to those projects - the cost to businesses of contributing now is far smaller than the cost of an important project that they depend on disappearing in future 53 | * Developers and businesses should support open source projects e.g: by buying licences for their premium/commercial services 54 | * Project maintainers should welcome help and contributions from others 55 | * Project maintainers should produce good quality documentation 56 | * Project maintainers should produce contributing guidelines 57 | 58 | ## Does PHP Internals have a low bus factor? 59 | * [PHP Internals](http://news.php.net/php.internals) has many maintainers and contributors, but some specific components have serious problems. For example: 60 | * [PDO](http://php.net/manual/en/book.pdo.php) does not have an active maintainer 61 | * [mcrypt](http://php.net/manual/en/book.mcrypt.php) does not have an active maintainer 62 | 63 | ## Sammy Kaye wraps up with 64 | * Developer shout-out: Derick Rethans 65 | -------------------------------------------------------------------------------- /episodes/027.md: -------------------------------------------------------------------------------- 1 | 2 | At Laracon 2015, panel of people talking. 3 | 4 | ### Guests 5 | * Jeremy Mikola - here because Taylor thinks he is funny. 6 | * Taylor Otwell - creator of Laravel 7 | * Jeffrey Way - creator of Laracasts 8 | 9 | Big thank you to Jeffrey for continuously sponsoring the "Developer Shout Out" on PHPRoundTable, gives PHPRoundTable the ability to give developers lots of money for being awesome! 10 | 11 | Technical difficulties begin happening almost immediately. And the show pretty much wraps...well at least the video version. The audio version is a bit longer and the rest of the notes are from there. 12 | 13 | Jeffrey talks about wearing Bunny Ears and giving out Halloween candy. 14 | 15 | The group discusses Matt Stauffer's talk about how Laravel is great for getting apps out fast. 16 | 17 | Jeremy hosted PHP Jeopardy where a scandal happened in the final round. 18 | 19 | The list of players for PHP Jeopardy was randomized, and a joke was made about using the updated [random functions in PHP7](http://php.net/csprng) that was contributed by PHPRoundTable's own Sammy Kaye Powers. However, that function was not used. 20 | 21 | Was there anything that stuck out in your mind about Laracon? 22 | 23 | Way: Taylor teasing [Spark](https://spark.laravel.com/), but Adam Wathan killed it! A talk on simple, clear code with tests backing it up. The talk was about refactoring. 24 | 25 | Otwell: The best thing I hear is when someone comes up to me and says "because of [Laravel](https://laravel.com/) I can work from home now and be with my kids". The personal stories I can relate to because I have been there. 26 | 27 | Mikola: I liked that there was a good mix between Laravel specific talks and other related things. Not only talks focused on Laravel. 28 | 29 | Otwell: Yeah we try to avoid all talks being about Laravel because otherwise it would be kind of boring. The developer world is so huge and we try to appealing, especially with a single track conference, we try to have something that everyone can take away. 30 | 31 | Powers: I was surprised that almost half the speakers hadn't used Laravel. 32 | 33 | Sammy asks the question to the crowd at the Hyatt 34 | 35 | Otwell talks about Spark and how he came about in building/releasing it. Basically, he saw that all the administration of a SaaS app was annoying and got in the way of releasing an app. So he decided to make a package to release that would allow people to quickly release apps. 36 | 37 | Spark is coupled to Cashier which is coupled to Stripe. 38 | 39 | General consensus is that Spark is awesome! 40 | 41 | The use of Traits in Spark looks great. The traits that are available are `CanJoinTeams`, `UseBillable`, `CanResetPassword`. Helps with Rapid Application Development. Spark has the ability to remove subscriptions. 42 | 43 | [Doctrine](http://www.doctrine-project.org/) was in beta for five years. 44 | 45 | 29:00 - The audio now begins to fail again. 46 | 47 | The rest of the show is the crowd discussing and asking some questions. 48 | -------------------------------------------------------------------------------- /episodes/030.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | SOA (Service Oriented Architecture) is an architecture that shifts our focus from one big monolithic web app to smaller connected web apps. We discuss what an SOA app looks like in the real world and how it affects our codebases, deployment & DevOps. 4 | 5 | # Guests 6 | * [Yitzchok Willroth](https://twitter.com/coderabbi) 7 | * [Sherif Ramadan](https://twitter.com/sr_googleguy) 8 | * [Samantha Geitz](https://twitter.com/SamanthaGeitz) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## What is Service Oriented Architecture (SOA)? 16 | * In the PHP community, it is traditionally referred to as the Service Layer 17 | * Recently, the name has changed to Microservices; 18 | * Definition of SAO was introduced by Don Box from Microsoft when talking about [WCF](https://en.wikipedia.org/wiki/Windows_Communication_Foundation) (Indigo project) 19 | * 4 Characteristics of SOA: 20 | * Boundaries between components are explicit 21 | * Services are autonomous 22 | * Service share a schema and contract 23 | * Service compatibility based on policy 24 | * Microservices seems to maintain the first two, but violate the third because they are fully autonomous 25 | 26 | ## What constitutes as a Service? 27 | * A service can be stateless or stateful 28 | * Some examples of stateless services: 29 | * Image resizing 30 | * PDF creation 31 | * Stateful service 32 | 33 | ## Are services a web API or a daemon running in the backround? 34 | * Doesn't have to strictly be a JSON based API, but most traditional services are 35 | * Generally break down into 3 categories: 36 | * core services 37 | * composite services 38 | * API services 39 | * API services expose your system landscape to internal or external consumers 40 | * Core services are busy with persistence. This is where most of your business rules are going to live 41 | * Composite services either aggregate from core services or coordinate the work of various core services. 42 | 43 | 44 | ## If I use AWS for my website and use SQS to send image resizing tasks to another server, is that considered a service? 45 | * The image resizing would be considered a service and Amazon's message queue, SQS, would be considered infrastructure 46 | 47 | ## Is it true SOA was inspired by OO design principals? 48 | * Yes. If you read the gang of four book ([Design Patterns: Elements of Reusable Object-Oriented Software](https://en.wikipedia.org/wiki/Design_Patterns)), everything you learn about design patterns, in general, is pretty closely related to what you do in software architecture. SOA is just a component architectural style. 49 | * A lot of the gang of four book topics like SOLID and the single responsibility principal apply to SOA. For example, a microservice should be doing only one core business thing, etc. 50 | 51 | ## Samantha's recent talk at LaraconUS 52 | * Gave an example of a web app that used SOA. It was a website for a t-shirt company where a user could upload designs and then print the t-shirts on demand 53 | * First explained how to build the website as a monolith where you have users, admins, various products, customer service things, order processing things, etc. 54 | * Showed how easy it was for things to get out of control using the monolith model to build the site 55 | * Then when into how a developer would break it up; where you might have one API to handle users, another to handle orders and customer service, another to handle products, etc. 56 | * You can you the single responsibility principle because you can say a particular API only handles inventory and doesn't need to be concerned with users or a blog 57 | * Slides for talk are published [here](https://www.slideshare.net/SamanthaGeitz1/serviceoriented-architecture-62986976) 58 | * If something seems like it doesn't closely tie to anything else, it is a good candidate to turn into a service. Worker processes are good candidates too. These things can live as their own projects and don't need to live as part of the central codebase and can be run on their own server 59 | 60 | 61 | ## What are some pain points in a monolith that are an indication you need to use SOA? 62 | * One indication is that you have a big team and you are starting to get a lot of merge conflicts 63 | * Another indication is that you have a humongous amount of tests from a big app that takes forever to run 64 | * One more indication is that you are constantly scaling vertically 65 | * Unfortunately, with a monolith, it is easy to not realize that your app is too big until it is too late and you start to run into the issues above 66 | * It can be harder to break up a monolith than to keep some of the SOA design prinicples from the start 67 | * One barometer people use to determine when to break up their app is when the see that components in their system need to be able to scale independently 68 | * Going back to the first point, scaling the development team is important. When breaking up the code, think about having cross-functional teams with each one owning a code base. This can bring a team size down to the Jeff Bezos recommended two pizza size, which usually makes team communication better and more productive 69 | 70 | ## Is the AWS SQS image resize a good example of SOA, or are there some missing pieces? 71 | * It is a good first step, it is a great way to "put your toes into the water" 72 | * Doesn't solve all problems, but implementing some stateless services is a good first step 73 | * If you decide to completely break up your monolith app, first, pull out all the obvious services, 74 | 75 | ## How do you design web APIs for all your services in a way that won't make it horrible to work with? 76 | * You should always compare tradeoffs that you are making to get the architecture you want 77 | * You don't always need a API in front of every service. 78 | * If you clearly define the constraints around your services, it makes it easier for you make changes underneath. It also allows you to have an easier time build your message bus between your services. 79 | 80 | ## How to break up APIs by business logic? 81 | * Think about your database schemas 82 | * If something has a lot of FK constraints, for example orders and shipping or orders and customer service, you know that they are closely coupled and that there will be a lot of related database calls to get those resources. You might want to do it over an API, but you will start to run into latency issues. 83 | * The more you start thinking about database schemas and relationship nesting, it is a good way to start breaking things up 84 | 85 | ## How do you manage a shared set of code all your components would like to use? 86 | * When starting out, you can copy and paste code, but you will want to eventually use [Composer](https://getcomposer.org/) packages 87 | * Composer makes it pretty seamless to keep things synced between projects 88 | * Try not to have shared domain logic. If properly bounded, your services should not be sharing domain logic at all 89 | * Wen components share domain logic, you are no longer clearly defining the constraints between how the components interact with each other 90 | 91 | ## Are aggregates a nice place to start to look for boundaries when moving to an SOA architecture? 92 | * Bounded context are usually more appropriate 93 | 94 | ## How have you used SOA in the real world? 95 | * Samantha: At her employer [Packback](https://www.packback.co/), a digital textbook rental company, they have services to manage users, books, and search. They also have worker processes to gather prices and display books. They have somewhere between 12-15 services. Having experience in the monolith app world and the SOA world, it is so much easier to manage something that uses SOA than a monolith 96 | * Sherif: Recently been working on a remote execution / eval type site. It is kind of like an educational site similar to Codecademy. This site has many services that run unit tests, makes an AST to understand code better, etc. 97 | 98 | ## How are the codebases structured? Do you have a bunch of repos for all your services? 99 | * Yes, Yitzchok's company has over 100 repos and Samantha's company is getting close 100 | 101 | ## Isn't it more complicated to manage that many repos compared to one repo for a monolith? 102 | * Absolutely from an operations perspective 103 | * From an application engineer's perspective, you have reduced the complexity because you made what they have to deal with and think about much smaller 104 | * From an operations perspective, you have dozens to 100s of components that have to work in concert with each other. This leads to issues with deployment, configuration management, security, message tracking, monitoring, logging, service version compatibility and many other things 105 | * With the exception of breaking off the obvious stateless services like image resizing, PDF generation, price querying, etc., it is advised you use strong caution breaking things up, unless you have a strong Devops team 106 | * Some things that impact how difficult managing an SOA based app depends on size of infrastructure, codebase size, number of services, weather or not Agile practices are used, etc. 107 | * There are some 3rd party tools that can help you with the Devops complexities. In the Laravel world, there is [Forge](https://forge.laravel.com) and [Envoyer](https://envoyer.io/). There is also [Blackfire.io](https://blackfire.io/) and [Newrelic](https://newrelic.com/) that can help monitor stuff 108 | 109 | ## Do you ever get confused when pushing repos, or have related issues? 110 | * Try to go for a gated deployment 111 | * Depending on the size of your engineering department, you can build teams around specific services, which makes it easier in terms of deployment. If one team is only responsible for one or two services, then it is less likely that they will make a mistake pushing code 112 | * Sometimes a properly sized and organized team structure is under appreciated when building microservices 113 | * [Conway's law](https://en.wikipedia.org/wiki/Conway%27s_law) is pretty inescapable, so when engineers are grouped by function, for example front-end, server-side, and operations engineers, tend to do well at producing successful layer apps because they are working on a layer that they are comfortable in. But they won't do well when producing microsevices 114 | * Typically a successful microservices team is a cross-functional squad where one person of every type on the team so that you have enough people to work from end to end on a microservice 115 | * In your tests, just like you mock out calls to 3rd party services, you will do the same for the microservices your team uses 116 | 117 | ## It seams that SOA influences how teams are structured, right? 118 | * A small, cross-functional team per service is probably best 119 | * If you work for a small organization or start-up, you might only have 5 people in the engineering department, so you won't be able to build teams around individual services. Just because you don't have individual teams for individual projects doesn't mean you won't be successful with SOA 120 | * Be sure to document your services well 121 | 122 | ## What about SOA and the lone developer / freelancer? 123 | * A developer implementing a PDF generator service or something like that should be fine 124 | * Juggling 4-5 bounded contexts where you have lots of business logic living in separate places and trying to coordinate things is probably not best for a one man shop 125 | * If you still want to do SOA as a one man shop, you probably want to consider a 3 tiered architecture where you can have a PHP framework handling the frontend stuff. Then on the 2nd and 3rd tier, do something with SQS and talking to 3rd party services for stuff like video encoding, PDF generation, etc. This is still kind of SOA, and manageable by one person 126 | * If you are building simple blogs for someone, then SOA is probably not the way to go 127 | * Things like image processing for a stateless service is great for a solo developer because they are usually small, simple, and the code doesn't change often. They can be deploy and forget if well-constructed 128 | 129 | ## How do you handle authentication in a SOA? 130 | * If you are using Laravel / Lumen, you can use [this](https://github.com/lucadegasperi/oauth2-server-laravel) Oauth 2.0 server Composer package by Github user [lucadegasperi](https://github.com/lucadegasperi). Note: Oauth 2.0 support built into Laravel now using Passport. 131 | * It is pretty hard to do authentication well. It is pretty easy to authenticate someone, but you have to think about security. Some things to think about: 132 | * How are you going to do security on multiple tiers? 133 | * Do you want to do end-to-end encryption on the 2nd and 3rd tier? 134 | * Do you want to do authentication across different parts of your application? 135 | * Oauth 2.0 vs some other thing? 136 | 137 | ## CQRS vs SOA 138 | * [Command Query Responsibility Segregation](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation#Command_query_responsibility_segregation) comes out of the domain driven design world 139 | * Are relatively orthogonal concerns in that you can do CQRS outside microservices architecture and also in complement. It is not a one or the other choice 140 | 141 | ## How do you manage environment variables across multiple servers? 142 | * One way to manage it is with Laravel Forge 143 | * If you are sharing environment variables horizontally (like if a service is load balanced), that is cool. But if you are sharing environment variables across different services, then it might smell a little, indicating that you might not have the right boundaries 144 | * Another option to manage environment variables is to use the combination of [HashiCorp's](https://www.hashicorp.com) products [Consul](https://www.consul.io), a service discovery tool, and [Vault](https://www.vaultproject.io) a key secrets management tool. Consul templates is used to publish `.env` files to each service. Vault is used to store the values in the `.env` files. The servers use the `.env` files to populate environment variables 145 | 146 | ## Any latency issues? 147 | * You can't escape physics, so there will always be some additional when implementing services (because it now has to make a network connection) 148 | * Don't get fixated on HTTP as your communication protocols. Obviously, for external users, you must use HTTP, but internally, you can consider other protocols 149 | * Consider [0MQ](http://zeromq.org/) or some other protocol 150 | * Latency is basically an optimization problem. There are probably other things in your app that you need to optimize first before latency becomes an issue. Probably lots of other low hanging fruit in terms of things to optimize. For example: 151 | * Caching 152 | * Getting rid of N+1 database queries 153 | 154 | ## Is there anything in PHP that makes SOA better or worse? Or does it matter what language you use? 155 | * In general, a language you use isn't the barrier to any architectural decisions made 156 | * In terms of PHP, with its primitive concurrency model, it is kind of helpful. Mostly requests hare handled with HTTP, it is stateless, everything starts from nothing on each request, etc. This kind of helps a person think about PHP in terms of API endpoints when experimenting with SOA 157 | * When you start to think about using other protocols besides HTTP for your internal components, then PHP could hinder you and you might want to look at other languages 158 | * For edge components, PHP is definitely a good choice 159 | 160 | ## Final thoughts 161 | * SOA can be intimidating. But it is not really hard to get into 162 | * Not a panacea and not a Pandora's box. Reach out to those who have done and are doing 163 | * Microservices envy is a thing and can be a dangerous thing 164 | * There is a marketing buzz around Microservices. Don't let it confuse you in making architectural choices. 165 | 166 | 167 | ## Sammy Kaye wraps up with 168 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 169 | * Nathan Morgan and Andrew Morgan challenged to start a podcast 170 | * Developer Shout-Out: [Steven Maguire](https://stevenmaguire.com/) 171 | * Shameless Plugs: 172 | * [Grovo](https://www.grovo.com/) 173 | * [Packback](https://www.packback.co/) 174 | -------------------------------------------------------------------------------- /episodes/034.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | A discussion about PHP debugging technology and techniques. 3 | 4 | # Guests 5 | * [Derick Rethans](https://twitter.com/derickr) 6 | * [Colin O'Dell](https://twitter.com/colinodell) 7 | * [Gary Hockin](https://twitter.com/GeeH) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## Debugging Attitudes 15 | * Developers sometimes assume that their code was written properly 16 | * Instead, you should verify that your code works 17 | 18 | ## var_dump 19 | * [`var_dump()`](http://php.net/var_dump) is still a valid way of debugging 20 | * [Xdebug](https://xdebug.org/) and similar things can make `var_dump()` prettier 21 | * If you are using `var_dump()` to the point that you need to make it look pretty, you should us a step debugger 22 | 23 | ## Logging 24 | * Log interesting things, but don't go overboard 25 | * Include useful information, like IDs 26 | * Events should have the option for logging to be enabled 27 | 28 | ## Step Debugging 29 | * Xdebug helps for step debugging amongst other things 30 | * Step debugging allows you to pause a program at certain lines 31 | * They are very good for debugging someone else's code 32 | 33 | ## Future of Debugging 34 | * Debugging that allows you to view the history of a variable 35 | 36 | ## Sammy Kaye wraps up with 37 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 38 | * Developer Shout-out: Remi Collet 39 | * Shameless Plugs: 40 | * [PHP 7 Book](http://www.php7book.com/) 41 | * [PHP World - Debugging Effectively](http://www.slideshare.net/colinodell/debugging-effectively-phpworld-2015) 42 | -------------------------------------------------------------------------------- /episodes/035.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | [Immutability](https://en.wikipedia.org/wiki/Immutable_object) plays a huge role in functional programming and many languages support immutability directly; like the `readonly` [keyword in C#](https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx). It is possible to create immutable objects in PHP, but the language lacks inherent immutable features for scalar variables and class properties. We discuss how to bring functional programming concepts to PHP and brainstorm some features that could possibly be added to future versions of PHP to offer better immutability support. 3 | 4 | # Guests 5 | * [Larry Garfield](https://twitter.com/Crell) 6 | * [Matthew Weier O’Phinney](https://twitter.com/mwop) 7 | * [Glen Hinkle](https://twitter.com/tempire) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | ## Intro 14 | * [Immutability](https://en.wikipedia.org/wiki/Immutable_object) 15 | * [The readonly keyword in C#](https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx) 16 | 17 | ## State 18 | * State is a representation of something that exists in the real world 19 | * State is not a bad thing, but we should think in terms of flow rather than in terms of state 20 | * Mutable state makes time a (hidden) input to everything - the order things happen in becomes important 21 | * Abstracting the notion of time means that order is not important and it is easier to reason about individual components of a system 22 | * Where possible, we do not want to consider time. Immutability can help us with this 23 | * "O-O languages deal with state by hiding it inside objects. Functional languages deal with state by implicitly defining it as part of a function call" 24 | 25 | ## An example demonstrating the problems with state - Zend framework test suite: 26 | * They used to run their whole test suite as one job 27 | * Some of those tests made changes to PHP's superglobals (e.g: `$_SESSION`) 28 | * This made the outcome of one test potentially depend on other tests 29 | * Now they run all of their tests in isolation 30 | 31 | ## Functional programming vs imperative programming 32 | * [Imperative languages](https://en.wikipedia.org/wiki/Imperative_programming) (inc. O-O) execute a sequence of statements in order, modifying state 33 | * [Functional programming](https://en.wikipedia.org/wiki/Functional_programming) defines relationships or transformations between inputs and outputs 34 | * An imperative language focusses on the values themselves, whereas a functional language focuses on the relationships between them 35 | * PHP is an imperative language, but we can apply some FP concepts. See [Functional programming in PHP](http://www.functionalphp.com/) and [Functional PHP](https://www.youtube.com/watch?v=M3_xnTK6-pA) 36 | 37 | ## Immutability in PSR-7 38 | * The specification says that any change to a message is a change to the value of the message 39 | * This means that any change to a message object should create a new value/object (as opposed to modifying the existing object) 40 | * This makes it a candidate for use of immutable objects 41 | * Introducing immutability into the implementation of PSR-7 removes a lot of problems (and a lot of code) 42 | 43 | ## Performance 44 | * Performance is sometimes cited as a reason not to use immutable variables 45 | * Because we can't directly change an immutable variable, we must frequently discard a variable and create a new instance 46 | * Benchmarks have shown that the performance hit is marginal 47 | * PHP is very efficient at cloning objects/variables 48 | 49 | ## Database objects/ORMs 50 | * We should separate read and write contexts 51 | * Data reading and data writing should be done with different object types 52 | * SQL already does this: 53 | * The result of a SELECT statement is immutable 54 | * An UPDATE or INSERT statement is an entirely different concept 55 | 56 | ## How could we implement immutable concepts in PHP? 57 | * We can never implement **true** immutability in PHP because reflection and closure binding allow us to break scope 58 | * Service objects should be completely immutable 59 | * For immutability to be useful, objects should not be 'locked' at construction time - we need the ability to easily create a new object based on an existing immutable object 60 | * Value objects should be implemented by replacing setter methods with a `with` statement, not providing objects that only have getter methods 61 | * PHP needs to decide what it wants to be: 62 | * Languages like Haskell or Clojure can do certain things because everything is immutable - PHP can never achieve this 63 | * Should PHP make architectural changes to support immutability, or accept that this is not the direction PHP should go in? 64 | * Is it better to build tools in user space that support immutability (and make changes to core that support them)? 65 | * Should PHP focus on embracing FP concepts in other ways (e.g: [array_map()](http://php.net/manual/en/function.array-map.php) for iterable objects)? 66 | * [readonly properties rfc](https://wiki.php.net/rfc/readonly_properties) 67 | 68 | ## Final thoughts - how can developers start using immutable and FP concepts in PHP now? 69 | * If you need to change something inside a function, ensure this is based on the input to that function 70 | * Try to eliminate temporary variables inside methods - this will force you into writing smaller methods and using less mutable variables 71 | * Never change the input variables to a function directly 72 | * Use message passing rather than state 73 | * Separate service objects and value objects 74 | 75 | ## Sammy Kaye wraps up with 76 | * Developer shout-out: Fabien Potencier 77 | -------------------------------------------------------------------------------- /episodes/037.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Object-relational mapping (ORM) tools are a great way to model relational databases in your codebase. We discuss the benefits that ORM tools can add to our apps, some problems with the ORM model and where the PHP community seems to be heading when it comes to persisting data. We'll also discuss the opposing active record & data mapper paradigms. 3 | 4 | # Guests 5 | * [Ross Tuck](https://twitter.com/rosstuck) 6 | * [Shawn McCool](https://twitter.com/ShawnMcCool) 7 | * [Marco Pivetta](https://twitter.com/Ocramius) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | A variety of stand-alone ORMs are available e.g: 15 | * [Propel](http://propelorm.org/) 16 | * [Doctrine](http://www.doctrine-project.org/projects/orm.html) 17 | * [Spot ORM](http://phpdatamapper.com/) 18 | 19 | Also a lot of frameworks ship with their own bespoke ORM. 20 | 21 | ## Why should someone who has never used an ORM use one? What's the 'elevator pitch'? 22 | * An ORM is a way to deal with relational databases in your O-O code 23 | * You can apply O-O principles to your data model and encapsulate your data logic 24 | * It represents a step up in complexity, but complexity is relative - a good abstraction removes underlying complexity and provides a simpler interface 25 | * Leave the "boring" parts to someone else 26 | * Cleaner code - codebases with a lot of raw SQL are "noisy" 27 | * ORMs separate our objects and the relationships between them from the details of persistence/how we store them. You can focus on the interface, not the data structure 28 | * An ORM lets you forget things: The design of your objects is your job and the process of saving/loading them to/from storage is the ORM's job 29 | * For some type of application, a DBAL like [PDO](http://php.net/manual/en/book.pdo.php) is sufficient or even more appropriate 30 | 31 | ## What do the panel think of the [Repository Pattern](http://martinfowler.com/eaaCatalog/repository.html) with ORMs? 32 | * [Shawn's article on the Repository Pattern](http://shawnmc.cool/the-repository-pattern) 33 | * Sometimes they are the right way to go and sometimes they aren't 34 | * Using the pattern is helpful when you want to construct objects and think about the persistence separately - it is useful to be able to 'hide' the ORM 35 | * Sometimes it is more useful not to abstract so much - it depends on the tradeoffs 36 | * Marco is currently working on an application which doesn't use an ORM at all 37 | * In small projects, the additional abstraction is often not worth it 38 | * It is also about personal preference/barriers to entry 39 | 40 | ## How do the panel approach mutability vs immutability with reference to ORMs 41 | * If mutable objects make things easier, they are fine 42 | * Immutability may be 'technically' superior, but it is often not 'practically' superior 43 | * O-O code generally uses mutable objects. An ORM should fit into its environment 44 | * Using [CQRS](http://martinfowler.com/bliki/CQRS.html) allows the use of different models/data structures for reading and writing (and hence immutable objects can be used for reading and mutable objects can be used for writing). 45 | 46 | The panel discuss their experiences with [Event Sourcing](http://martinfowler.com/eaaDev/EventSourcing.html) 47 | 48 | ## A comparison of how database access patterns scale 49 | * Direct Database Access: Simplest possible technology - basically zero barrier to entry, but complexity quickly rises with application scale 50 | * [ActiveRecord](https://en.wikipedia.org/wiki/Active_record_pattern): Slightly higher introduction cost, complexity still rises with scale, but at a lower rate 51 | * [DataMapper](https://en.wikipedia.org/wiki/Data_mapper_pattern): Setup complexity high, complexity scales just under linearly as application grows 52 | * [Event Sourcing](http://martinfowler.com/eaaDev/EventSourcing.html): Starting complexity is really high (but decreasing), but complexity is nearly constant 53 | 54 | However, this changes over time. 55 | 56 | ## ORMs and Graph DBs 57 | * Marco talks about [Orient DB ODM](http://www.doctrine-project.org/projects/orientdb-odm.html) - an ORM/(OGM?) for [OrientDB](http://orientdb.com/) 58 | * In some ways object-oriented code is closer to a graph DB model than a relational DB model: 59 | * Objects reference other objects with pointers, and this is also what is happening in a graph DB 60 | * In an SQL database, association between entities is defined by indexes, foreign keys, joins, pivot tables, etc not pointers 61 | * There is an entire episode on [Graph Databases](https://www.phproundtable.com/episode/using-graph-databases-in-php) 62 | 63 | ## What performance benefits do ORMs offer? 64 | * ORMs can provide caching in the case of repeated queries, but this is effectively by coincidence rather than design 65 | * An ORM is about abstraction not performance 66 | * Adding a layer of abstraction will usually **decrease** performance 67 | 68 | ## ActiveRecord vs DataMapper 69 | 70 | ### ActiveRecord: 71 | * A record class or object represents a row of data 72 | * It has user-defined methods based on what the object models 73 | * It also has methods implementing DB functionality (for example, it knows how to save itself) 74 | * ActiveRecord defines its own conventions and idioms 75 | * Models and database are tightly coupled 76 | 77 | ### DataMapper: 78 | * A record class or object only models what it represents in your application 79 | * It must be passed to a separate service object (repository) which deals with operations like saving 80 | * This provides separation of concerns 81 | * DataMapper allows more idiomatic use of the underlying language 82 | * Often sacrifices developer experience to gain architectural purity 83 | 84 | ### Comparison 85 | * [ActiveRecord](https://en.wikipedia.org/wiki/Active_record_pattern) is quick with low barriers to implementation, but suffers from some ambiguity between record logic and object logic 86 | * [DataMapper](https://en.wikipedia.org/wiki/Data_mapper_pattern) has a much higher barrier to entry, but provides a more robust abstraction 87 | * In the PHP community, ActiveRecord vs DataMapper often manifests itself as [Eloquent](https://laravel.com/docs/5.0/eloquent) vs [Doctrine](http://www.doctrine-project.org/) 88 | * It isn't as big an issue as some people turn it into 89 | * A lot of it is about personal preference or the right tool for the job 90 | 91 | ## Further Links 92 | * [Konstantin Kudryashov - Min-maxing Software Costs](https://www.youtube.com/watch?v=uQUxJObxTUs&index=12&list=PLMdXHJK-lGoA9SIsuFy0UWL8PZD1G3YFZ) 93 | 94 | ## Sammy Kaye wraps up with 95 | * Developer Shout-Out: Elliot Levin 96 | * Shameless Plugs 97 | -------------------------------------------------------------------------------- /episodes/038.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | New features of PHP get added via the [request for comments process](https://wiki.php.net/rfc). We are chatting with a few RFC authors about what features they are proposing for the next major version of PHP. 3 | 4 | # Guests 5 | * [Phil Sturgeon](https://twitter.com/philsturgeon) 6 | * [Scott Arciszewski](https://twitter.com/voodooKobra) 7 | * [Andrea Faulds](https://twitter.com/AndreaFaulds) 8 | * [François Laupretre](https://twitter.com/flaupretre) 9 | * [Davey Shafik](https://twitter.com/dshafik) 10 | 11 | Hosted by 12 | * [Sammy K Powers](https://twitter.com/SammyK) 13 | 14 | # Discussion 15 | ## Davey Shafik talks about 16 | * [HTTP 2 push requests support](https://wiki.php.net/rfc/curl_http2_push) 17 | * [HTTP 2 support in CLI server](https://wiki.php.net/rfc/cli_server_http2) 18 | * [Combined Comparison (Spaceship) Operator](https://wiki.php.net/rfc/combined-comparison-operator) 19 | 20 | ## Sammy K talks about 21 | * [Class Constant Visibility](https://wiki.php.net/rfc/class_const_visibility) 22 | 23 | Consensus is "how does this not already exist?" 24 | 25 | ## Phil Sturgeon talks about 26 | * We should steal the retry keyword from Ruby for use in try/catch blocks 27 | 28 | Debate about whether this is better or worse than using a goto ensues. 29 | 30 | ## Andrea Faulds talks about 31 | * [Void Return Types](https://wiki.php.net/rfc/void_return_type) 32 | 33 | Discussion about whether this is the same or different to just returning null. 34 | 35 | * [List Reference Assignment](https://wiki.php.net/rfc/list_reference_assignment) 36 | * [Named Parameters](https://wiki.php.net/rfc/named_params) 37 | 38 | ## François Laupretre talks about 39 | * PCS extensions 40 | * [Cache Key Operation](https://wiki.php.net/rfc/streams-is-cacheable) 41 | * Taking over the PHAR project 42 | 43 | ## Scott Arciszewski talks about 44 | * [Deprecating mcrypt](https://wiki.php.net/rfc/deprecate_mcrypt_rand) 45 | * "Boring" cryptography 46 | * [libsodium](https://github.com/jedisct1/libsodium) 47 | * Pluggable crypto library - "PDO for crypto" 48 | 49 | ## Sammy K wraps up with 50 | * [Deprecations for PHP 7.1](https://wiki.php.net/rfc/deprecations_php_7_1) 51 | 52 | Some discussion around poor approaches to cryptography and random number generation including deprecation/removal of [rand](http://php.net/manual/en/function.rand.php) and [srand](http://php.net/manual/en/function.srand.php) and potential pitfalls/issues with this. 53 | 54 | * [Code of Conduct](https://wiki.php.net/rfc/adopt-code-of-conduct) 55 | * Developer shout-out: Paul Dragoonis 56 | 57 | ## Further Links: 58 | * [PHP The Right Way](http://www.phptherightway.com/) 59 | * [PHP Sadness](http://phpsadness.com/) 60 | * [PHP Town Hall: Code of Conduct](https://phptownhall.com/episode-48-code-of-conduct/) 61 | -------------------------------------------------------------------------------- /episodes/039.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We get an update on status of the project we discussed in [part 1](https://www.phproundtable.com/episode/part-1-turning-an-idea-into-code-for-production) and discuss next steps to take our dance event management app idea to production. 3 | 4 | # Guests 5 | * [Steven Maguire](https://twitter.com/StevenMaguire) 6 | * [Jocelyn Lopez](https://twitter.com/Joclpz) 7 | * Dan Yamamoto 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | ## Intro 14 | * What is [west coast swing](https://en.wikipedia.org/wiki/West_Coast_Swing)? 15 | * Recap of [part 1](https://www.phproundtable.com/episode/part-1-turning-an-idea-into-code-for-production) 16 | * [MVP with fake data](https://www.dancerdeck.com/) 17 | 18 | ## Tech Stack 19 | * [Laravel 5.2](https://laravel.com/) 20 | * [VueJS](http://vuejs.org/) 21 | * [Let's Encrypt](https://letsencrypt.org/) - check out Erika Heidi's articles at Digital Ocean: 22 | * https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-centos-7 23 | * https://www.digitalocean.com/community/tutorials/how-to-set-up-let-s-encrypt-certificates-for-multiple-apache-virtual-hosts-on-ubuntu-14-04 24 | * https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-14-04 25 | * [JSON web tokens](https://jwt.io/) 26 | * [ECMAScript 6](http://es6-features.org/) 27 | 28 | ## Problems Encountered 29 | * Time 30 | * Finding an ORM to work with graph database - [neo4j](http://neo4j.com/) 31 | * The ideal solution vs sticking with what you know 32 | * Building a single page load web app 33 | 34 | ## Where next? 35 | * Review of priorities: 36 | * Event curation: back end done, front end in progress 37 | * Event discovery: done 38 | * Calendar integration: not done 39 | * Participant accounts: back end done, front end in progress 40 | * Event subscription: not started - some discussion around how this should work/feature ideas: 41 | * GitHub terminology ("watch" and "star") vs Facebook terminology ("going" and "like") 42 | * Subscribe by event/subscribe by region 43 | * What events might a user be interested in subscribing to (e.g: venue/accommodation/schedule changes) - could these be handled using Laravel events? 44 | * Live push notifications (schedule events, "milestones") + opt-in or aggregation to avoid spamming users 45 | * Real data: not yet, but this is high priority 46 | * Invitations/partner management: not done 47 | * How do entities in the data model relate to each other - series/groups? Some discussion of polymorphic data model. 48 | * Should endpoints be context-aware? 49 | * What data would API users like to consume? 50 | * Event attendees - stats/badges, biographies 51 | * Event directors - what services are on offer that I could use? 52 | * What goes into the next iteration - long list: 53 | * Finish Event curation 54 | * Participant accounts 55 | * Event subscription/notifications 56 | * Partner management 57 | * Pro Schedule 58 | * Gamification/milestones 59 | * Event rating system 60 | * What goes into the next iteration - short list: 61 | * Finish Event curation 62 | * Participant accounts 63 | * Event subscription 64 | 65 | ## Sammy Kaye wraps up with 66 | * Developer shout-out: Ben Corlett 67 | 68 | ## Further Links: 69 | [Full-Stack Radio](http://www.fullstackradio.com/) 70 | -------------------------------------------------------------------------------- /episodes/040.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Traditional relational databases like MySQL or Postgres are really good at providing many solutions to the problem of persisting state. But these types of database are really horrible at querying highly connected models in an efficient way. 3 | 4 | Graph databases like [Neo4j](http://neo4j.com/) and [OrientDB](http://orientdb.com/orientdb/) excel at highly connected data. In fact, graph technologies are the backbone of social networks like Facebook and Twitter. We discuss how to think about our data using the graph model and what tools we can use in our PHP projects to interface with them. We also discuss the considerations we'll need to make when deciding whether or not to use a graph database in our next project. 5 | 6 | # Guests 7 | * [Michelle Sanver](https://twitter.com/michellesanver) 8 | * [Ed Finkler](https://twitter.com/funkatron) 9 | * [Jeremy Kendall](https://twitter.com/JeremyKendall) 10 | * Chris White 11 | 12 | Hosted by 13 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 14 | 15 | # Sammy Kaye Introduces 16 | * A classic problem in graph theory: [The Seven Bridges of Königsberg](https://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg) 17 | 18 | # Discussion - The panel talks about... 19 | ## Query Languages 20 | Graph DBs don't usually use SQL. The most common query languages are: 21 | * [Cypher](https://en.wikipedia.org/wiki/Cypher_Query_Language) 22 | * [Gremlin](https://github.com/tinkerpop/gremlin) 23 | * [OrientDB](http://orientdb.com/) does allow the use of SQL among other query languages 24 | 25 | ## What are the key concepts of graph DBs and how do they differ from relational DBs? 26 | * Graph DBs are flexible 27 | * Graph DBs use 'nodes' and 'edges'. These can be thought of as 'entities'/'nouns' and 'relationships'/'verbs' 28 | * Graph DBs map more closely to how we might think or draw a diagram 29 | * It is easy to get started, but the complexity quickly ramps up 30 | * Graph DBs are new - there's less information out there. Relational DBs are well studied and well documented 31 | * Graph DB schema can be evolved much more easily than relational DBs 32 | 33 | ## When should I use graph DBs - what are the use cases? 34 | * Highly connected data: If your data model uses a lot of joins, graph DBs may be a good approach 35 | * If your data model uses a lot of one-to-one relationships, or 'get item by id' type queries, graph DBs are not a good fit 36 | * If you don't yet know what sort of queries you want to answer, graph DBs can offer flexibility later 37 | * If your queries are based more around relationships or verbs than objects or nouns, graph DBs may be a good approach 38 | * 'sparse' schemas lend themselves to graph DBs 39 | * There is some debate from the panel around whether graph DBs should work **alongside** relational DBs or **instead of** relational DBs 40 | 41 | ## How should we interact with graph databases? 42 | * Adapt existing ORMs to work with graph DBs like [NeoEloquent](https://github.com/Vinelab/NeoEloquent) 43 | * Throw out the ORM model and build specialised OGMs like [Neo4jrb](https://github.com/neo4jrb/neo4j) 44 | * Write query languages like Cypher/Gremlin/etc directly 45 | * Specialised tools like recommendation engines e.g: [neo4j-reco](https://github.com/graphaware/neo4j-reco) 46 | 47 | ## Other topics 48 | * Security - do we need to worry about 'cypher injection'? Most libraries have named parameters 'out of the box' 49 | * Graphical tools e.g: [neo4j browser](http://neo4j.com/developer/guide-data-visualization/#_screencast_the_neo4j_browser) 50 | * Graph DBs don't give nodes auto increment IDs - how do we identify nodes? 51 | * We can use uuids 52 | * With graph DBs, we are less likely to need IDs 53 | * Some graph DB engines discourage the use of IDs 54 | * Use 'natural' IDs where possible 55 | * Graph DBs can benefit from indexing and unique constraints in much the same way as relational DBs 56 | * Neo4j doesn't have triggers. OrientDB does 57 | * Neo4j is more of a 'pure' graph database. OrientDB combines NoSQL and graph approaches 58 | 59 | ## A Concrete example 60 | Sammy Kaye talks about a problem he is facing with his [DancerDeck](https://www.dancerdeck.com/) project, discussed in episodes [21](https://www.phproundtable.com/episode/part-1-turning-an-idea-into-code-for-production) and [39](https://www.phproundtable.com/episode/part-2-turning-an-idea-into-code-for-production): 61 | 62 | I want to be able to allow a user to subscribe (edge) to an event (node), but manage what sort of notifications are associated with that subscription. Should I use multiple edges between the user and node (an edge for each notification), or one edge (subscribe) with multiple properties (notifications) associated with that edge? 63 | 64 | The panel offer their opinions on both solutions and also propose another solution: represent each notification as a node (rather than en edge or an edge property) and create edges between the user and the notification nodes. 65 | 66 | Ultimately, it depends on how you want to query it. 67 | 68 | ## Sammy Kaye wraps up with 69 | * A return to [The Seven Bridges of Königsberg](https://en.wikipedia.org/wiki/Seven_Bridges_of_K%C3%B6nigsberg) problem 70 | * [PHP Roundtable on GitHub](https://github.com/PHPRoundtable/) 71 | * Developer shout-out: Adam Engebretson 72 | -------------------------------------------------------------------------------- /episodes/041.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | The [PHP-FIG](http://www.php-fig.org/) has really helped the PHP community get onboard the collaboration train with really great standards like the PSR-4 autoloading standard and the PSR-7 HTTP message interfaces. 3 | 4 | We discuss PSR-0 through PSR-13 and the process they go through to become standards. We also discuss where the FIG came from and the possible big changes coming to the organization soon. 5 | 6 | # Guests 7 | * [Cal Evans](https://twitter.com/CalEvans) 8 | * [Paul Jones](https://twitter.com/pmjones) 9 | * [Paul Dragoonis](https://twitter.com/dr4goonis) 10 | * [Chris Tankersley](https://twitter.com/dragonmantank) 11 | * [Evert Pot](https://twitter.com/evertp) 12 | * [Samantha Quiñones](https://twitter.com/ieatkillerbees) 13 | * [Michael Cullum](https://twitter.com/michaelcullumuk) 14 | * [Matthew Weier O’Phinney](https://twitter.com/mwop) 15 | 16 | Hosted by 17 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 18 | 19 | # Discussion - The panel talks about... 20 | 21 | > **Show note merge conflict.** For this episode, both [Chris Shaw](https://github.com/chris48s) and [Ken Guest](https://twitter.com/kenguest) sent in a pull request with the show notes which created quite a merge conflict. :) But I'm very happy for your contributions! Thanks so much Chris and Ken! 22 | 23 | ### Intro 24 | * Misnomers - Phil Sturgeon didn't start the phpfig :lol: (David & Travis were the instigators according to Cal & Paul [53:28](https://youtu.be/tAHfoh641wM?t=3208)). 25 | * Puntastic fun. 26 | 27 | ### What was the PHP Community like before the FIG? 28 | * Poor communication and co-operation 29 | * Frameworks started to establish standards [3:09](https://www.youtube.com/watch?v=tAHfoh641wM&t=189) 30 | * Multiple competing standards/framework-specific standards 31 | * [PEAR](https://pear.php.net/) was the closest thing to a standards body [5:07](https://www.youtube.com/watch?v=tAHfoh641wM&t=307); [5:52](https://www.youtube.com/watch?v=tAHfoh641wM&t=352) and sound like they were used as the main foundation for the first few PSRs[6:15](https://www.youtube.com/watch?v=tAHfoh641wM&t=374). But the PEAR Standards didn't keep up with the changing landscape - autoloaders. Evert sounds like he misses PEAR as it was/is more than just a Coding Standard :( [7:04] (https://www.youtube.com/watch?v=tAHfoh641wM&t=424) 32 | * [PSR-0](http://www.php-fig.org/psr/psr-0/) represented the first step towards the [PHP-FIG](http://www.php-fig.org/), but it wasn't called PSR-0 at the time. It was just 'an autoloading standard' 33 | * Backlash from the general community. [8:27](https://www.youtube.com/watch?v=tAHfoh641wM&t=507) 34 | 35 | ### What is the role of a PHP-FIG secretary? 36 | * Admin tasks 37 | * Vote tracking 38 | * Co-ordination 39 | * Point of contact 40 | * Impartial - not representing a particular project 41 | 42 | ### What process does a PSR go through to become a standard? 43 | * See [PSR workflow](http://www.php-fig.org/bylaws/psr-workflow/) for full process. Core steps are: 44 | * Proposal 45 | * Entrance vote 46 | * PSR is assigned a number 47 | * Draft 48 | * Review 49 | * Final acceptance vote 50 | * Sometimes this takes a long time. [PSR-6](http://www.php-fig.org/psr/psr-6/) took over 4 years to become a standard 51 | 52 | ### Changes in the PHP-FIG's approach 53 | * The PHP-FIG is currently undergoing an identity crisis and drafting new by-laws 54 | * Historically, the FIG has strived to arrive at a 'perfect' standard and set it in stone 55 | * The group is moving towards a model where standards can evolve 56 | * One approach being considered is that a PSR must have 2 interoperable real-world implementations before standardisation 57 | * Standards can now be deprecated - this is a new status. [PSR-0](http://www.php-fig.org/psr/psr-0/) is now deprecated in favour of [PSR-4](http://www.php-fig.org/psr/psr-4/) 58 | * [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md) will deprecate [PSR-2](http://www.php-fig.org/psr/psr-2/) 59 | * A new status 'abandoned' will also be introduced for standards which are no longer actively being drafted 60 | 61 | ### PSRs currently in draft 62 | * [PSR-5](https://github.com/phpDocumentor/fig-standards/tree/master/proposed) - PHPDoc Standard 63 | * [PSR-9](https://github.com/php-fig/fig-standards/blob/master/proposed/security-disclosure-publication.md) - Security disclosure and [PSR-10](https://github.com/php-fig/fig-standards/blob/master/proposed/security-reporting-process.md) - Security Advisories (related) 64 | * [PSR-8](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-8-hug/psr-8-hug.md) - Huggable Interface (an April fools joke). 65 | * There is actual legitimate debate on whether this should be abandoned or implemented 66 | * Supporters of PSR-8 cite examples such as [IP over Avian Carrier](https://www.ietf.org/rfc/rfc1149.txt) and [HTTP Status code 418](https://httpstatuses.com/418) as grounds to ratify 67 | * [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md) - Container Interface 68 | * [PSR-13](https://github.com/php-fig/fig-standards/blob/master/proposed/links.md) - Hypermedia Links 69 | 70 | ### Why are [PSR-1](http://www.php-fig.org/psr/psr-1/) and [PSR-2](http://www.php-fig.org/psr/psr-2/) different? 71 | * Paul M. Jones explains that PSRs 1 and 2 were once just the one document and split in two to make them more likely to be adopted. 72 | * Coding style is a controversial topic 73 | * Splitting into 2 standards was a way to successfully ratify it 74 | * PSR-1 deals with the most important/least controversial aspects of coding style 75 | * PSR-2 deals with aspects that are less important/more open to interpretation 76 | * The panel talks tabs vs spaces (yeah they went there!) 77 | * Sammy explaining tabs v Spaces to his dance partner [39:30](https://youtu.be/tAHfoh641wM?t=2375) 78 | * [PSR-12](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md) will deprecate [PSR-2](http://www.php-fig.org/psr/psr-2/) updates PSR-2 to deal with new additions to the language in PHP7 e.g: [Return type hints](https://wiki.php.net/rfc/return_types) 79 | * PSR-1 will not be deprecated 80 | 81 | There is an [entire episode](/episode/psr-7-streams-immutability-middleware-oh-my) on PSR-7 82 | 83 | ### What is the role of PHP-FIG in the community 84 | * The panel discusses the role of the PHP-FIG - there are a variety of opinions, both complimentary and conflicting. 85 | * People want a Standards Body, says Samantha. [59:01](https://www.youtube.com/watch?v=tAHfoh641wM&t=3543) 86 | * Composer born out of the FIG Autoloading PSRs, according to Matthew [56:34](https://www.youtube.com/watch?v=tAHfoh641wM&t=3394) 87 | 88 | ### Where is the PHP-FIG going in future? 89 | * Not officially proposed yet! [1:03:53](https://youtu.be/tAHfoh641wM?t=3837) 90 | * [Member projects](http://www.php-fig.org/members/) vote on PSRs, but there are some problems: 91 | * It is difficult to achieve quorum 92 | * Not everyone is engaged 93 | * Not all of the members are engaged with/knowledgable about every topic 94 | * A new structure aims to solve some of these problems: 95 | * Working group structure: people who know/care about the topic become involved in the working group for that specific PSR 96 | * Core committee 97 | * Specifications are reviewed by the core committee 98 | * They don't handle the **content** of the PSR - just a final QA (e.g: ensure 2 working interoperable implementations) 99 | * The member projects include the community in the FIG and lend weight to the FIG, but they don't all have to have input on every PSR 100 | 101 | ### Mentions 102 | * [Brett Bieber](https://twitter.com/saltybeagle) 103 | * [David Coallier](https://twitter.com/davidcoallier) 104 | * [Helgi Þorbjörnsson](https://twitter.com/h) 105 | * [Larry Garfield](https://twitter.com/Crell) 106 | * [Mike van Riel](https://twitter.com/mvriel) 107 | * [Nate Abele](https://twitter.com/nateabele) 108 | * [Phil Sturgeon](https://twitter.com/philsturgeon) 109 | * [Stefan Koopmanschap](https://twitter.com/skoop) 110 | * [Travis Swicegood](https://twitter.com/tswicegood) 111 | 112 | ### The PSRs 113 | * [PSR-0: Autoloading Standard](http://www.php-fig.org/psr/psr-0/) 114 | * [PSR-1: Basic Coding Standard](http://www.php-fig.org/psr/psr-1/) 115 | * [PSR-2: Coding Style Guide](http://www.php-fig.org/psr/psr-2/) 116 | * [PSR-3: Logger Interface](http://www.php-fig.org/psr/psr-3/) 117 | * [PSR-4: Autoloader](http://www.php-fig.org/psr/psr-4/) 118 | * [PSR-5: PHPDoc Standard](https://github.com/php-fig/fig-standards/pull/169) 119 | * [PSR-6: Caching Interface](http://www.php-fig.org/psr/psr-6/) 120 | * [PSR-7: HTTP message interfaces](http://www.php-fig.org/psr/psr-7/) 121 | * [PSR-8: Mutually Assured Hug](https://github.com/php-fig/fig-standards/blob/master/proposed/psr-8-hug/psr-8-hug.md) 122 | * [PSR-9: Security Reporting Process](https://github.com/php-fig/fig-standards/blob/master/proposed/security-reporting-process.md) 123 | * [PSR-10: Security Disclosure Publication](https://github.com/php-fig/fig-standards/blob/master/proposed/security-disclosure-publication.md) 124 | * [PSR-11: Container Interface](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md) 125 | * [PSR-12: Extended Coding Style Guide](https://github.com/php-fig/fig-standards/blob/master/proposed/extended-coding-style-guide.md) 126 | * [PSR-13: Link Definition Interfaces](https://github.com/php-fig/fig-standards/blob/master/proposed/links.md) 127 | 128 | 129 | ## Sammy Kaye wraps up with 130 | * Developer shout-out: [Adam Culp](https://twitter.com/adamculp) 131 | 132 | ## Further Links and Shameless Plugs: 133 | * [Day Camp 4 Developers](https://daycamp4developers.com/) 134 | * [Docker for Developers](https://leanpub.com/dockerfordevs) 135 | * [Doctrine](http://www.doctrine-project.org/) 136 | * [Girls Who Code](http://girlswhocode.com) 137 | * [Laravel](https://laravel.com/) 138 | * [Modernising Legacy Applications in PHP](http://mlaphp.com/) 139 | * [PEAR](http://pear.php.net) 140 | * [phpBB](https://www.phpbb.com/) 141 | * [PHP South Coast](http://phpsouthcoast.co.uk) 142 | * [PPI Framework](http://www.ppi.io/) 143 | * [SabreDav](http://sabre.io/) 144 | * [Sculpin; a Static Site Generator](https://sculpin.io/) 145 | * [Stash](http://www.stashphp.com/) 146 | * [Symfony](http://symfony.com/) 147 | * [VueJS](http://vuejs.org/) 148 | * [Zend Framework](http://framework.zend.com/) 149 | -------------------------------------------------------------------------------- /episodes/042.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | The technologies that run the web are constantly changing. We discuss strategies for staying on top of the constant flux with continuous learning throughout your career, having mentors, engaging regularly with your peers, contributing to open source projects, voracious reading, and travel to programming events. 3 | 4 | # Guests 5 | * [Matthew Setter](https://twitter.com/settermjd) 6 | * [Andy Huggins](https://twitter.com/andy_huggins) 7 | * [Henning Glatter-Götz](https://twitter.com/hglattergotz) 8 | * [Tom Oram](https://twitter.com/tomphp) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## An event that made you realise you weren't staying relevant? 16 | * Popular answer - Not doing unit testing - more than one person talks about the moment they realised they needed to start writing tests 17 | * Discovery that reading books about development (on Kindle) is a great way to stay up-to-date 18 | 19 | ## How does the panel stay up to date? 20 | * Books 21 | * Talking to other devs (user groups etc) 22 | * Podcasts - anyone know of a [good one](https://www.phproundtable.com/)? ;) 23 | * [Twitter](https://twitter.com/) delivers a lot of info very quickly, but has a high signal:noise ratio - [Nuzzel](http://nuzzel.com/) can help 24 | 25 | Sammy asked a bunch of programmers on twitter: What one book made you become a better programmer? Most common answer was [Clean Code](http://www.amazon.co.uk/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882). 26 | 27 | It can be easy to focus so much on doing things the "right" way or the most modern way to the point it becomes a distraction from the core problem solving. 28 | 29 | ## How does the panel avoid becoming "paralysed" into inaction as a result of this? 30 | * Think of code as creative writing - write a first draft, second draft, etc.. 31 | * With so many trends in software development, pick the most important to you and focus on them 32 | * "Mastery" is understanding what level of perfection the task requires 33 | * Another book recommendation: [On Writing Well](http://www.amazon.com/On-Writing-Well-Classic-Nonfiction/dp/0060891548) - a book about creative writing with lessons that are applicable to software 34 | 35 | The next book on Sammy's list is [Refactoring: Improving the Design of Existing Code](http://www.amazon.co.uk/Refactoring-Improving-Design-Existing-Technology/dp/0201485672) 36 | 37 | ## How do the panel approach refactoring? 38 | * Refactor as you go: 39 | * Make small feature branches 40 | * Every few features, do a small cleanup 41 | * Don't treat refactoring as a task in itself 42 | 43 | ## Tools come and go quickly. Techniques are timeless and move slowly. 44 | ### Some timeless techniques: 45 | * Unit(/automated) testing 46 | * Refactoring 47 | * Functional Testing 48 | * Design patterns 49 | * Algorithms 50 | 51 | ## How do the panel become better programmers? 52 | * Ask someone who has been doing it for a while - [PHP Mentoring](https://phpmentoring.org/) can help with that 53 | * Connect with the community - user groups, conferences, workshops, etc 54 | * Speak at a user group 55 | * You learn a lot from talking to/watching/working with other developers 56 | * Code reviews 57 | * Contributing to open source: 58 | * Follow the contributing guidelines 59 | * Get feedback on your code 60 | * Find a project you use yourself - find a bug that needs fixing or a feature that needs adding 61 | * The process associated with getting a PR accepted to a large project is an eye-opener 62 | * Think of submitting a patch as an opportunity to receive a free code review 63 | * Look for issues tagged 'easy' or 'beginner' 64 | * [up-4-grabs.net](http://up-for-grabs.net/#/) - projects 'advertising' easy issues for new contributors 65 | * [First Timers Only](https://medium.com/@kentcdodds/first-timers-only-78281ea47455#.o04s2sjhq) 66 | * [Making your first pull request](http://www.charlotteis.co.uk/making-your-first-pull-request/) 67 | 68 | ## Other resources/links 69 | * [Clean coders video series](https://cleancoders.com/videos/clean-code) 70 | * If you can't get to a conference/user group in your area, check out [Nomad PHP](https://nomadphp.com/) 71 | * [Jeff Carouth's Development Book Club](https://carouth.com/blog/categories/book-club/) 72 | 73 | ## Sammy Kaye wraps up with 74 | * Developer Shout Out: Raquel Vélez [(@rockbot)](https://twitter.com/rockbot) 75 | * Shameless Plugs 76 | * [Lone Star PHP](http://lonestarphp.com/) 77 | -------------------------------------------------------------------------------- /episodes/044.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Async? Isn't that like AJAX in Javascript or something? Most PHP developers encounter asynchronous code for the first time in Javascript, but not many are aware that PHP can do async too. We discuss asynchronous programming in PHP and how we might be able to implement it in our own projects using various libraries. We also take a look at how async features could be added to PHP core to support async natively. 3 | 4 | # Guests 5 | * [Christopher Pitt](https://twitter.com/assertchris) 6 | * [Sara Golemon](https://twitter.com/SaraMG) 7 | * [Aaron Piotrowski](https://twitter.com/trowski2002) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## How does asynchronous programming differ from synchronous programming? 15 | ### In synchronous programming 16 | * We issue a statement, 17 | * We wait for it to complete 18 | * ..and then move on to the next statement. 19 | 20 | ### In asynchronous programming 21 | * We issue a statement 22 | * While we are waiting for it to complete, we can perform other tasks 23 | * When it has finished, we run a callback function 24 | 25 | This means we can reduce total execution time using an asynchronous methodology because we minimise the time spent waiting for operations to complete. 26 | 27 | The downside is that often callback depend on callbacks which depend on other callbacks 28 | 29 | ## How can we avoid deeply nested callbacks (Callback Hell)? 30 | * We don't have to use callbacks: 31 | * `async`/`await` in [Hack](http://hacklang.org/) and [C#](https://msdn.microsoft.com/en-us/library/hh191443.aspx) 32 | * [Threads in Java](https://docs.oracle.com/javase/tutorial/essential/concurrency/) 33 | * Use libraries like [cURL](http://php.net/manual/en/book.curl.php) or [Guzzle](http://docs.guzzlephp.org/en/latest/) to help 34 | * [Promises](http://12devs.co.uk/articles/promises-an-alternative-way-to-approach-asynchronous-javascript/) (or 'futures') can help 35 | * Promises don't avoid nesting callbacks - they just provide a nicer syntax to deal with them 36 | 37 | ## What is the difference between multi-threading and asynchronous programming? 38 | * Usually asynchronous code/languages will **use** threads 39 | * This is an implementation detail which is abstracted from the user 40 | * Usually in asynchronous code, all of the core application logic takes place in one thread 41 | * Other threads are usually 'lightweight' and are just waiting for some blocking/IO code to complete 42 | * In true multithreaded programming, core program logic will be executed in many threads 43 | 44 | ## Introducing Asynchronous concepts into PHP 45 | * This is unlike the 'traditional' implementation/libraries we are used to in PHP 46 | * We can use multi-threading in PHP using the [pthreads extension](http://php.net/manual/en/book.pthreads.php) 47 | * This requires [Zend Thread Safety](http://php.net/manual/en/pthreads.requirements.php) 48 | * Threads are not necessary for concurrent execution in PHP - [Process Control Extensions](http://php.net/manual/en/refs.fileprocess.process.php) use process forking 49 | * If we are to write PHP asynchronously, this rules out use of a lot of functions/libraries we like to use, because they block on IO 50 | * These problems are not unique to PHP 51 | 52 | ## Libraries for writing async PHP 53 | * [Icicle](https://github.com/icicleio/icicle) 54 | * [React PHP](http://reactphp.org/) 55 | * On a simple level, it is possible to write asynchronous PHP code by spawning additional processes using [exec](http://php.net/manual/en/function.exec.php) - you don't **need** a library 56 | 57 | ## A PSR for async in PHP 58 | * Find out more at https://github.com/async-interop 59 | * This is not a PSR yet, but these standards will be proposed to the [FIG](http://www.php-fig.org/) in future 60 | 61 | ## PHP 5.5 introduces [Generators](http://php.net/manual/en/language.generators.overview.php) and the `yield` keyword - do these help us to use asynchronous techniques in PHP? 62 | * [Icicle](https://github.com/icicleio/icicle) makes use of this heavily 63 | * This allows us to write asynchronous code that looks more like synchronous code 64 | * We may see an implementation of `async`/`await` in PHP in future, but not soon 65 | * This is similar to the path that [NodeJS](https://nodejs.org/en/) and [Python](https://www.python.org/) have followed or are following 66 | * This will require non-blocking versions of existing blocking functions like [file_get_contents()](http://php.net/manual/en/function.file-get-contents.php) to be written, but this process is underway 67 | 68 | ## Sammy Kaye wraps up with 69 | * Developer Shout-out: Stephen Coakley 70 | * Shameless Plugs 71 | -------------------------------------------------------------------------------- /episodes/046.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | If you've ever gotten a number of weird looking characters in your database or on your website like, "�" and didn't know why, then this episode is for you. Those bizarre characters called "mojibake", rear their ugly heads when we don't account for a consistent character encoding. Today we discuss what character encoding is, how to accommodate for it in HTML, PHP & your database, and how we can ensure we'll never encounter an unexpected alien character in our web apps again. 4 | 5 | 6 | # Guests 7 | * [Andreas Heigl](http://andreas.heigl.org/) 8 | * [Evert Pot](https://evertpot.com/) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## What are character encodings? 16 | * Comparison of number systems (base-10, binary, hexadecimal) 17 | * Historical development of character maps and encodings (telegram, ASCII, ISO-8859-1...) 18 | * Unicode and its implementations (UTF-8, UTF-16, UTF-32) 19 | * UTF-8 uses 1-4 bytes per character--shows all Unicode characters while keeping a small file size 20 | * UTF-16 uses 2 bytes per character, so results in larger files 21 | * UTF-32 uses 4 bytes per character, so results in even larger files 22 | 23 | ## Character encodings in PHP 24 | * Some other languages have a UTF-8 core, while PHP stores strings a series of bytes--can result in misinterpretation/mojibake 25 | * Mind the [multibyte string functions](http://php.net/manual/en/ref.mbstring.php): 26 | * E.g., [`strpos()`](http://php.net/manual/en/function.strpos.php) works by counting a number of bytes; this is unreliable for UTF-8, so use [`mb_strpos()`](http://php.net/manual/en/function.mb-strpos.php) for unicode strings 27 | * There is a php.ini setting (named?) which overloads functions like `strpos` with their multibyte versions. This it NOT RECOMMENDED as it can cause weird bugs, whether when switching hosts or when using 3rd-party code that wasn't written with this in mind. 28 | * php7: the [IntlChar class](http://php.net/manual/en/class.intlchar.php) offers many useful static functions, e.g. [`IntlChar::chr()`](http://php.net/manual/en/intlchar.chr.php) and [`IntlChar::isWhitespace`](http://php.net/manual/en/intlchar.iswhitespace.php) 29 | * php7: [`\u` escape for unicode codepoints](http://php.net/manual/de/migration70.new-features.php#migration70.new-features.unicode-codepoint-escape-syntax) in strings 30 | 31 | ## Character encodings in HTML 32 | * HTML5: [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#attr-charset) 33 | * [`Content-Type: text/html; charset=utf-8`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) HTTP header 34 | * [`
`](https://developer.mozilla.org/en/docs/Web/HTML/Element/form) 35 | 36 | ## Character encodings in MySQL 37 | * MySQL default encoding is still `latin1_swedish_ci`--beware 38 | * Only `utf8mb4` supports the full range of UTF-8 characters (as people have discovered from trying to store emoji) 39 | * `varbinary` and `blob` consume less space than utf8 `varchar`, so they are useful in fields that users won't touch or whose contents never need to include special chars (e.g. URLs) 40 | * Is there any other tradeoff? 41 | 42 | ## Tips/best practices 43 | * Save source files as UTF-8 without BOM. 44 | * Always use `` and a `Content-Type` header. 45 | * Remember that [`header()`](http://php.net/manual/en/function.header.php) must precede any echoed output. (Presence of a BOM can cause bugs here.) 46 | * Storing UTF-8 special characters in their native form (rather than as escaped sequences) in your source can act as "canary" for others--if I see mojibake, maybe my IDE/editor is not configured correctly? 47 | * For MySQL, use `SET NAMES utf8` at the beginning of every connection 48 | * Always validate inputs; always consider character encoding for input (whether from user or APIs), persistence, and output. 49 | * Remember that connections/clients themselves _also_ have encodings 50 | * Mismatched encoding bugs can hide among Roman alphanumerics, since ISO-8859 and UTF-8 are compatible in these lower codepoints. Check higher codepoints to be sure. 51 | 52 | ## Sammy Kaye wraps up with 53 | * Developer Shout-out sponsor: [Laracasts.com](https://laracasts.com/) 54 | * Developer Shout-out: [Michael Cullum](https://laracasts.com/), [PHP-FIG](http://www.php-fig.org/) Secretary 55 | * Shameless plugs 56 | * [PHP.UserGroup](http://php.ug/) 57 | * [sabre/dav](http://sabre.io/dav/) 58 | -------------------------------------------------------------------------------- /episodes/047.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | HTTP/1.1 will eventually be replaced by HTTP/2 so it's important for us PHP nerds to know all about the latest version of the HTTP protocol that's already running some of the internet's biggest websites. We discuss the things we need to know to start using HTTP/2 in our next PHP app. 3 | 4 | We also go briefly off topic to discuss the status of PHP 7.1 and the [ramsey/uuid lib](https://github.com/ramsey/uuid). 5 | 6 | # Guests 7 | * [Davey Shafik](https://twitter.com/dshafik) 8 | * [Ben Ramsey](https://twitter.com/ramsey) 9 | * [Junade Ali](https://twitter.com/IcyApril) 10 | 11 | Hosted by 12 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 13 | 14 | # HTTP/2 15 | 16 | ## Why move away from HTTP/1.1? 17 | * We have stretched the limits of HTTP/1.1 18 | * Pressure/innovation from Google: 19 | * Google developed its own [SPDY](https://en.wikipedia.org/wiki/SPDY) protocol 20 | * SPDY was later folded into the HTTP/2 specification 21 | * Some devices/browsers still support only SPDY 22 | * Improvements in efficiency and security 23 | 24 | ## What are the usage stats for HTTP/2? 25 | * The **big** sites (google, facebook, twitter) are all using HTTP/2 where possible 26 | * Some cloud providers e.g: [cloudflare](https://www.cloudflare.com/) are already using HTTP/2 either by default or as an option 27 | * ~60% of browsers support HTTP/2 28 | * All browser implementations effectively require TLS for HTTP/2 communication 29 | * Due to these support/requirements constraints, a significant proportion of traffic falls back to HTTP/1.1 30 | * One of the barriers to greater adoption of HTTP/2 is persuading users to switch on [TLS](https://en.wikipedia.org/wiki/Transport_Layer_Security) 31 | * TLS unlocks the benefits of HTTP/2, but also: 32 | * It offers improved security over SSL 33 | * Google uses it as a ranking signal 34 | * TLS certificates are now available for free from [Let's Encrypt](https://letsencrypt.org/) 35 | * HTTP/2 negates a lot of the performance overhead associated with encrypted HTTP traffic 36 | * HTTP/2 is in use by 8.2% of websites surveyed by [w3techs](https://w3techs.com/) as of June 2016 37 | 38 | ## How does PHP help us to implement HTTP/2? 39 | * [cURL](http://php.net/manual/en/book.curl.php) support for handling [server push](https://tools.ietf.org/html/rfc7540#section-8.2) will be part of PHP 7.1 40 | * There is an [open RFC](https://wiki.php.net/rfc/cli_server_http2) for adding support for HTTP/2 to PHP's CLI server 41 | * This will introduce some additional dependencies: [nghttp2](https://nghttp2.org/) and [OpenSSL](https://www.openssl.org/) 42 | 43 | ## What is multiplexing in the context of HTTP/2? 44 | * Multiplexing allows us to interleave frames containing responses relating to multiple requests using a single connection 45 | * HTTP/1.1 requires a separate TCP connection for each request/responses 46 | * There are some limits on this: 47 | * ngnix defaults to 128 streams per connection 48 | * Chrome defaults to 256 streams per connection 49 | 50 | ## What do HTTP/2 request/responses look like? 51 | * From a user-level perspective, pretty much the same as a HTTP/1.1 request/responses 52 | * HTTP/2 requests still use [HTTP verbs](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods). Requests and responses still have a head and a body, etc 53 | * At a lower level: 54 | * Header and data frames are separated 55 | * HTTP/2 is a binary protocol 56 | * Frames will be multiplexed 57 | * Unless you are directly writing a client or server, little will change from your perspective 58 | * If you **are** writing your own client or server, [h2spec](https://github.com/summerwind/h2spec) can help you with this 59 | * More info on the low-level details is in [RFC 7540](https://tools.ietf.org/html/rfc7540#section-4.1) 60 | 61 | ## How does server push work? 62 | * The server can send a frame called a [push promise](https://tools.ietf.org/html/rfc7540#section-6.6) 63 | * The client can choose to accept or decline the asset 64 | * If the client accepts, the asset will be delivered as if it had been requested by the client and cached for future use 65 | * This could be used to help browsers to start pre-fetching/pre-caching assets such as javascript, css, images and webfonts before starting to parse the HTML of a web page, for example. 66 | 67 | ## Do optimisation techniques we use in HTTP/1.1 apply to HTTP/2? 68 | * [Domain Sharding](https://www.maxcdn.com/one/visual-glossary/domain-sharding-2/) is broadly rendered irrelevant by multiplexing. Sharding resources across subdomains probably makes performance worse in HTTP/2 as it increases the number of DNS lookups that must be performed (and potentially TCP connections that must be opened) to complete a request. 69 | * [CSS Sprites](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS) may still be a valid technique 70 | * If using GZip compression, minification is of dubious value anyway 71 | * HTTP/2 may allow us to reduce the amount of pre-processing we need to do on css/js in future 72 | * Each technique will need to be evaluated in isolation. HTTP/2 is sufficiently new that best practices are still not fully defined 73 | 74 | ## If my CDN uses HTTP/2, does it help performance if my origin also serves HTTP/2 75 | * It will benefit communication between the origin and cache, but how substantial this benefit is depends on how often the cache fetches from the origin 76 | * The largest performance benefit is to be found using HTTP/2 between the CDN and the end-user 77 | * HTTP/2-enabled cache may still fetch from the origin over HTTP/1.1 78 | 79 | ## Can I just enable HTTP/2 and immediately start seeing performance benefits? 80 | * Some performance benefits will apply immediately (e.g: 81 | * multiplexing 82 | * more efficient binary protocol 83 | * Some benefits (e.g: effective use of push headers) will require change/optimisation to take advantage of them 84 | * The community is still working out best practices 85 | * Upgrading is frictionless: 86 | * Clients that can use HTTP/2 will do so 87 | * Clients that don't support HTTP/2 can fall back to HTTP/1.1 88 | * If you're using apache, enable [mod_http2](https://httpd.apache.org/docs/2.4/mod/mod_http2.html) 89 | 90 | # Tangents 91 | 92 | ## What is the status of PHP 7.1? 93 | * [PHP 7.1 Alpha 1](http://php.net/archive/2016.php#id2016-06-09-1) is out 94 | * Working towards beta 1 95 | * 7.1 will be a "loaded version": lots of new features 96 | * Will hopefully not include many non-backwards compatible changes 97 | 98 | ## Are there any plans to add [ramsey/uuid lib](https://github.com/ramsey/uuid) to PHP as a core extension? 99 | * Core extensions are difficult to iterate 100 | * Keeping it as a package that can be required by composer provides more flexibility 101 | * There is a PHP [uuid](https://pecl.php.net/package/uuid) extension 102 | * It only works on linux due to dependency on `/dev/random` 103 | 104 | # Sammy Kaye wraps up with 105 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 106 | * Developer Shout-out: Jessica Mauerhan 107 | * Shameless Plugs: 108 | * [Let's Encrypt](https://letsencrypt.org/) 109 | * [Password Shaming](http://password-shaming.tumblr.com/) 110 | * [Plain Text Offenders](http://plaintextoffenders.com/) 111 | -------------------------------------------------------------------------------- /episodes/048.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | The demand for DevOps skills is growing more and more in modern web development. But all the hype and demand is met with myriad DevOps tools. Staying abreast of how these tools can help make our jobs easier can be daunting. So today we take a closer look at one of these tools called [Docker](https://www.docker.com/) which takes a microservices-architecture approach to managing your servers. 3 | 4 | # Guests 5 | * [Phillip Shipley](https://twitter.com/phillipshipley) 6 | * [Chris Tankersley](https://twitter.com/dragonmantank) 7 | 8 | Hosted by 9 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 10 | 11 | # Discussion - The panel talks about... 12 | 13 | ## What is [docker](https://www.docker.com/)? 14 | * A deployment strategy 15 | * We use it in a similar way to something like [vagrant](https://www.vagrantup.com/) 16 | * It allows us to deploy our code into a pre-built environment 17 | * Reduces the 'works on my machine' problem 18 | 19 | ## How does docker differ from tools like [ansible](https://www.ansible.com/), [puppet](https://puppet.com/), [chef](https://www.chef.io/chef/)? 20 | * Configuration Management Tools allow us to describe a full virtual machine configuration 21 | * A docker file describes a container, which is 'smaller' than a virtual machine 22 | * A container only contains the environment necessary to run a single service 23 | * Tools like ansible fit into a docker workflow in configuring and managing the host environment that docker sits on 24 | 25 | ## Docker files can be considered as 'snapshots' 26 | * A docker snapshot can freeze 100% of the dependencies for an application, but we can also choose to exclude certain parts of an environment from a snapshot (e.g: we could exclude everything in `/var/www/html` from the snapshot process) 27 | * Docker makes it easy to tag and roll back changes 28 | * If a bug exists in production, we don't need to try to recreate the same conditions in a development environment: If we pull down a docker image that was deployed to the production server, it is the exact same thing that was in production 29 | 30 | ## A helpful metaphor 31 | * A docker image is like a class. A docker container is like an object. 32 | * Docker images extend other images 33 | * There are a number of official docker images (for ubuntu, PHP, ngnix, etc) 34 | * Docker images that we create will extend one of these base images 35 | * We create multiple layers of these 36 | * A container is an instance of an image: Having defined suitable images (classes) we can then instantiate many containers (objects) 37 | 38 | ## Best Practices 39 | * We should strive for 1 process per container as far as possible 40 | * This makes it easier to swap out components 41 | * Think of it like programming: this is like an object having a single responsibility 42 | * [Docker Compose](https://docs.docker.com/compose/) allows us to define an application with many docker containers, including how docker containers inside that environment communicate with each other 43 | 44 | ## Components of Docker: 45 | * [Docker Engine](https://www.docker.com/products/docker-engine) 46 | * [Docker Machine](https://docs.docker.com/machine/) 47 | * [Docker Compose](https://docs.docker.com/compose/) 48 | * [Docker Swarm](https://docs.docker.com/swarm/) 49 | 50 | ## How does Copy on Write FileSystem work? 51 | * As you build a docker file, every command creates a new 'layer' 52 | * Layers can be shared between containers 53 | * If your docker containers share common layers, they don't have to be duplicated. 54 | * For example, if you already have an ubuntu container and you add a ngnx container (which shares common ancestry with the ubuntu container), the ngnx container only needs to download the difference between the 2 (i.e: the 'layers' where ngnx was installed on top of ubuntu). 55 | * This makes it quick to deploy applications with docker because deploying a new version only requires us to download and apply the changed/different layers each time. 56 | 57 | ## How do we manage many docker containers? 58 | * This process is called 'orchestration' 59 | * There are various tools which can help us to manage this: 60 | * [Kubernetes](http://kubernetes.io/) 61 | * [Docker Swarm](https://docs.docker.com/swarm/) 62 | * [Rancher](http://rancher.com/) 63 | * [Amazon EC2 Container Service](https://aws.amazon.com/ecs/) 64 | 65 | ## What are the disadvantages associated with using docker? 66 | * Initially docker moved quickly but sometimes broke backwards compatibility 67 | * More recently, docker has become much more stable 68 | * Support for MacOS and Windows still has some problems and lags behind linux support 69 | 70 | ## Other resources 71 | * [Docker for Mac/Windows](https://www.docker.com/products/docker) 72 | * [Docker tutorial](https://github.com/docker/docker-birthday-3) 73 | * Phil's [ecs-deploy](https://github.com/silinternational/ecs-deploy) script & [article on how it works](https://blog.codeship.com/easy-blue-green-deployments-on-amazon-ec2-container-service/) 74 | * [Scaling down with Docker](https://blog.codeship.com/non-profit-case-docker/) 75 | 76 | ## Sammy Kaye wraps up with 77 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 78 | * Developer Shout-out: Eli White 79 | * Shameless Plugs: 80 | * Phil's ECS deploy script **@SammyK can you add link?** 81 | * [Docker for Developers](https://leanpub.com/dockerfordevs) 82 | -------------------------------------------------------------------------------- /episodes/049.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We spend much of our time as developers, figuring out the best way to read, mutate and persist the state of our applications. There are many different approaches and philosophies attributed to managing application state and Event Sourcing is one such approach. Today we discuss what Event Sourcing is, and how we can start integrating it into our PHP applications. 3 | 4 | # Guests 5 | * [Beau Simensen](https://twitter.com/beausimensen) 6 | * [Ross Tuck](https://twitter.com/rosstuck) 7 | * [Shawn McCool](https://twitter.com/ShawnMcCool) 8 | * [Willem-Jan Zijderveld](https://twitter.com/ZijderveldJw) 9 | 10 | # Hosted By 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion 14 | 15 | ## What is Event Sourcing? 16 | Event Sourcing is thinking of application state as a frames in a video, we could "scrub" through different states of the application. 17 | 18 | Everytime something happens that is relevant, you just record what it was, then you tie to it, any extra details that are really necessary to understand what happened. Then later you can turn those events into state, by running one after another to see how they stack up. 19 | 20 | So basically it's recording what happened, then generating state from those records. 21 | 22 | #### Real World Example 23 | Accounting, as in a bank ledger. You wouldn't just update the balance after a transaction occurred on an account, you store a record of the transaction that then the state of the account is based on the summing of the transactions. 24 | 25 | #### Good Use Cases for Event Sourcing 26 | Simple CRUD apps are probably not a good candidate for using this type of approach. Generally, you would want to use Event Sourcing when you need a record of something, when you need to know what happened and in what order, AND when there is a delay of time between events. Something with good amount of complexity, or auditability requirements, or complex decision making, so that you can go back and figure out what happened. Things like Data Mining, where you are looking to see behavior over time to influence marketing. Legal requirements. 27 | 28 | #### How to think about the data 29 | In comparison to a typical CRUD style of app, where data is stored in a database and we can think about our data, like Users in a Users table, Event Sourcing will have an id (usually UUID) and a field to indicate which order the events happened. Often people store Meta data as well. The Action is the first class citizen and the Data is the second class citizen. 30 | 31 | It's not necessarily the Action, as much as the Effect that gets recorded. So for example, Borrowing a Book, you would have a command called BorrowABook, and you would store "A book was loaned out to user X". 32 | 33 | #### How to handle an object that has millioins of "events" 34 | Snapshotting, instead of loading all millions of events, you look for the most recent snapshot, and grab all the events that happened after the snapshot. 35 | 36 | Snapshotting doesn't seem to be too necessary, it seems rare to have something that has a lot of events that would be processor heavy enough to require snapshotting, but it is a potential way of handling situations where an object may have many many events. 37 | 38 | #### How does CQRS relate to Event Sourcing? 39 | [CQRS - Command Query Responsibility Segregation](http://martinfowler.com/bliki/CQRS.html) 40 | 41 | The general idea for CQRS is to have separate models for different purposes. So far we have been discussing Event Sourcing as a way to persist your main business objects, so in the example of a Borrowed Book, you could replay the events into a Books table, that's the point where you would have a Read model and a Command model. So when you need to make a change to a books status, you would write to the Command model...and anytime you wanted to display that information, you would get that through the Read side. 42 | 43 | #### Command and CommandHandler and Events and EventHandlers 44 | This is sort of the plumbing for Event Sourcing. You generally start with a simple Command object, that then gets passed on to a Command Bus, that then figures out the CommandHandler, that then figures out which Object you actually want to change and passes the data from the Command to the actual Object. The actual Object is the one that is going to conain the data or raise the proper events. 45 | 46 | Some of this can be accomplished in other languages using AOP ([Aspect-Oriented Programming](https://en.wikipedia.org/wiki/Aspect-oriented_programming)). 47 | 48 | Another thing about Commands and Events, from a high level, is that Commands are expressing intent for something to happen. So you are asking to "Register a User". You don't necessarily know that a User is going to be Registered as a result of that command, commands can fail and do all sorts of things. Commands, CommandHandlers, Events, and EventHandlers are different but only subtley. 49 | 50 | #### Common Pitfalls 51 | People tend to try to Event Source their entire applications. Event Sourcing has a cost, and it is beneficial to limit it to the parts of your application that it is going to provide the most benefit to you. 52 | 53 | There is a lot to build in order to do Event Sourcing and CQRS, that is not talked about alot. There is a lot of "plumbing" that has to be built in order to Event Sourcing. It's really up to you to decide if your business will benefit by having the flexibility that CQRS offers. 54 | 55 | Also, people tend to conflate things into Event Sourcing. The Command Bus, Read Models, Projects, aren't actually Event Sourcing, but rather patterns that go well with Event Sourcing to the point where they are almost the de facto way to Event Source, but there tends to be a lot of confusion about that. 56 | 57 | #### What value does Event Sourcing provide? 58 | Generally, adding a new feature in a couple years time, if you have kept enough change along the way, you are often able to do that in an Event Sourced application. In a way you can future proof the application to be able to use the data that you are gathering now, which you may not necessarily know you need at this point. 59 | 60 | A fundamental consequence of sourcing your state from your events, is that you don't any data. Everything that you have Event Sourced, you have, going forward. 61 | 62 | #### Is there any particular approach to storing this data? 63 | [Event Store](https://geteventstore.com/) is a open source, functional database with complex event processing in JavaScript. Is this a preferred way to store events (or to process them) vs MySQL, Mongo, or other? 64 | 65 | Generally, you can use a lot of storage that you can think of because of the nature of an Event Store. Like you don't modify records, you just add records over and over again. Most Databases are not optimized for that, but it's also not usually a big deal. 66 | 67 | The mentioned Event Store solution provides a way to process events in to new event streams, which is probably the biggest benefit of it over a more common database store. 68 | 69 | #### Recommended Resources for PHP 70 | * [Broadway](https://github.com/qandidate-labs/broadway) (https://github.com/qandidate-labs/broadway) 71 | * [Nomad PHP - Introduction to Event Sourcing and CQRS](https://nomadphp.com/product/introduction-event-sourcing-cqrs/) 72 | * [Blog post from Qandidate-labs (group behind Broadway)](http://labs.qandidate.com/blog/2014/08/26/broadway-our-cqrs-es-framework-open-sourced/) 73 | * [CQRS.nu](http://cqrs.nu/) 74 | * [Axon Framework](http://www.axonframework.org/) 75 | 76 | ## Sammy Kaye wraps up with 77 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 78 | * Developer Shout-out: Marijn Huizendveld 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /episodes/050.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | If you're just starting with programming & PHP, this episode is for you. We discuss some helpful tips to get you started with PHP programming such as some helpful learning resources and some common pitfalls to watch out for when learning to program. 3 | 4 | # Guests 5 | * [Andy Huggins](https://twitter.com/andy_huggins) 6 | * [Nick Escobedo](https://twitter.com/nick_escobedo) 7 | 8 | Hosted by 9 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 10 | 11 | # Discussion - The panel talks about... 12 | 13 | ## Getting Started 14 | * Google is your friend, but one of the first hurdles is reaching a point where you know enough to search for solutions to your own problems. 15 | * Books, User Groups, pair programming and mentoring can help with this. 16 | * Break problems down into the smallest chunks possible - more specific questions are easier to find answers for. 17 | 18 | ## What is a user group and how do I get involved? 19 | * A bunch of nerds talking about nerd stuff. 20 | * A good way to meet other people using the same technologies. 21 | * Search for PHP groups in your area on [meetup.com](https://www.meetup.com/). 22 | 23 | ## Why should you choose PHP? 24 | * PHP is specifically designed for web development. 25 | * The barrier to entry is very low. 26 | * It has a large standard library: you get a lot 'out of the box'. 27 | * There's a lot of demand for PHP developers: PHP runs [82% of the world's websites](https://w3techs.com/technologies/details/pl-php/all/all). 28 | 29 | ## Why should you not choose PHP? 30 | * PHP is well suited to generating dynamic web content, but there are other languages better suited for other tasks. 31 | * PHP is not available everywhere. For example, you can't develop an android app with PHP. 32 | * Subjectively, many people think PHP has an ugly syntax. 33 | * The standard library is very inconsistent. For example: 34 | * http://phpsadness.com/sad/9 35 | * http://phpsadness.com/sad/4 36 | * http://phpsadness.com/sad/48 37 | 38 | ## There's a lot to learn - how do we deal with this? 39 | * Tackle one problem at a time - you don't need to learn it all at once. 40 | * To be a programmer, you have to enjoy the process of finding solutions to problems. 41 | * There are good habits and bad habits - focus on good habits and be prepared to re-evaluate bad ones. 42 | * Don't be afraid to ask for help. 43 | 44 | ## My code isn't working - how do I find out what the problem is? 45 | * Turn on [error reporting](http://php.net/manual/en/function.error-reporting.php) in dev. 46 | * [var_dump](http://php.net/manual/en/function.var-dump.php) 47 | * Look at [step dubugging](https://www.phproundtable.com/episode/debugging-is-more-than-var-dump) (tangent - [CppCast Episode 30](http://cppcast.com/2015/10/kate-gregory/)) 48 | 49 | ## Resources and finding help 50 | * [Laracasts: PHP For Beginners](https://laracasts.com/series/php-for-beginners) 51 | * [Stackoverflow](http://stackoverflow.com/) 52 | * Bloggers 53 | * [Scotch](https://scotch.io/) 54 | * [PHP Women](https://phpwomen.org/) is very beginner friendly 55 | * When asking for help, provide as much detail as possible and outline what you've already done to try and solve the problem. 56 | * [NomadPHP](https://nomadphp.com/) - online user groups. 57 | * Conferences. e.g: 58 | * [php[tek]](https://tek.phparch.com/) 59 | * [php[world]](https://world.phparch.com/) 60 | * [Sunshine PHP](http://sunshinephp.com/) 61 | * [PNPPHP](http://www.pnwphp.com/) 62 | * [PHP The Right Way](http://www.phptherightway.com/) 63 | 64 | ## Sammy Kaye wraps up with 65 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 66 | * Developer Shout-out: Josh Lockhart 67 | * Shameless Plugs: 68 | * https://github.com/ahuggins/utilities 69 | * http://www.meetup.com/Chicago-PHP-User-Group/ 70 | -------------------------------------------------------------------------------- /episodes/051.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Despite the fact that there was never an official release of PHP 6, it was going to be a real thing with a lot of great improvements to the engine and language. But why was this version of PHP never released? We talk with some previous and current internals developers to hear the story of what happened to PHP 6. 3 | 4 | # Guests 5 | * [Sara Golemon](https://twitter.com/SaraMG) 6 | * [Derick Rethans](https://twitter.com/derickr) 7 | * [Sean Coates](https://twitter.com/coates) 8 | * [Andrei Zmievski](https://twitter.com/a) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## What was the plan for PHP 6? 16 | * PHP 6 was supposed to add native unicode support to PHP. 17 | * This represented a big change and many features were blocked from being added to the PHP 5.x codebase because unicode support had to be added first. 18 | * Significant progress was made towards implementing unicode support, but the process dragged on for a long time: 19 | * [PHP 6 Unicode conversion was at 4.5% in 2006](http://web.archive.org/web/20060614101310/http://www.php.net/~scoates/unicode/render_func_data.php). 20 | * [PHP 6 Unicode conversion was at ~70% in 2011](http://web.archive.org/web/20110819115549/http://www.php.net/~scoates/unicode/render_func_data.php). 21 | * Eventually many of the new features intended for PHP 6 were backported to the PHP 5.x branch. 22 | * PHP 6 had a wider focus than just character encoding (There is an episode of PHP roundtable on the subject of [Character Encoding and UTF-8](https://www.phproundtable.com/episode/character-encoding-and-utf-8-in-php)) - it was also about changing the approach to [i18n and l10n](https://en.wikipedia.org/wiki/Internationalization_and_localization). 23 | 24 | ## What is the legacy of PHP 6's collapse? 25 | * Strings literals in PHP are still fundamentally composed of bytes. 26 | * It is up to developers to deal with character encoding issues using [mbstring](http://php.net/manual/en/book.mbstring.php), [iconv](http://php.net/manual/en/book.iconv.php), [uconverter](http://php.net/manual/en/class.uconverter.php), etc. 27 | * The [intl extension](http://php.net/manual/en/book.intl.php) wraps a lot of the functionality that was originally going to be a part of PHP 6 for use in PHP 5.x/7.x. 28 | * In PHP 5, working with UTF-8 could be painful. Sometimes we would have to specify UTF-8 characters using hex notation. 29 | * PHP 7 helps by adding the inline UTF-8 literal syntax `\u{[0-9A-Fa-f]+}` and [IntlChar class](http://php.net/manual/en/class.intlchar.php). 30 | 31 | ## What went wrong? 32 | * The decision to use UTF-16 internally was made early on in the process (2005). 33 | * At the start of work on PHP 6, UTF-8 was not widely supported but during development, the industry started to standardise on this. Widespread adoption of this more forgiving encoding helped with a lot of the problems that PHP 6 was trying to solve and made the objectives less relevant. 34 | * The number of contributors who fully understood the problem was relatively small and the amount of tedious conversion work was large. 35 | * In open source, people work on what they are interested in and not enough people were interested in it. 36 | * Full unicode support using UTF-16 negatively impacted performance. 37 | * By 2009/2010, it had started to become apparent that PHP 6 was never going to happen. 38 | 39 | ## What can we learn from PHP 6? 40 | * PHP 6 was not a failure: it spawned the [intl extension](http://php.net/manual/en/book.intl.php) and other features that are now part of the language in 5.x or 7. 41 | 42 | ## Other links 43 | * [Andrei's slides from 'The Good, the Bad, and the Ugly: What Happened to Unicode and PHP 6'](http://www.slideshare.net/andreizm/the-good-the-bad-and-the-ugly-what-happened-to-unicode-and-php-6). 44 | * [Because, PHP](https://www.facebook.com/Because-PHP-147594855443853/) 45 | 46 | ## Sammy Kaye wraps up with 47 | * Upcoming conferences: 48 | * [PNPPHP](http://www.pnwphp.com/) 49 | * [ZendCon](http://www.zendcon.com/) 50 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 51 | * Developer Shout-out: Simon Welsh 52 | * Shameless Plugs: 53 | * [dram.io](https://dram.io/) 54 | * [Mongo DB Europe](https://www.mongodb.com/europe16) 55 | * [seancoates.com](http://seancoates.com/) 56 | * [xhp](https://github.com/phplang/xhp) 57 | -------------------------------------------------------------------------------- /episodes/053.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | So you spend most of your time programming in PHP. You meet another programmer out in the wild. You begin explaining what you do. Do you find yourself using vague terms and actively trying to avoid the word "PHP?" Do you dread the question, "What language do you primarily code in?" Do you anticipate them scoffing at you when you say, "PHP?" 3 | 4 | We discuss why PHP has such a bad rep in the eyes of many and why some of us feel the need to start conversations with, "I use PHP but let me explain..." 5 | 6 | # Guests 7 | * [Evert Pot](https://twitter.com/evertp) 8 | * [Davey Shafik](https://twitter.com/dshafik) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## Are negative opinions about PHP always valid? 16 | * A lot of negative stereotypes of PHP are base on negative traits of the language that are no longer a problem: PHP has matured a lot over the last few years 17 | * [PHP: a fractal of bad design](https://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/) is a blog post written in 2012 which details many of these issues. 18 | * In the article, the author notes that some of these problems have been fixed in PHP 5.x releases 19 | * Some of these issues have also been fixed or improved in PHP 7 20 | * Many of the problems noted in this article remain in the language 21 | * PHP now has a [language specification](https://github.com/php/php-langspec) 22 | 23 | ## Where does this reputation come from? 24 | 25 | ### Poor quality userland code 26 | * PHP contains a lot of constructs which are often poorly understood and misused by developers 27 | * PHP is widely used and has a low barrier to entry - it is often the first language people pick up 28 | * This means that there is a lot of poor quality PHP code out there 29 | * Perhaps if another language was the most widely used language on the web, that language would have the same reputation 30 | * Many PHP tutorials and answers to PHP questions on stackoverflow are of poor quality 31 | * Many negative perceptions of PHP are influenced more by this than inherent flaws in the language 32 | 33 | ### Failings of the language itself 34 | * Sammy mentions a [Quora topic](https://www.quora.com/Why-doesnt-JavaScript-have-the-bad-reputation-over-PHP) where PHP is described as "an unstructured conglomerate of half-understood and badly implemented features" 35 | * Almost everything on [PHP Sadness](http://phpsadness.com/) is valid criticism 36 | * Every language has problems, but in PHP we are very aware of them 37 | * The communities around some other languages are less self-aware in this sense 38 | * Being aware of our failings helps the community to improve 39 | 40 | 41 | ## How is the PHP community fixing these problems? 42 | * PHP is rapidly evolving and adding more sophisticated features e.g: 43 | * [Type hinting](http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) 44 | * [Generators](http://php.net/manual/en/language.generators.overview.php) 45 | * [Anonymous Classes](http://php.net/manual/en/language.oop5.anonymous.php) 46 | * PHP 7 allowed the introduction of important backwards-incompatible changes e.g: 47 | * [Uniform variable syntax](https://wiki.php.net/rfc/uniform_variable_syntax) 48 | * PHP 8 will also feature more deprecations and compatibility breaking changes which help to drop some of PHP's baggage 49 | 50 | ## Will this change perceptions? 51 | * In isolation, these structural/technical improvements won't change external perceptions 52 | * As they help to improve 'userland' PHP code, this will change perceptions 53 | 54 | ## Is PHP's community insular? 55 | * [Jon Kuperman's blog post 'The Life of a PHP Developer'](https://jonkuperman.com/life-of-a-php-developer/) 56 | * All languages have their own communities, events and culture 57 | * PHP developers may be less well represented at language-agnostic events 58 | * If anything, PHP developers are often more pragmatic and willing to accept other solutions than developers in other languages 59 | 60 | ## Do other languages/communities have to deal with negative stigma? 61 | * Perl, NodeJS, Ruby all have their detractors ..but everyone loves Python, right? :) 62 | * All languages have problems, but we shouldn't try to justify our preferences by criticising the choices of others 63 | 64 | ## How can we change the perception of PHP? 65 | * Improvements the language help to make it more predictable, consistent and concise: 66 | * [Late Static Binding](http://php.net/manual/en/language.oop5.late-static-bindings.php) 67 | * [Uniform variable syntax](https://wiki.php.net/rfc/uniform_variable_syntax) 68 | * [Closures](http://php.net/manual/en/class.closure.php) 69 | * [Callables](http://php.net/manual/en/language.types.callable.php) 70 | * [Traits](http://php.net/manual/en/language.oop5.traits.php) 71 | * [Generators](http://php.net/manual/en/language.generators.overview.php) 72 | * As a community we need to be more vocal about these improvements 73 | * Using these must become the norm in code examples, tutorials, stack overflow answers, etc to really change opinions 74 | 75 | 76 | ## Discussion about Evert's blog post [PHP Sucks](https://evertpot.com/PHP-Sucks/) 77 | * These attitudes genuinely do negatively impact people 78 | * Evert feels that negative perceptions of PHP impact his ability to succeed both as a developer and more widely as an entrepreneur 79 | * As a polyglot developer, it is possible to gain an outsider's perspective 80 | 81 | 82 | ## Sammy Kaye wraps up with 83 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 84 | * Get a [25% discount on php[architect]](http://phpa.me/phproundtable) 85 | * Upcoming conferences: 86 | * [PNPPHP](http://www.pnwphp.com/) 87 | * [ZendCon](http://www.zendcon.com/) 88 | * Developer Shout-out: Chris Cornutt 89 | * Shameless plugs: 90 | * [Polyglot Contrib](http://polyglotcontrib.com/) 91 | * [sabre/xml](http://sabre.io/xml/) 92 | -------------------------------------------------------------------------------- /episodes/054.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We chat about security in the the PHP community, encryption & hashing in PHP and a new-hotness crypto library called [libsodium](https://download.libsodium.org/doc/). 3 | 4 | # Guests 5 | * [Scott Arciszewski](https://twitter.com/CiPHPerCoder) 6 | * [Chris Riley](https://twitter.com/giveupalready) 7 | * [Chris Cornutt](https://twitter.com/enygma) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## PSR-9 and PSR-10 15 | * [PSR-9](https://github.com/php-fig/fig-standards/blob/master/proposed/security-disclosure-publication.md) deals with the process by which security issues are submitted or reported to project maintainers. 16 | * [PSR-10](https://github.com/php-fig/fig-standards/blob/master/proposed/security-reporting-process.md) describes a machine-readable format for disclosing security issues to users. 17 | * [Roave/SecurityAdvisories](https://github.com/Roave/SecurityAdvisories) Prevents the installation of packages with known security vulnerabilities. 18 | * [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories) provides tools for identifying dependencies with known security issues. 19 | 20 | ## Encryption 21 | * Encryption when you need decryption. Hash when you don't (e.g: passwords) 22 | * Encryption provides confidentiality, [AEAD](https://en.wikipedia.org/wiki/Authenticated_encryption) aims to go further. 23 | * Message authentication/integrity checksum is usually a hashing problem, rather than encryption. 24 | * Scott discusses some encryption pitfalls and how a simple operation like `==` can become very complex to implement securely without becoming vulnerable to side-channel attacks. Encryption is **hard** - don't roll your own. Leave it to the specialists. 25 | * [RFC: OpenSSL AEAD support](https://wiki.php.net/rfc/openssl_aead) 26 | * Always hash passwords with a slow hash function like bcrypt, scrypt or argon2 in [libsodium](https://download.libsodium.org/doc/). Fast hash functions like sha-2 are more vulnerable to brute-force attacks. 27 | * [hash_pbkdf2()](http://php.net/manual/en/function.hash-pbkdf2.php) can be used to slow down your hash process to guard against brute-force by creating a bottleneck for an attacker. Don't DDOS your own server though: Use rate-limiting to avoid creating a DDOS vector. 28 | 29 | ## How do we upgrade the password hashing in legacy apps (e.g: md5)? 30 | * Don't do a mass mailing and require a password reset from everyone: This implies a breach has taken place. 31 | * Phased update - upgrade your userbase gradually: 32 | * Re-hash passwords using a new algorithm in the background each time a user logs in. Mark the user as re-hashed each time. 33 | * As users log in, force a password reset. 34 | * bcrypt all the md5 hashes and make your hashing algorithm `bcrypt(md5($password))` 35 | 36 | ## Password Managers 37 | * Make it easy for users to use password managers on your site 38 | * Don't disable copy & paste on password fields 39 | * Name password fields obviously 40 | 41 | ## libsodium 42 | * [libsodium](https://download.libsodium.org/doc/) is a C library implementing best-in-class cryptographic and hashing algorithms 43 | * Safe from side-channel and cache-timing attacks 44 | * There are plans to move to libsodium implementations of built-in crypto function in PHP >= 7.2 45 | * [mcrypt](http://php.net/manual/en/book.mcrypt.php) is deprecated in PHP 7.1 46 | 47 | ## Sammy Kaye wraps up with 48 | * Discount code for [PHP Architect](https://phpa.me/phproundtable) 49 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 50 | * Developer Shout-out: Brian Retterer 51 | * Shameless Plugs: 52 | * [PHP Yorkshire](https://twitter.com/phpyorkshire) 53 | * [PHP Scotland](http://conference.scotlandphp.co.uk/) 54 | * [Paragon IE Newsletters](https://paragonie.com/contact) 55 | * [websec.io](https://websec.io/) 56 | -------------------------------------------------------------------------------- /episodes/055.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We chat about the open-source Behavior-Driven Development framework called [Behat](http://behat.org/). We get a brief overview of how Behat can help us write more reliable code and also explore some best-practices when writing automated tests. 3 | 4 | # Guests 5 | * [Jessica Mauerhan](https://twitter.com/JessicaMauerhan) 6 | * [Konstantin Kudryashov](https://twitter.com/everzet) 7 | 8 | Hosted by 9 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 10 | 11 | # Discussion - The panel talks about... 12 | 13 | ## What does Behat do? 14 | * Behat is a [BDD](https://en.wikipedia.org/wiki/Behavior-driven_development) tool 15 | * Behat is even more BDD-specific than [RSpec](http://rspec.info/) or [phpspec](http://www.phpspec.net/en/stable/) 16 | * Behat separates semantics of problem description from automated tests 17 | * Behat can be seen more as a tool for documentation and specification than testing in the sense of removing bugs 18 | 19 | ## How do we decide what to test with Behat? 20 | * The [testing pyramid](http://martinfowler.com/bliki/images/testPyramid/test-pyramid.png) 21 | * We should have the lowest number of the tests which are the slowest to run 22 | * We can mock out external services in acceptance tests in the same way we use mocks and stubs in unit testing 23 | * If your test suite takes longer than 10 minutes, you have big problems 24 | * Favour lower-levels tests where possible 25 | 26 | ## How can Behat help us to modernize legacy applications? 27 | * Write end-to-end tests with Behat to define expected behaviour 28 | * Refactor underlying code into more defined 'layers' using acceptance tests to ensure we have not broken anything 29 | * As we refactor, replace slower acceptance tests with faster lower-level (unit/integration) tests 30 | * Only keep the most important acceptance tests 31 | 32 | ## How do we isolate layers (esp. the UI layer) so we don't need end-to-end tests? 33 | * If our UI talks to the back end via REST, point it at a fake back-end 34 | * Use BDD or unit testing tools for javascript 35 | * Write feature files in a UI-agnostic way 36 | * If your tests are entangled, your application will be entangled 37 | * The same descriptions can be used with Behat and [Cucumber JS](https://github.com/cucumber/cucumber-js). This allows your UI and back-end to be tested against the same specification 38 | 39 | ## How do we write good user stories? 40 | * User stories should be the result of a **conversation** between developers and users 41 | * Keep the discussion high-level 42 | * Focus on understanding the problem, not the implementation details 43 | 44 | ## How do we get started with Behat in a project that already has Unit Tests? 45 | * Behat expects to find a top-level dir called `/features` for specifications 46 | * `/features` does not contain tests - think of `/features` as documentation as well as specification 47 | * Within `/tests`, divide tests into `/unit`, `/integration`, `/acceptance` and namespace them 48 | * The content of `/features` should be human-readable, describe features to be used by humans and be implementation-agnostic 49 | 50 | ## How do we acceptance test a user interaction with many variations? 51 | * We don't need to explicitly test every scenario end-to-end 52 | * Create scenario outlines with multiple examples 53 | * Identify the most critical paths and focus testing on those 54 | 55 | ## Sammy Kaye wraps up with 56 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 57 | * Developer Shout-out: Wouter J 58 | * Shameless Plugs: 59 | * [Jessica's Blog](https://jmauerhan.wordpress.com/) 60 | * [Contribute to Behat](https://github.com/behat/behat) 61 | * [Stakeholder Whisperer](http://stakeholderwhisperer.com/) 62 | * [BDD Exchange](https://skillsmatter.com/conferences/7428-agile-testing-and-bdd-exchange-2016#program) 63 | -------------------------------------------------------------------------------- /episodes/056.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | There are two seemingly contradicting philosophies about how to charge clients for programming work. The hourly camp suggests that the client is paying for your skill and hiring you for your time. The value-based pricing camp suggests that the programmer should price a project based on its value to the client instead of the hours it will take to build it. Today we chat about these two ideas and discuss the pros and cons of both. 3 | 4 | # Guests 5 | * [Keith Casey Jr](https://twitter.com/CaseySoftware) 6 | * [Tim Lytle](https://twitter.com/tjlytle) 7 | * [Mike McDerment](https://twitter.com/MikeMcDerment) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## Time-based pricing 15 | * Resolution could be hourly or daily 16 | * Allows flexibility: bill your client for the hours you work 17 | * Requires you to keep track of your time 18 | * Was that 10 hours of actual development, or 10 hours of replying to emails? 19 | * As you get better and you can do things faster, you actually earn less 20 | * Safe model if value of work is speculative/experimental 21 | 22 | ## Value-based pricing 23 | * Value of your work is determined by your client, not you 24 | * Charge your client a percentage of the expected value of what you produce 25 | * Fixing a major security hole in the right client's product make be worth a huge amount to them, even if it only takes you an hour to fix 26 | * Billing by the hour pits you against your client: 27 | * You want to bill for as many hours as possible 28 | * Your client wants you to charge them for as few hours as possible 29 | * Value-based pricing puts you both on the same side 30 | * Using value-based pricing, your client should see the money they spend with you as an investment, not a cost 31 | * Many SaaS products use value-based pricing e.g: [GitHub](https://github.com/pricing). Different users receive different levels of value from the same or similar product and pay different prices accordingly 32 | 33 | ## How can we transition hourly clients to a value-based model? 34 | * As speculative/experimental clients become more stable, now is a good time to change 35 | * Start changing your model with new clients 36 | * Use a new project as an opportunity to try something different - don't try to change mid-project 37 | 38 | ## How can we apply value-based pricing to refactoring legacy code? 39 | * It depends on the legacy system: 40 | * If the legacy app is important/frequently used or where defects have high potential cost, it is an easy sell 41 | * If the legacy app is not so important/less frequently used, its a more difficult proposition 42 | * Compare refactoring legacy code to: 43 | * The cost/risk of writing a new system 44 | * The cost/pain of maintaining a brittle legacy product 45 | 46 | ## Sammy Kaye wraps up with 47 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 48 | * Developer Shout-out: Patrick McKenzie 49 | * Shameless Plugs: 50 | * [FreshBooks](https://www.freshbooks.com/) 51 | * [theapidesignbook.com](http://theapidesignbook.com/) 52 | * [php|world](https://world.phparch.com/) 53 | * [@nexmo](https://twitter.com/Nexmo) 54 | -------------------------------------------------------------------------------- /episodes/057.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | There's a lot more going on at [Zend](http://www.zend.com/) other than [Zend Framework](https://framework.zend.com/). We chat about the Zend ecosystem, from [Apigility](https://apigility.org/) to [Zend Certification](http://www.zend.com/en/services/certification) and what Zend's role is in PHP internals. 3 | 4 | # Guests 5 | * [Adam Culp](https://twitter.com/adamculp) 6 | * [Cal Evans](https://twitter.com/CalEvans) 7 | * [Gary Hockin](https://twitter.com/GeeH) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## The company behind Zend 15 | * Zend Engine is a pre-compiler for PHP and is used internally in PHP's interpreter 16 | * The Zend company and other products grew out of this 17 | * Zend is [now owned by Rogue Wave](http://www.zend.com/en/resources/news-and-events/newsroom/press/3683_rogue-wave-software-acquires-enterprise-php-leader-zend-acquisition-broadens-enterprise-strength-across-top-five-development-languages) 18 | 19 | ## What is Zend's role in PHP Internals? 20 | * [Rogue Wave](http://www.roguewave.com/) employs a number of PHP core contributors 21 | * [Dmitry Stogov](https://twitter.com/dstogov) developed much of the basis for the PHP 7 Engine (codenamed [phpng](https://en.wikipedia.org/wiki/PHP#NG) at the time) while at Zend 22 | * Dmitry and others at Rogue Wave are working on JIT-compilation for PHP 23 | 24 | ## The Zend Framework 25 | * Component-based framework 26 | * Focusses on configuration over 'magic' 27 | * Promotes best-practices and maintainability over rapid development 28 | * Used by a lot of large organisations 29 | * Backed by a stable company 30 | 31 | ## What's new in version 3? 32 | * The framework is now decoupled across 61 'component' repositories instead of all the components living in a single repository - this promotes component re-use 33 | * Contains multiple [backwards-incompatible changes](https://github.com/zendframework/zendframework/wiki/ZF-3.0-Backwards-Compatibility-Breaks), but upgrading from 2.x is not too much of a headache and [well documented](https://docs.zendframework.com/zend-mvc/migration/to-v3-0/) 34 | * Improved performance 35 | * Improved developer experience 36 | * Improved [documentation](https://docs.zendframework.com/) 37 | 38 | ## Apigility 39 | * A quick way to create database-connected APIs 40 | * Handles a lot of the overhead/boilerplate associated with creating APIs: 41 | * error handling 42 | * content negotiation 43 | * versioning 44 | * etc 45 | 46 | ## PHP and Zend Framework Certification 47 | * Proves you understand PHP and current best-practices 48 | * Focussed on core PHP concepts, rather than language features of a particular version of PHP 49 | 50 | ## Sammy Kaye wraps up with 51 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 52 | * No developer shout out this time. If you are interested in sponsoring the developer shout-out in future, [contact Sammy](https://twitter.com/SammyK) 53 | * Shameless plugs: 54 | * [Spin a Good Yarn](https://spin-a-good-yarn.com/) 55 | * [Sunshine PHP](http://2017.sunshinephp.com/) 56 | * [Run Geek radio](https://rungeekradio.com/) 57 | * [PHPStorm](https://www.jetbrains.com/phpstorm/) 58 | * [Jerks Talk Games](https://jerkstalkgames.com/) 59 | -------------------------------------------------------------------------------- /episodes/058.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | [Guzzle](http://docs.guzzlephp.org/) has become the de-facto HTTP-client library for PHP. But recently a number of open source projects have been switching to [HTTPlug](http://httplug.io/) which boasts itself as an HTTP-client abstraction. We chat about the problems HTTPlug aims to solve, the plans for its future and the reasons behind why some library maintainers have chosen to adopt it or not. 3 | 4 | # Guests 5 | * [Tobias Nyholm](https://twitter.com/TobiasNyholm) 6 | * [Woody Gilk](https://twitter.com/shadowhand) 7 | * [Steven Maguire](https://twitter.com/StevenMaguire) 8 | * [Brian Retterer](https://twitter.com/bretterer) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## Tobias, how did you get involved in Guzzle? 16 | * Michael [tweeted](https://twitter.com/mtdowling/status/771191447324196867) a call for an additional maintainer. 17 | * Tobias answered the call. 18 | * [Márk Sági-Kazár](https://github.com/sagikazarmark) is also a superstar maintainer on the project. 19 | * Guzzle has released several major releases in a fairly short space of time, which has lead to some conflicts. The Guzzle community will be more careful about a version 7 release. 20 | 21 | ## What does HTTPlug offer that Guzzle doesn't? 22 | * HTTPlug is an abstraction over HTTP clients and provides a consistent [PSR-7](http://www.php-fig.org/psr/psr-7/) compliant wrapper over multiple HTTP clients. 23 | * It grew out of [Ivory HTTP Adapter](https://github.com/egeloen/ivory-http-adapter). 24 | * Using HTTPlug means your code depends on an HTTP abstraction rather than an HTTP implementation. 25 | 26 | ## How do I migrate to HTTPlug? 27 | * It depends on how coupled you are to an existing implementation. 28 | * You need 3 libraries/packages to implement HTTPlug: 29 | * A HTTP message (PSR-7 implementation) 30 | * A way to create the message (message factory) 31 | * A way to send the message (HTTP client) 32 | * Users of libraries that use HTTPlug may choose their own packages/implementations or library maintainers may specify default implementations. 33 | * HTTPlug is for library authors. Application developers are consumers of HTTPlug. 34 | 35 | ## Brian talks about [Stormpath PHP SDK](https://github.com/stormpath/stormpath-sdk-php)'s migration to HTTPlug 36 | * Stormpath SDK was using Guzzle 3 which is now abandoned. 37 | * Lack of other dependencies/integrations allowed Stormpath to avoid upgrading. 38 | * Once they started adding more integrations, this lead to problems with conflicting version requirements. 39 | * There was some debate over whether to migrate to a newer version of Guzzle or use something else. 40 | * HTTPlug represented a more versatile solution. 41 | * Tobias and [Magnus Nordlander](https://github.com/magnusnordlander) helped them to migrate. 42 | * Stormpath provide default implementations for HTTPlug to wrap, but users may change them. 43 | 44 | ## Woody, what are the reasons for [thephpleague/oauth2-client](https://github.com/thephpleague/oauth2-client) sticking with Guzzle? 45 | * [thephpleague/oauth2-client](https://github.com/thephpleague/oauth2-client) recently [decided against](https://github.com/thephpleague/oauth2-client/pull/538) migrating to HTTPlug. 46 | * Guzzle is the de-facto standard. 47 | * Guzzle 6 is PSR-7 now compliant. 48 | * With wider adoption of PSR-7, there is less need for an abstraction library like HTTPlug. PSR-7 provides that abstraction. 49 | * HTTPlug can add complexity for your users if you force them to pick their own implementations. 50 | 51 | ## Is this a transient problem, is there a long-term need for an abstraction like HTTPlug? 52 | * Building HTTPlug was something that could be done quickly. PSRs move slowly. 53 | * There are several upcoming PSR standards ([PSR-15](https://github.com/php-fig/fig-standards/blob/master/proposed/http-middleware/middleware.md), [PSR-17](https://github.com/php-fig/fig-standards/blob/master/proposed/http-factory/http-factory.md)) which should help to resolve these issues. 54 | * In principle, these upcoming PSRs should solve problems, but during the transitional phase of libraries adopting these standards, we may still need adapters. 55 | 56 | ## Sammy Kaye wraps up with 57 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 58 | * Shameless Plugs: 59 | * Sammy and Woody will both be speaking at [Midwest PHP](https://2017.midwestphp.org/) 60 | * [Subtree Split as a Service](https://www.subtreesplit.com/) 61 | * [DonorsChoose.org](https://www.donorschoose.org/) 62 | * [Stormpath](https://stormpath.com/) 63 | * Go to your local meetup or user group 64 | -------------------------------------------------------------------------------- /episodes/059.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | PHP 7.1, the latest minor version of PHP, was [released on December 1st](http://php.net/archive/2016.php#id2016-12-01-3). We discuss some things that went on behind-the-scenes that brought this new version to a stable release and we look at some new features that we can start taking advantage of today. 3 | 4 | # Guests 5 | * [Davey Shafik](https://twitter.com/dshafik) 6 | * Sean DuBois 7 | * [Levi Morrison](https://twitter.com/morrisonlevi) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## PHP has been seeing more regular releases recently - what changed? 15 | * PHP adheres to semantic versioning more closely now. In the past this was not the case 16 | * A lot of time was spent on [PHP 6](https://www.phproundtable.com/episode/what-happened-to-php-6) which never happened 17 | * PHP has settled into a more mature yearly release cadence and [support policy](http://php.net/supported-versions.php) 18 | 19 | ## Davey talks about his role as release manager for 7.1? 20 | * Answered a call on PHP Internals list 21 | * Davey and [Joe Watkins](https://github.com/krakjoe) were approved as co-release managers 22 | * Received a lot of help from others e.g: Stephen from Microsoft (Windows binaries) and Remi from Redhat (testing on RHEL, Fedora, CentOS) 23 | * Primarily about housekeeping: 24 | * Publishing and signing tarballs 25 | * Ensuring there are no unintended BC-breaks 26 | * Ensuring nothing is added that isn't approved 27 | 28 | ## New features in PHP 7.1 29 | * [Nullable Types](http://php.net/manual/en/migration71.new-features.php#migration71.new-features.nullable-types) 30 | * [Iterable Pseudo-Type](http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type) 31 | * [Class Constant Visibility](http://php.net/manual/en/migration71.new-features.php#migration71.new-features.class-constant-visibility) 32 | * [Void Return Types](http://php.net/manual/en/migration71.new-features.php#migration71.new-features.void-functions) 33 | * [Multi-Catch Exception Handling](http://php.net/manual/en/migration71.new-features.php#migration71.new-features.mulit-catch-exception-handling) 34 | * Mcrypt has been deprecated and will be removed in PHP 8 35 | * Fix [inconsistent behavior](https://wiki.php.net/rfc/this_var) of `$this` variable 36 | 37 | ## Features that didn't make 7.1 or may appear in future releases 38 | * [Union Types](https://wiki.php.net/rfc/union_types) (did not pass) 39 | * [Intersection Types](https://wiki.php.net/rfc/intersection_types) (may appear in a future release) 40 | * [Merge Symbol Tables](https://wiki.php.net/rfc/php8/merge_symbol_tables) (proposed for PHP 8 but requires huge BC-breaks) 41 | 42 | ## Sammy Kaye wraps up with 43 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 44 | * Shameless Plugs: 45 | * [Akamai for WordPress](https://github.com/akamai-open/wp-akamai) 46 | * PHP 7.2 - [Call for release managers](http://www.mail-archive.com/internals@lists.php.net/msg90860.html) 47 | * [Arrow Functions RFC](https://wiki.php.net/rfc/arrow_functions) 48 | * [Therac](https://github.com/Sean-Der/Therac) 49 | -------------------------------------------------------------------------------- /episodes/060.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | No matter how experienced you are as a programmer, at some point your app will generate errors and crash. Fixing problems with your app quickly is paramount in order to affect as little of your user base as possible. We discuss what is involved with implementing effective logging and crash reporting techniques in PHP to help you keep your apps up and running like a well-oiled machine. 4 | 5 | # Guests 6 | * [John-Daniel Trask](https://twitter.com/traskjd) 7 | * [Daniel Berman](https://twitter.com/proudboffin) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | # Discussion - The panel talks about... 13 | 14 | ## What are logs and why do we care about logging? 15 | * Logs are streams of time-ordered events collected from a running process 16 | * Logging can generate huge amounts of output 17 | * Logs allow us to reason about our systems by telling us: 18 | * What is happening 19 | * When it is happening 20 | * Why it is happening 21 | * We can use tools to help us to 22 | * Isolate relevant events based on queries 23 | * Notify us about important events (e.g: by email, slack, etc) 24 | 25 | ## What should we log? 26 | * In general, log more rather than less 27 | * There are some things we should not log: 28 | * Passwords 29 | * Personal data 30 | * Software with filtering can help with this 31 | * Logging too much can impact performance 32 | 33 | The de-facto standard for logging in PHP is [PSR-3](http://www.php-fig.org/psr/psr-3/) and the most common logging library is [monolog](https://github.com/Seldaek/monolog) 34 | 35 | ## PSR-3 Defines a lot of log levels. How many should we use? 36 | * `DEBUG`, `INFO`, `WARNING` and `ERROR` is probably enough for most apps 37 | * The levels we use are based on the [syslog RFC](https://www.ietf.org/rfc/rfc3164.txt) 38 | * It depends on the scale of your application 39 | 40 | ## How can we visualise logs? 41 | * `tail -f` 42 | * The ELK Stack is popular, fast and (relatively) easy to set up 43 | * [Elasticsearch](https://www.elastic.co/products/elasticsearch) indexes logs and makes them searchable 44 | * [Logstash](https://www.elastic.co/products/logstash) collates the data from different log sources 45 | * [Kibana](https://www.elastic.co/products/kibana) is the visualisation layer for analysing the data 46 | 47 | ## Where should we write logs? 48 | * Flat files and `logrotate` 49 | * A buffering system like [Redis](https://redis.io/) or [Kafka](https://kafka.apache.org/) 50 | * Send logs to an aggregation service 51 | 52 | ## Sammy Kaye wraps up with 53 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 54 | * Sammy is giving 2 talks at [PHP|tek](https://tek.phparch.com/) 55 | * Developer Shout-Out: Zeev Suraski 56 | * Shameless Plugs: 57 | * [logz.io](https://logz.io/) 58 | * [raygun.com](https://raygun.com/) 59 | -------------------------------------------------------------------------------- /episodes/061.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) has been a design principle that the PHP community has embraced more fully than a lot of other programming communities. There's even an official PHP-FIG standard being discussed called [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md) which will standardize dependency injection containers. Today we chat all things dependency injection. 3 | 4 | # Guests 5 | * [Stephan Hochdörfer](https://twitter.com/shochdoerfer) 6 | * [David Stockton](https://twitter.com/dstockto) 7 | * [David Négrier](https://twitter.com/david_negrier) 8 | * [Matthias Noback](https://twitter.com/matthiasnoback) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Discussion - The panel talks about... 14 | 15 | ## What does dependency injection give us? 16 | * Flexibility 17 | * Avoids tight coupling 18 | * Allows component re-use 19 | * Provides separation of concerns 20 | * Makes objects more testable 21 | * Provides inversion of control 22 | 23 | ## How do we implement dependency injection? 24 | * Pass in objects we need as parameters 25 | * Avoid the `new` keyword inside our object code 26 | * Push object instantiation outside of our objects (this is where DI containers can help us) 27 | 28 | ## When should we use dependency injection? 29 | * Services or Repositories which we want to exchange within our code base 30 | * Anywhere we want to be able to use more than one implementation 31 | * Anywhere we want to be able to swap out an object under testing 32 | * Sometimes we can directly instantiate objects, for example domain objects and helper classes 33 | 34 | ## What role do [interfaces](http://php.net/manual/en/language.oop5.interfaces.php) play in dependency injection? 35 | * Interfaces help us to decouple dependencies from their implementation 36 | * We should be able to exchange a dependency with another that conforms to the same interface 37 | * There are some things an interface doesn't capture (e.g: the exceptions that can be thrown by a method) 38 | 39 | ## Which tools can we use to help with dependency injection? 40 | PHP dependency injection containers fall into one of 3 categories: 41 | * Pure PHP: 42 | * [Pimple](https://pimple.sensiolabs.org/) 43 | * [Disco](https://github.com/bitExpert/disco) 44 | * Configuration file-based: 45 | * [Symfony DependencyInjection Component](http://symfony.com/doc/current/components/dependency_injection.html) can optionally work in this way 46 | * Reflection-based/"autowiring": 47 | * [Laravel IoC](https://laravel.com/docs/4.2/ioc) 48 | 49 | ## PSR-11 50 | * [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md) addresses one problem: How do we fetch an object from a container? 51 | * 2 methods: `get()` and `has()` 52 | * Many components (e.g: frameworks or routers) are currently tightly coupled to a particular container implementation 53 | * Standardising container implementation will help to make components more generic 54 | 55 | ## How did dependency injection become so popular in PHP? 56 | * As unit testing has become more important, so has DI. The two compliment each other 57 | * The first versions of frameworks like Zend and Symfony were monolithic. In version 2 these frameworks started to split into smaller components. Using dependency injection helped them to decouple. 58 | * Early implementations borrowed/ported the concept from [Spring](https://spring.io/) in Java 59 | 60 | ## Sammy Kaye wraps up with 61 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes) 62 | * Developer Shout-Out: Matthieu Napoli 63 | * Shameless Plugs: 64 | * [Disco](https://github.com/bitExpert/disco) 65 | * [training.matthiasnoback.nl](https://training.matthiasnoback.nl/) 66 | * [Mouf](http://mouf-php.com/) 67 | -------------------------------------------------------------------------------- /episodes/062.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | We chat all things about the [Laravel](https://laravel.com/) ecosystem. 4 | 5 | # Guests 6 | * [Adam Wathan](https://twitter.com/adamwathan) 7 | * [Jeffrey Way](https://twitter.com/jeffrey_way) 8 | * [Taylor Otwell](https://twitter.com/taylorotwell) 9 | * [Dries Vints](https://twitter.com/driesvints) 10 | * [Mohamed Said](https://twitter.com/themsaid) 11 | 12 | Hosted by 13 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 14 | 15 | # Discussion - The panel talks about... 16 | 17 | ## What to expect as a new Laravel person 18 | * Laravel is a full featured framework for PHP that has pretty much most of what you need to develop a modern web app 19 | * Some things that includes: 20 | * Routing: Inspired by Sinatra. Similar to Slim and Silix 21 | * ORM: Called Eloquent that is inspired by the Ruby on Rails implementation of the Active Record design pattern 22 | * Unit testing 23 | * Message queue library 24 | * Support for Web Sockets 25 | * Laravel Mix: Makes working with Webpack much easier 26 | * geared for Rapid Application Development because the syntax is really simple and intuitive 27 | * Strives to have good documentation; if you can learn it quickly, then you can build it quickly 28 | 29 | 30 | ## What is the best place to get started learning about Laravel? 31 | * Jeffery has good videos on [Laracasts](https://laracasts.com) 32 | * Read the [documentation](https://laravel.com/docs) from beginning to end 33 | 34 | ## How does Taylor keep up with the ridiculous amount of PRs? 35 | * Taylor gets to work on Laravel full time 36 | * Has a Github page that has a list of all the PRs across all of the repositories 37 | * Tries to keep the list of PRs down to 10-15 38 | * Checks the PRs everyday for like an hour 39 | 40 | ## Has there ever been anything you wanted to implement in the framework that has been hindered by the PHP language itself? 41 | * Real threads. Even though the [pthreads](http://php.net/manual/en/book.pthreads.php) extension exists, it is not common for it to be available 42 | * Some collection / iterable things can't be passed into `array_map` or `array_filter`. You have to cast the object to an array before you can use it with those functions. 43 | 44 | ## Laravel has hired its first employee 45 | * It is [Mohamed Said](https://twitter.com/themsaid) 46 | * He has been on staff for roughly 6 months 47 | 48 | ## What is a typical day for employee #1 like? 49 | * Usually starts the day looking at the Github issues and pull requests and triage them 50 | * Tests new code on different environments 51 | * Looks at tasks in the various Laravel projects and sees what needs to be worked on 52 | * Lately have been studying Laravel Horizon; a project that is soon to be released 53 | * Spends an hour or two experimenting with new features Mohamed has in mind. Checks Laracasts forums to see if he can write a blog article that can help developers understand something better 54 | 55 | ## What kind of influence has Laravel had on Adam's success? 56 | * Lucky to be involved in a big community that is excited to learn new things and the same things he is working on 57 | 58 | ## Tools Adam finds exceptionally helpful when launching new products 59 | * [ConvertKit](https://convertkit.com/) - An email marketing automation tool. Makes it real easy to collect email address from people interested in your projects 60 | 61 | ## Refactoring to Collections 62 | * Adam wrote a [book](https://adamwathan.me/refactoring-to-collections/) about it 63 | * Started the book when he started to discover some of the functional features of PHP 64 | 65 | ## What is `tap` and the higher order `tap`? 66 | * The function `tap` allows you to pass in an object as the first parameter and a callable, like an anonymous function, as the second parameter. 67 | * More info on `tap` [here](https://medium.com/@taylorotwell/tap-tap-tap-1fc6fc1f93a6). PR for higher order tap [here](https://github.com/laravel/framework/commit/3abc4fb90fe59a90c2d8cccd27e310b20e5e2631) 68 | * Was originally in Rails, but then added to the Ruby language. This is where the inspiration came from for the Laravel implemnetation 69 | 70 | ## New way to do Laravel Migrations in 5.5 71 | * Some people think the `down` method in migrations is useless, specially in production, which can be dangerous 72 | * Now `down` is optional in 5.5 73 | * New `db:freash` command which drops all the tables and reruns all of the migrations. This way you do not need to write any `down` methods, which might save some time 74 | 75 | 76 | ## How does Laravel deal with the slowness that comes with the Reflection API? 77 | * You usually do not resolve enough stuff in a request to experience the slowdown. If you look at a controller, you might only have like 3-4 dependancies. 78 | * Haven't done anything special in the framework to mitigate the slowness 79 | * Taylor's first open source project was a reflection based DI container he wrote back in 2010. It was written for the Code Igniter community. The container in Laravel is similar to the one he wrote years ago. 80 | 81 | ## Whats a good way to decouple routing with the container? 82 | * They are integrated at that point, so you just have to deal with it 83 | 84 | ## Laracast 85 | * [Laracast](http://laracasts.com) is like the Netflix for developers 86 | * A great resource on Laravel besides the documentation 87 | * In general, Jeffery usually releases one or two videos at a time 88 | * Jeffery has been working on [Laravel Mix](https://laravel.com/docs/5.5/mix) and [Webpack](https://webpack.github.io/) in a [new series](http://webpackcasts.com/) recently. He is also working on a series where he [builds a forum from scratch](https://laracasts.com/series/lets-build-a-forum-with-laravel) 89 | 90 | ## Any advice on creating your own screencast business? 91 | * You need to update it often 92 | * If you are in the content business, you need a steady stream of stuff 93 | * When building a site, if you use 3rd party packages, make sure you trust the maintainer. You don't want them to end support and you are stuck with their old code 94 | 95 | ## What is the typical upgrade path of the Laracast site? 96 | * Usually updates at every minor release 97 | * Probably updates more often than many other Laravel production enviroments 98 | 99 | ## Why Laravel 5.5 instead of 6? 100 | * Laravel uses a slightly different versioning scheme, which is laid out in the [documentation](https://laravel.com/docs/5.5/releases#versioning-scheme) 101 | * Major numbers are used when there is a paradime shift in the framework 102 | * As of the time of the recording, there is no plan for Laravel 6. The Laravel 5 architecture and structure has been working out and there is no need to change everything. 103 | * For minor releases, the second number in the the release version, some minor breaking changes can be introduced. Taylor's guideline is to try to keep the changes low enough that a developer can update to the latest minor release within a day's worth of work 104 | 105 | ## What is Laravel.io? 106 | * It started out in 2013 with [Shawn McCool](http://shawnmc.cool/) as the original maintainer. Now maintained by Dries Vints 107 | * [Laravel.io](https://laravel.io/) is a discussion forum for developers 108 | * The source code for the site is on [Github](https://github.com/laravelio) 109 | * The next version of the site should come out a month or two after this recording. It is a total rewrite 110 | 111 | ## A Docker based solution like Laravel Homestead or Laravel Valet 112 | * There is nothing official, but [Laradock](http://laradock.io/) is the closet thing 113 | * It is very common that people roll their own solution 114 | 115 | ## Other Laravel Stuff 116 | * [Spark](https://spark.laravel.com/) A SaaS framework 117 | * [Lumen](https://lumen.laravel.com/) A micro framework based on Laravel 118 | * Bunch of official packages 119 | * [Cashier](http://laravel.com/docs/billing) Help with doing billing and subscriptions using either Stripe or Braintree 120 | * [Envoy](http://laravel.com/docs/envoy) A remote task runner. It can SSH to a box and run commands 121 | * [Passport](http://laravel.com/docs/master/passport) A Oauth2 server implementation for Laravel 122 | * [Scout](http://laravel.com/docs/master/scout) Adds full-text search to Eloquent models 123 | * [Socialite](https://github.com/laravel/socialite) Social Media authentication. Providers like Github, Facebook, Twitter, built-in. Lots of community driven providers listed [here](https://socialiteproviders.github.io/) 124 | 125 | ## Laravel Sneak Peak 126 | * [Horizon](http://laravel.com/docs/master/horizon) will come out at Laracon 2017 127 | * Next big thing might come out at the end of 2017, but most likely 2018 128 | 129 | ## Sammy Kaye wraps up with 130 | * Upcoming conferences: 131 | * [PHPTek](https://tek.phparch.com/) - Sammy is giving a couple of [talks](https://tek.phparch.com/speakers/sammy-powers/) 132 | * [PNW PHP](http://pnwphp.com/) 133 | * [Madison PHP](http://2017.madisonphpconference.com/) 134 | * [ConFoo](https://confoo.ca/en) 135 | * Developer Shoutout 136 | * Sponsor: [Zend Training](http://www.zend.com/en/services/training) 137 | * Winner: [Marcel Pociot](https://github.com/mpociot) 138 | * Shameless Plugs: 139 | * Adam: [Test Driven Laravel](https://testdrivenlaravel.com/) course. [Full Stack Radio](http://www.fullstackradio.com/) podcast 140 | * Dries: Working on a project called [Pilot](https://qapilot.com/). It tries to fill in the gaps in the QA testing space 141 | * Jeff: [Laracasts](https://laracasts.com/). [Laracast Podcast](https://laracasts.com/podcast) 142 | * Mohamed: Look into the [source code](https://github.com/laravel/framework) of Laravel 143 | * Taylor: [Forge](https://forge.laravel.com/) to spin up Laravel servers. [Envoyer](https://envoyer.io/) for deployment. [Laracon US](http://laracon.us/) and [Laracon EU](https://laracon.eu/) -------------------------------------------------------------------------------- /episodes/064.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | We take a deep-dive into the underlaying structure of the the PHP source code and talk about the scanner, parser, the new AST layer (and the evil things we can do with it), and the Zend engine. Let's see how the PHP sausage is made! 3 | 4 | # Guests 5 | * [Sara Golemon](https://twitter.com/SaraMG) 6 | 7 | Hosted by 8 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 9 | 10 | # Background 11 | Previous podcasts about PHP internals provide some context for this episode: 12 | * [005: PHP Internals - Past, Present & Future](https://www.phproundtable.com/episode/php-internals-past-present-future) 13 | * [025: PHP7 Release Management](https://www.phproundtable.com/episode/php7-release-management) 14 | * [038: RFC Show & Tell](https://www.phproundtable.com/episode/proposed-features-of-php-71) 15 | * [051: What happened to PHP 6?](https://www.phproundtable.com/episode/what-happened-to-php-6) 16 | * [059: PHP 7.1](https://www.phproundtable.com/episode/php-7-1) 17 | 18 | # Discussion - Sammy and Sara talk about... 19 | 20 | ## PHP 7.2 alpha 3 21 | * Next release is beta 1 22 | * Feature freeze/feature slushie is impending 23 | * The [retry keyword](https://wiki.php.net/rfc/retry-keyword) will not be in PHP 7.2 24 | 25 | ## What is your setup when working on PHP internals? 26 | * MacBook 27 | * [VMware Fusion](https://my.vmware.com/en/web/vmware/info/slug/desktop_end_user_computing/vmware_fusion/8_0) 28 | * [Ubuntu](https://www.ubuntu.com/) 29 | * Bash and git aliases to [automate common tasks](https://xkcd.com/1205/) 30 | * `make` tip: use [`-j N`](https://www.gnu.org/software/make/manual/html_node/Parallel.html) where N = [number of cores]+1 31 | 32 | ## Compiling PHP 33 | * PHP is not difficult to compile but if you are using PHP in userland, use a pre-compiled binary from a package manager 34 | * If you hit an issue with a pre-compiled binary, it cuts out a lot of ambiguity 35 | * PHP does not distribute a `configure` script because it is generated from other files in the repository. Requiring users to generate it removes the possibility of `configure` being out of sync. 36 | 37 | ## The scanner and the parser 38 | * PHP uses [re2c](http://re2c.org/) (regular expression to C) to generate a scanner (or lexer) and [Bison](https://www.gnu.org/software/bison/) to generate a parser 39 | * The scanner splits the input PHP code into tokens 40 | * The parser groups and arranges those tokens into meaningful expressions 41 | * In PHP 5, the parser directly converted parsed expressions to [opcodes](http://php.net/manual/en/internals2.opcodes.php) 42 | * In PHP 7, it is converted to an [Abstract Syntax Tree](https://wiki.php.net/rfc/abstract_syntax_tree) (AST) 43 | * Using an AST allows the compiler to perform optimisations 44 | * Sara's blog post about [the compiler processes](http://blog.golemon.com/2008/01/understanding-opcodes.html) 45 | * Sara's blog post about [lexers and parsers](http://blog.golemon.com/2006/05/re2c-is-no-lemon.html) 46 | 47 | ## How does the executor (or VM) work? 48 | * In PHP 4, this was basically a huge `while` loop with a `switch` statement in it: 49 | * Loop over each opline 50 | * `switch` statement defines behaviour for each opcode 51 | * PHP 5 used a call VM: 52 | * We still loop over each opline 53 | * Instead of the big `switch`, each opline has a handler field containing a pointer to a callback function 54 | * In PHP 7, the call VM is still in use but other styles are also used, including computed goto 55 | * The [Zend VM](https://github.com/php/php-src/blob/master/Zend/zend_vm_def.h) is generated by a [PHP file](https://github.com/php/php-src/blob/master/Zend/zend_vm_gen.php). You can't build the PHP executor without PHP 56 | 57 | ## Testing 58 | * PHP internals has ~15,000 tests 59 | * Running the full test suite doesn't support parallelisation - they all run in series 60 | * [PHP TestFest](https://phptestfest.org/) aims to encourage people to add tests to PHP Internals 61 | * The test suite for PHP is written in PHP - you don't need to know C to contribute tests 62 | * [PHP Code Coverage](http://gcov.php.net/) allows us to discover PHP internals code that is missing tests 63 | 64 | ## PHP Internals Documentation 65 | * [PHP Internals Book](http://www.phpinternalsbook.com/) 66 | * Internals lacks inline documentation in many places and the [Doxygen RFC](https://wiki.php.net/rfc/doxygen) recently failed 67 | * [PHP 7 Virtual Machine](https://nikic.github.io/2017/04/14/PHP-7-Virtual-machine.html) 68 | * ..and more generally [Nikita Popov's blog](https://nikic.github.io/) 69 | 70 | ## Sammy Kaye wraps up with 71 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 72 | * Upcoming conferences: 73 | * [North East PHP](https://northeastphp2017.sched.com/) 74 | * [Zendcon](http://www.zendcon.com/) 75 | * [Pacific Northwest PHP](http://www.pnwphp.com/) 76 | * Developer Shout-Out: Julien Pauli 77 | * Shameless plugs: 78 | * [Donate](http://support.hopeforthewarriors.org/site/TR?fr_id=1180&pg=teamlist) to Team No Sleep 'till Brooklyn in [Rally North America](https://www.rallynorthamerica.com/) 79 | -------------------------------------------------------------------------------- /episodes/065.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | Adding tests to php-src is a great way to get involved with PHP internals. Don't know how to get started? You're in luck. [TestFest 2017](https://phptestfest.org/) is going to be a thing in September. User groups and individuals around the world are going to organize to learn how to add tests to PHP and become official internals contributors. 3 | 4 | It has been 7 years since the last [TestFest in 2010](https://wiki.php.net/qa/testfest-2010). We chat about how to get involved with TestFest 2017. 5 | 6 | # Guests 7 | * [Ben Ramsey](https://twitter.com/ramsey) 8 | * [Rafael Dohms](https://twitter.com/rdohms) 9 | * [Zoë Slattery](https://twitter.com/zoe_slattery) 10 | * [Cal Evans](https://twitter.com/CalEvans) 11 | 12 | Hosted by 13 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 14 | 15 | # Discussion - The panel talks about... 16 | 17 | # How do I get involved? 18 | * TestFest runs from September - December 2017 19 | * Join the [Google group](https://groups.google.com/a/phpcommunity.org/forum/#!forum/testfest) 20 | * Attend an event 21 | * If you are a user group, run one or more events where you: 22 | * Introduce TestFest 23 | * Explain what PHPT tests are and how to create them 24 | * Explain how to contribute them 25 | * Help everyone to get set up 26 | * Hold a mini-hackathon where devs write tests for PHP and help each other 27 | * Sammy's [Video Tutorials](https://phptestfest.org/tutorials/writing-tests-for-php-source/) provide some teaching materials 28 | * [docker-phpqa](https://phptestfest.org/tutorials/phpqa-tutorial/) can help devs to get an environment up-and-running quickly 29 | * Contribute the tests to [php-src](https://github.com/php/php-src) 30 | 31 | # Do I need to know C to contribute tests? 32 | * The tests themselves are not written in C. They are written in PHP. 33 | * To find untested code, you will need to read some C code to understand the coverage reports at http://gcov.php.net/ 34 | * You don't need to be able to fully parse the code in order to do this 35 | * There is some internals documentation at [PHP Internals Book](http://www.phpinternalsbook.com/) 36 | 37 | ## Sammy Kaye wraps up with 38 | * Contribute [show notes](https://github.com/PHPRoundtable/show-notes/) 39 | * Upcoming conferences: 40 | * [North East PHP](https://northeastphp2017.sched.com/) 41 | * [Zendcon](http://www.zendcon.com/) 42 | * [Pacific Northwest PHP](http://www.pnwphp.com/) 43 | * Developer Shout-Out: Khayrattee Wasseem 44 | * Shameless plugs: 45 | * http://news.php.net/ 46 | * [Kesha Williams - Machine Learning Circa Minority Report](https://nomadphp.com/machine-learning-circa-minority-report/) 47 | * [PHP São Paulo](https://www.meetup.com/php-sp/) 48 | -------------------------------------------------------------------------------- /episodes/066.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | After years of resisting, SammyK finally drank the [Docker](https://www.docker.com/) Kool-Aid for his everyday client work. We talk about his transition from [Vagrant](https://www.vagrantup.com/) to Docker and some bumps he hit along the way. 4 | 5 | # Guests 6 | * [Phillip Shipley](https://twitter.com/phillipshipley) 7 | * [Chris Fidao](https://twitter.com/fideloper) 8 | * [Chris Tankersley](https://twitter.com/dragonmantank) 9 | 10 | Hosted by 11 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 12 | 13 | # Notes 14 | 15 | You can submit a form on [phproundtable.com](https://www.phproundtable.com/contact) with any ideas you have for topics that can be discussed on the podcast. 16 | 17 | The last episode about Docker was Episode 48. 18 | 19 | Brand new stickers are available (much smaller!), and will be sent out for the Developer Shout-Outs. 20 | 21 | ## Discussion - The panel talks about... 22 | 23 | ### Docker Compose vs. Docker 24 | 25 | Comparison: 26 | * You need to use Docker to figure out how Docker works. Start with this. 27 | * Then you use Docker Compose, because you know how Docker works by this point, so it does most of the work for you. 28 | * Docker Compose allows you to keep all of your configuration in a text file. With regular Docker, you need to use multiple commands to set everything up. 29 | 30 | Minimum, you need: 31 | * `Dockerfile` 32 | * What container you are starting with (base container) 33 | * Commands to set up your configuration / install things for you 34 | 35 | ### When to use the `--rm` flag 36 | 37 | Docker command has multiple flags. For example: 38 | * `-i` - Interactive shell 39 | * `-t` - Allocate a tty 40 | * `--rm` - Remove container after you're done 41 | 42 | **Q: Why would you create it, only to delete it again after it's done?** 43 | 44 | Chris Tankersley: 45 | * He generally has an Apache container, a MySQL container, and a couple of other containers that make the application work. Those you usually want to stay around. Don't `--rm` those. 46 | * Others (composer, unit tests, etc) you will `--rm` ... you want to use them for something quick, but don't care about keeping them around (unlike the database container). 47 | 48 | Phillip Shipley: 49 | * Will often use `--rm` when he's initially building his `Dockerfile`. 50 | * He can exec into a base container (or run it interactive), and have it delete itself afterwards. 51 | * Once it's working how he wants it to and he's finished making rapid changes to his `Dockerfile`, he can remove the `--rm` flag. It's built-in garbage collection! 52 | 53 | Chris Fidao: 54 | * When you stop a container, it still exists - it's just not running. 55 | * If you never clean out those containers, you have this list of unused containers just hanging around in your system. 56 | 57 | ### Image vs Container 58 | 59 | Main difference: 60 | * You build the image (state / like an OOP Class) 61 | * Container is run from the image (instance / like an OOP Object) 62 | 63 | Key points: 64 | * By running `--rm` you are cleaning up the container, but the image still exists. 65 | * When you make changes in your `Dockerfile` to copy files into the image, you want to _make sure you are rebuilding the image_. Otherwise, when you rebuild the container, it won't have copied those files in because it's still using the old image. 66 | 67 | ### Docker Compose commands 68 | 69 | Docker Compose settings are saved inside the `docker-compose.yml` file in your project root. 70 | 71 | `docker build`: 72 | * BUILD - Build (or rebuild) the image. 73 | 74 | `docker up` and `docker down`: 75 | * UP - Bring the environment up. Creates containers and starts them. 76 | * DOWN - Bring the environment down. Stops containers and removes them. 77 | 78 | `docker start` and `docker stop`: 79 | * START - Starts services from existing containers. 80 | * STOP - Stops services, but doesn't remove them. 81 | 82 | Running `docker up` will usually do `docker build` for you: 83 | * If the image doesn't exist, it will detect this and will build the image for you, saving the need to run `docker build` manually. 84 | * If you've made changes to `Dockerfile` or `docker-compose.yml`, it should detect this and rebuild the image for you. 85 | * If you've made changes to other files (e.g. your source code), it won't detect that and you need to run `docker build` manually before you start it up again. 86 | 87 | Notes about adding files: 88 | * Copy/add files - takes place at build time, and adds them to the image. 89 | * You can also use volumes, which is a way of adding files to the container at runtime. 90 | * Official container for MySQL sets up the database on a volume. Since it's effectively mounted, the files end up on your disk. 91 | 92 | Important distinction to make: 93 | * UP - Creates containers and starts them. 94 | * DOWN - Stops containers and removes them. 95 | * START - Start container only. 96 | * STOP - Stop container only. 97 | 98 | So, to clarify: 99 | * UP/DOWN = Full environment and stack. 100 | * START/STOP = Just the container. 101 | 102 | ### Project structure - best practices 103 | 104 | With Docker version 2 & 3 - you can specify named volumes: 105 | * You can make a volume that is mountable across multiple containers. 106 | * Persistent outside of the containers, too. 107 | * By defining a named volume in your configuration file, the data will persist between up/down commands. 108 | 109 | There is a speed drop with Windows / macOS: 110 | * Trying to access files from a Linux Docker container on your Windows or macOS system, it's slower. This is because the linux container boots up inside a VM. 111 | * Docker runs underneath the host OS kernel, it's not actually a VM in and of itself. 112 | * But since Windows / macOS are not linux, it bootstraps itself inside of a linux virtual machine. 113 | * If you need to get to stuff on your host machine, you're effectively trying to put your host machine inside a virtual machine. 114 | * The issue on macOS is that the layer it uses is very slow. Not an issue with Docker, it's an issue with the intermediate layer. Apple is working with Docker to speed that up. 115 | * Windows seems to do slightly better than macOS in terms of speed for Linux containers. 116 | * Linux is best of all for running Linux, because you don't need the virtualisation layer. 117 | * You mainly see the speed drop for I/O heavy traffic. So applications that rely on heavy I/O will suffer most noticeably. 118 | 119 | ### Docker in Production 120 | 121 | Docker as a product has stabilised significantly over the years, and is now much easier to use. It's getting better and better, and a lot of the rough edges have been "shaved off". 122 | 123 | Production readiness: 124 | * Build for production 125 | * In your development environment, plug in what you need just for that environment. 126 | * You only want certain runtime dependencies like Xdebug in the environment that you need them (development). They should not exist in the production environment. 127 | 128 | You can stack multiple configuration files on top of each other: 129 | * For example, `docker-compose.yml` (production) and `docker-compose.dev.yml` (development). 130 | * It will take the stuff in dev and then merge it into the production one. 131 | 132 | Upcoming feature: Multi-stage builds: 133 | * A single `Dockerfile` that builds multiple images (i.e. production & development) 134 | 135 | Multiple startup scripts: 136 | * You can have two separate bash scripts, one that launches with production config, and another that launches with dev config. 137 | * Each script can be used for a different entry point, and can do some different set up before starting the container. 138 | 139 | Docker is greater for the state-less part of your application, i.e. your code. 140 | 141 | Everything else should probably be pushed out to other services (Amazon RDS, Redis, etc). 142 | 143 | #### Docker Machine 144 | 145 | You can use Docker Machine with Amazon / Digital Ocean, to set up your machine. 146 | 147 | It allows you to run things from your local machine. You can run Docker Up regardless of whether you're working on your local environment, or your production environment, which is pretty nice. 148 | 149 | Under the hood, Docker is pretty much just a HTTP API. The Docker command is literally just an API client! 150 | 151 | #### Docker Hub 152 | 153 | A registry for storing your images. You can access public images, or you can pay to store your private images there. 154 | 155 | On your docker server, you would then pull those images down from Docker Hub (or a similar service). 156 | 157 | Updates could be as simple as: 158 | 1. Stop container 159 | 1. Docker Pull 160 | 1. Start container 161 | 162 | #### Docker Swarm 163 | 164 | Allows you to run multiple instances quite easily, and will do the rolling release for you. 165 | 166 | There are ways to set this up with EC2. ECS orchestration service is free, you just pay for the actual EC2 usage. 167 | 168 | ### Accessing Docker via CLI 169 | 170 | **Q: Vagrant allows us to simply connect using `vagrant ssh`. How do we do something similar with Docker?** 171 | 172 | * The main thing to remember is that Docker isn't a machine, it's a process. It spins up a process and then watches it. 173 | * You can use something like `docker exec` to spin up a second process in the same area, rather than SSHing into a machine. 174 | * They might act like machines, but they're not. There's not actually a command-line process / ssh daemon running inside those containers, usually. 175 | * If you change things in that container, you will lose it when you restart. The restarted container will go off the base image, so to make changes you should modify the image instead. 176 | * Most containers expect to run as root, they don't expect another user to run inside of them. So it's not a good idea to set up additional users. 177 | 178 | ### Sub-domains / TLS in Development 179 | 180 | * Generally, don't bother. Just bind to a different port if you need multiple apps running at once. 181 | * There are ways to get things like Let's Encrypt set up locally if you need it, but on a day-to-day basis it's usually not something the panel members worry about. 182 | 183 | ### Logging 184 | 185 | * You can run in the foreground and have it tail the logs for you, but using Ctrl+C afterwards is a little tricky. 186 | * It's probably better to run it in the background (as a daemon) instead using `docker up -d`, and then use the `docker logs --follow` command to follow your logs. 187 | * Docker most likely expects you to shut it down using `docker down`, not `Ctrl+C`. 188 | * If you want to get really fancy, you can push to Kibana, etc. 189 | 190 | ## Sammy Kaye wraps up with 191 | * Show Notes Shoutout 192 | * Chris Shaw: Episode 064 (PHP 7 Source Code: A Deep Dive) 193 | * Christopher Thomas: Episode 030 (SLA & Micro Services) 194 | * Developer Shoutout 195 | * Sponsor: [Zendcon](http://www.zendcon.com/) 196 | * Winner: [Ed Finkler](https://twitter.com/funkatron) for [OSMI: Open Sourcing Mental Illness](https://osmihelp.org/) 197 | * Shameless Plugs: 198 | * Chris Fidao: [ServersForHackers.com](https://serversforhackers.com/) has Docker-related courses, both free and paid. 199 | * Chris Tankersley: [LearningContainers.com](http://learningcontainers.com/) and his "Docker for Developers" book (EPUB, PDF, Print) 200 | * Phillip Shipley: [ECS Deploy script](https://github.com/silinternational/ecs-deploy) that is used to simplify how they do their rolling releases, and [Terraforming Your Docker Environment on AWS](https://blog.codeship.com/terraforming-your-docker-environment-on-aws/) blog post. 201 | 202 | -------------------------------------------------------------------------------- /episodes/069.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | Hello, and welcome to the first recording of PHP Round Table for 2018! This is a podcast where PHP nerds discuss things that developers care about. 4 | 5 | # Guests 6 | * [Chris Tankersley](https://twitter.com/dragonmantank) 7 | * [Joe Ferguson](https://twitter.com/JoePFerguson) 8 | 9 | Hosted by 10 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 11 | 12 | ## Discussion - The panel talks about... 13 | 14 | ### Databases and Application State 15 | 16 | * Sometimes it's difficult to tell whether data should be hard-coded, or stored in the database. For example, a list of all 50 states in the United States. 17 | * Joe has worked with an e-Commerce business (back in early 2006) which worked with customers from multiple countries across the globe. In that case, it's good to have some kind of auto-updating system - even better if you can pull that from an external service that maintains the list for you, and then cache in your database. 18 | * It all comes down to how often the data changes. US states do not change often - they could go in config. But there are new zip codes being added constantly. 19 | * Chris' application looks up geolocation for IPs. In many cases, the IP range mapping to countries changes, so it's not really something you can keep in config. 20 | * Be wary of giving your credit card details to online services that provide a list of zip codes, because many of them are unreliable. 21 | * [Smarty Streets API](https://smartystreets.com/docs/cloud/us-street-api) is one of those services that SammyK first implemented Codeception and Feature Acceptance Tests on. He was hitting the real API in his tests, and quickly ran up against the request limit! 22 | 23 | ### Templating Engines 24 | 25 | * [Smarty](https://www.smarty.net/) - both Chris and Joe have used in the past, but not recently. 26 | * [Twig](https://twig.symfony.com/) - currently used by SammyK for non-Laravel projects. 27 | * [Blade](https://laravel.com/docs/5.6/blade) - currently used by SammyK for Laravel projects. 28 | * [Plates](http://platesphp.com/) - Joe feels that this is pretty awesome, but doesn't get as much credit as it should. 29 | 30 | If you're only getting into templating now, it's probably worth starting with Twig, because it will help you to do things properly. 31 | 32 | ### Storing Poop Emojis in your Database 33 | 34 | * Make sure you're using MySQL's `utf8mb4`, you can't just use `utf8`. 35 | 36 | ### Displaying right-to-left languages in HTML 37 | 38 | * Use the [bdi](https://www.w3.org/International/articles/inline-bidi-markup/#bdi) element (bidirectional isolate) 39 | 40 | ### Podcast Tips 41 | 42 | * Don't go months without a podcast, and then expect everything to flow and your guests to be sober! ;-) 43 | 44 | ### Things That Nerds Care About That Don't Matter 45 | 46 | * Just go through PSR-2! 47 | * Tabs vs Spaces 48 | * Using carriage-returns instead of spaces ... what?! 49 | * Postgres - When you try to add a column to a table, you are forced to add it to the end! 50 | * Trailing commas - Joe feels that it looks wrong when the last item doesn't have a trailing comma 51 | * PHP 7.3 allows trailing commas in method calls! 52 | * Fixed-width fields in input files can cause PTSD 53 | * How to pronounce GIF (Graphics Interchange Format, 'giff' and 'jiff') 54 | * How to pronounce CSRF (Cross-Site Request Forgery, 'C-S-R-F' or 'c-surf') 55 | * How to pronounce XSS (Cross-Site Scripting, 'X-S-S' or other silly pronunciations) 56 | * How to pronounce CSPRNG (Cryptographically Secure PseudoRandom Number Generator, 'C-Spring' or 'C-Sprung' in past-tense!) 57 | * How to pronounce PRNG (PseudoRandom Number Generator, or 'Pring'??) 58 | * Trying to map programming concepts to the school environment 59 | * How many pivot tables in a relational database should you reach, before it's better to just use a graph database? 60 | * How to pronounce PNG (Portable Network Graphics, 'P-N-G' or 'Ping') 61 | * Where do extensions for PHP go to die? PECL! Not to be confused with Pickle. 62 | * Don't use `gdb` as an alias for 'git delete branch' if you also want to use the GNU Project Debugger! 63 | 64 | ### The big reveal! 65 | 66 | * Watch the video from 48:52 to 50:55 for details! 67 | 68 | ## Sammy Kaye wraps up with 69 | 70 | * Shameless Plugs: 71 | * Chris Tankersley: [LearningContainers.com](http://learningcontainers.com/) 72 | 73 | -------------------------------------------------------------------------------- /episodes/073.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | Hello, and welcome to episode 073 of PHP Round Table! This is a podcast where PHP nerds discuss things that developers care about. 4 | 5 | # Guests 6 | * [Craig Duncan](https://twitter.com/duncan3dc) 7 | * [Ondřej Mirtes](https://twitter.com/OndrejMirtes) 8 | * [Vladimir Reznichenko](https://twitter.com/kalessil) 9 | * [Damien Seguy](https://twitter.com/faguo) 10 | 11 | Hosted by 12 | * [Sammy Kaye Powers](https://twitter.com/SammyK) 13 | 14 | ## Discussion - The panel talks about... 15 | 16 | ### Static Code Analyzers 17 | 18 | Static code analysis tools maintained by the guests: 19 | 20 | * [Exakat](https://www.exakat.io/) 21 | * [PHPStan](https://github.com/phpstan/phpstan) 22 | * [PHP Inspections (EA Extended)](https://plugins.jetbrains.com/plugin/7622-php-inspections-ea-extended-) and [PHP Inspections (EA Ultimate)](https://plugins.jetbrains.com/plugin/10215-php-inspections-ea-ultimate-) 23 | 24 | ### Learnings and Recommendations 25 | 26 | In no particular order: 27 | 28 | * Start simple by installing one of these or other tools and let it analyze your code base. 29 | * Integrate static code analysis into your continuous integration process. 30 | * Most tools support error levels so you can fine-tune your checks. 31 | * Go for easy fixes that stand out in your code base first. 32 | * Static code analysis is useful for PHP projects because PHP does not have a compiler ([yet](https://externals.io/message/102415#102415) ;-)). 33 | 34 | ### Misc 35 | 36 | Colin O'Dell asked for a [working PHPStan config for Drupal 8](https://twitter.com/colinodell/status/1006613928393273344) during the recording of the podcast. [Here it is](https://gist.github.com/dantleech/84d82659583e55d0ffeb48d36d27a9fc). 37 | -------------------------------------------------------------------------------- /episodes/84.md: -------------------------------------------------------------------------------- 1 | Ben shared with us his experience being a Release Manager for PHP 8.1. We also talk about the voting process for Release Manager voting for 8.2 (https://externals.io/message/117716#1...). Congratulations to Sergey Panteleev and Pierrick Charron on becoming the Release Managers for PHP 8.2. We share our thoughts on how to follow along with discussions happening on PHP Internals. 2 | 3 | We also talk about PHP Internal's move to Github (https://github.com/php). What's been going on at the PHP Foundation. Joining PHP Social-verse and the overall Fediverse at https://phpc.social. The return of PHP in-person Meetups and Conferences and MergePHP - https://twitter.com/mergephp. 4 | -------------------------------------------------------------------------------- /episodes/85.md: -------------------------------------------------------------------------------- 1 | An international panel of PHP Community members discusses the stat of PHP User Groups. How to get involved, so of the pitfalls, and a lot of the benefits of being a part of the community. 2 | 3 | ## Panel Member: 4 | 5 | * [Andreas Heigl](https://twitter.com/heiglandreas) 6 | * [Rafael Dohms](https://twitter.com/rdohms) 7 | * [Rick Kuipers](https://twitter.com/rskuipers) 8 | * [Bob Bloom](https://twitter.com/bobbloom) 9 | * [Chris Spruck](https://twitter.com/cspruck) 10 | * [Joe Ferguson](https://twitter.com/JoePFerguson) 11 | * [Ben Ramsey](https://twitter.com/ramsey) 12 | * [Sara Golemon](https://phpc.social/web/@pollita) 13 | * [Eric Van Johnson](https://twitter.com/shocm) 14 | 15 | ## Links Discussed on the show 16 | 17 | * [https://twitter.com/taylorotwell/status/1537970285097275393](https://twitter.com/taylorotwell/status/1537970285097275393) 18 | * [https://php.ug/](https://php.ug/) 19 | * [https://wiki.php.net/usergroups](https://wiki.php.net/usergroups) 20 | * [https://nashvillephp.org/](https://nashvillephp.org/) 21 | * [https://phpamersfoort.nl/](https://phpamersfoort.nl/) 22 | * [https://memphistechnology.org/](https://memphistechnology.org/) 23 | * [https://atlantaphp.org/](https://atlantaphp.org/) 24 | * [https://gtaphp.org/](https://gtaphp.org/) 25 | * [https://www.meetup.com/gta-php-user-group-toronto/](https://www.meetup.com/gta-php-user-group-toronto/) 26 | * [https://bobbloom.me/gta-php-meetup-23jun2022](https://bobbloom.me/gta-php-meetup-23jun2022) 27 | 28 | Stay current with what we are doing by following and subscribing. 29 | 30 | * Website: [https://phproundtable.com](https://phproundtable.com) 31 | * YouTube: [https://www.youtube.com/phproundtable](https://www.youtube.com/phproundtable) 32 | * Twitter: [@phproundtable](https://twitter,com/phproundtable) 33 | * Mastodon: [@phproundtable@phpc.social](https://phpc.social/web/@phproundtable) 34 | * Audio Podcast: [https://pca.st/usqnzuif](https://pca.st/usqnzuif) 35 | * Discord: [https://discord.gg/wmD3sGnMMe](https://discord.gg/wmD3sGnMMe) 36 | -------------------------------------------------------------------------------- /episodes/86.md: -------------------------------------------------------------------------------- 1 | ## Links from the Show 2 | 3 | - [Boise State University GIMM Program](https://www.boisestate.edu/gimm/) 4 | 5 | - [Madison Area Technical College](https://madisoncollege.edu/) 6 | 7 | ## The Panel 8 | - **Eric Van Johnson** - This is me :-) I am a self-taught PHP developer and have been running a development studio for over ten years. Back in 2021, my business partner and I took over the operations of php[architect] / [phparch.social/@eric](https://phparch.social/@eric) and [@shocm on Twitter](https://twitter.com/shocm) 9 | 10 | - **Ben Ramsey** - A Software Architect, maintainer of the PHP UUID library, release manager for PHP 8.1 and 8.2, and does a lot for the PHP Community as a whole / [phpc.social/@ramsey](https://phpc.social/@ramsey) 11 | 12 | - **Joe Ferguson** - Principal Software Engineer. Writer for php[architect], and is one of the organizers behind [OSMI](https://osmihelp.org/) / [phpc.social@joepferguson](https://phpc.social/@joepferguson) 13 | 14 | - **Sara Golemon** - Contributor to PHP Core, PHP Release Manager 8.0 and 7.2, Author, and has code on Mars / [phpc.social@pollita](https://phpc.social/@pollita) 15 | 16 | - **Kenneth Marks** - Author of "PHP Web Development with MySQL" and teaching IT programming at [Madison Area Technical College](https://madisoncollege.edu/) for ten and a half years in the Web Software Developer degree program / [@FlibertiGiblets](https://twitter.com/FlibertiGiblets) 17 | 18 | - **Kaelyn Lang** - Student at [Madison Area Technical College](https://madisoncollege.edu/) studying Web Software Development BFA in Game Design and Development - Art and a minor in Computer Science from the [University of Wisconsin-Stout](https://www.uwstout.edu/) 19 | 20 | - **Jack Polifka** - Clinical assistant professor at [Boise State University in the Games, Interactive Media, and Mobile (GIMM) program](https://www.boisestate.edu/gimm/) 21 | / [@jack_polifka](https://twitter.com/jack_polifka) 22 | 23 | - **Adam Giles** - third-year student at [Boise State University](https://www.boisestate.edu/gimm/) 24 | pursuing an undergraduate degree in Games, Interactive Media, and Mobile [(GIMM)](https://www.boisestate.edu/gimm/) / [@adamgiles278]( https://twitter.com/adamgiles278) 25 | 26 | - **Derek Pyatt** - third-year student at [Boise State University](https://www.boisestate.edu/gimm/) 27 | pursuing an undergraduate degree in Games, Interactive Media, and Mobile [(GIMM)](https://www.boisestate.edu/gimm/), also working as a Web and Digital Coordinator for BSU's Admissions office / [@pyatt_derek](https://twitter.com/pyatt_derek) 28 | 29 | 30 | ## Thanks to the our sponsor 31 | [![php\[architect\]](https://cdn.phparch.social/logos%2Fphparch-logo-orange-with-slogan%20(150%20%C3%97%20150%20px).png)](https://phparch.com) 32 | 33 | 34 | ### Shownotes 35 | To add to or modify these show notes please open a PR to [show notes for episode 86](https://github.com/PHPRoundtable/show-notes/blob/master/episodes/86.md) 36 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # PHP Roundtable Show Notes 2 | 3 | Here is a list of the episodes that need show notes on [PHPRoundtable.com](https://www.phproundtable.com/). 4 | 5 | Pull requests are welcome and you will be fully credited during a live recording and on the website. 6 | 7 | Just use the following template and save it to a markdown file in the `episodes/` folder and name the file after the episode number. 8 | 9 | ``` 10 | # Episode Title Here 11 | 12 | > No need to add the description or panelist info here since it's already on the site. :) 13 | 14 | ## Some Point 15 | 16 | - Some more details on the subject. 17 | - Jane mentions some [blog post](https://www.sammyk.me/how-to-compile-an-unreleased-rfc-feature-for-php-source-php-internals) relevant to the topic. 18 | 19 | ## Some Other Point 20 | 21 | - Some other point summarized. 22 | - Another point here. 23 | 24 | > No need to add developer shout-outs or shameless plugs since those are already on the site as well. :) 25 | ``` 26 | 27 | | # | Episode | Status | Credit | 28 | |-------|-----------|----------|----------| 29 | | 080 | [PHP Internals: Preloading, FFI & More][080] | :exclamation: | | 30 | | 079 | [GDPR For PHP Devs][079] | :exclamation: | | 31 | | 078 | [DocBlocks, Annotations, PSR-5 & The Like][078] | :exclamation: | | 32 | | 077 | [Tech Interviews for Self-Taught PHP Programmers][077] | :exclamation: | | 33 | | 076 | [Concurrency, Generators & Coroutines - Oh My!][076] | :exclamation: | | 34 | | 075 | [Web Content Accessibility Guidelines (WCAG) 2.1][075] | :white_check_mark: | [Eric Eggert][@yatil] | 35 | | 074 | [Secrets, Secrets, Are No Fun][074] | :exclamation: | | 36 | | 073 | [PHP Static Analysis][073] | :white_check_mark: | [Matthias Gutjahr][@mattsches] | 37 | | 072 | [Secret Project Revealed!][072] | :exclamation: | | 38 | | 071 | [Extra, extra: PHP 7.2 released!][071] | :exclamation: | | 39 | | 070 | [All things WordPress][070] | :exclamation: | | 40 | | 069 | [Catching Up With PHP Friends][069] | :white_check_mark: | [Shane Smith][@shane-smith] | 41 | | 068 | [PHP's Dirty Little Segfault Secret][068] | :exclamation: | | 42 | | 067 | [Imposter syndrome and the Dunning-Kruger effect][067] | :exclamation: | | 43 | | 066 | [Docker: Drinking the Kool-Aid][066] | :white_check_mark: | [Shane Smith][@shane-smith] | 44 | | 065 | [TestFest 2017][065] | :white_check_mark: | [Chris Shaw][@chris48s] | 45 | | 064 | [PHP 7 Source Code: A Deep Dive][064] | :white_check_mark: | [Chris Shaw][@chris48s] | 46 | | 063 | [A php[tek] 2017 Special][063] | :exclamation: | | 47 | | 062 | [All things Laravel][062] | :white_check_mark: | [Chris Thomas][@cwt137] | 48 | | 061 | [Dependency Injection][061] | :white_check_mark: | [Chris Shaw][@chris48s] | 49 | | 060 | [Logging & Crash Reporting in PHP][060] | :white_check_mark: | [Chris Shaw][@chris48s] | 50 | | 059 | [PHP 7.1][059] | :white_check_mark: | [Chris Shaw][@chris48s] | 51 | | 058 | [HTTPlug, Guzzle & API's][058] | :white_check_mark: | [Chris Shaw][@chris48s] | 52 | | 057 | [All Things Zend][057] | :white_check_mark: | [Chris Shaw][@chris48s] | 53 | | 056 | [Hourly vs Value-Based Pricing][056] | :white_check_mark: | [Chris Shaw][@chris48s] | 54 | | 055 | [Acceptance Testing with Behat][055] | :white_check_mark: | [Chris Shaw][@chris48s] | 55 | | 054 | [Security: Encryption, Hashing and PHP][054] | :white_check_mark: | [Chris Shaw][@chris48s] | 56 | | 053 | [Why I'm Afraid To Admit I Use PHP][053] | :white_check_mark: | [Chris Shaw][@chris48s] | 57 | | 052 | [Happy Birthday PHP Roundtable!][052] | :exclamation: | | 58 | | 051 | [What happened to PHP 6?][051] | :white_check_mark: | [Chris Shaw][@chris48s] | 59 | | 050 | [PHP For Beginners][050] | :white_check_mark: | [Chris Shaw][@chris48s] | 60 | | 049 | [Event Sourcing in PHP][049] | :white_check_mark: | [Andy Huggins][@andy_huggins] | 61 | | 048 | [Docker & PHP][048] | :white_check_mark: | [Chris Shaw][@chris48s] | 62 | | 047 | [All About HTTP/2][047] | :white_check_mark: | [Chris Shaw][@chris48s] | 63 | | 046 | [Character Encoding and UTF-8 in PHP][046] | :white_check_mark: | [Dominic Bordelon][@dominicbordelon] | 64 | | 045 | [A php-tek 2016 Special][045] | :exclamation: | | 65 | | 044 | [Asynchronous PHP][044] | :white_check_mark: | [Chris Shaw][@chris48s] | 66 | | 043 | [A Lone Star PHP 2016 Special][043] | :exclamation: | | 67 | | 042 | [Staying Relevant For Web Development][042] | :white_check_mark: | [Chris Shaw][@chris48s] | 68 | | 041 | [The PHP-FIG: Past, Present & Future][041] | :white_check_mark: | [Chris Shaw][@chris48s] & [Ken Guest][@kenguest] | 69 | | 040 | [Graph Databases][040] | :white_check_mark: | [Chris Shaw][@chris48s] | 70 | | 039 | [From Idea To Production: Part 2][039] | :white_check_mark: | [Chris Shaw][@chris48s] | 71 | | 038 | [RFC Show & Tell][038] | :white_check_mark: | [Chris Shaw][@chris48s] | 72 | | 037 | [An ORM Discussion][037] | :white_check_mark: | [Chris Shaw][@chris48s] | 73 | | 036 | [A Room 11 Special][036] | :exclamation: | | 74 | | 035 | [Immutable PHP][035] | :white_check_mark: | [Chris Shaw][@chris48s] | 75 | | 034 | [Debugging is more than var_dump()][034] | :white_check_mark: | [Peter Keller][@petekeller2] | 76 | | 033 | [Design Patternmania][033] | :white_check_mark: | [Andy Huggins][@andy_huggins] | 77 | | 032 | [Running A Rockin' PHP User Group][032] | :exclamation: | | 78 | | 031 | [Checking in with PHP & HHVM internals][031] | :exclamation: | | 79 | | 030 | [SOA and Microservices][030] | :white_check_mark: | [Chris Thomas][@cwt137] | 80 | | 029 | [The Only Girl In The Room][029] | :exclamation: | | 81 | | 028 | [The Alcoholic & Unfit PHP Culture][028] | :exclamation: | | 82 | | 027 | [A Laracon US Special][027] | :white_check_mark: | [Andy Huggins][@andy_huggins] | 83 | | 026 | [Documentation & Developer Experience][026] | :exclamation: | | 84 | | 025 | [PHP7 Release Management][025] | :exclamation: | | 85 | | 024 | [Becoming A PHP Entrepreneur][024] | :exclamation: | | 86 | | 023 | [PHP's Major "Bus Factor" Problem][023] | :white_check_mark: | [Chris Shaw][@chris48s] | 87 | | 022 | [All About PSR-7][022] | :exclamation: | | 88 | | 021 | [From Idea To Production: Part 1][021] | :white_check_mark: | [Sammy Kaye Powers][@SammyK] & [Steven Maguire][@StevenMaguire] | 89 | | 020 | [A Loosely Coupled Mashup @ php[tek]][020] | :exclamation: | | 90 | | 019 | [The Business of PHP][019] | :exclamation: | | 91 | | 018 | [F8 Afterglow & The PHP SDK][018] | :exclamation: | | 92 | | 017 | [Modernizing Legacy Codebases in PHP][017] | :white_check_mark: | [Chris Shaw][@chris48s] | 93 | | 016 | [Contributing To PHP 7][016] | :exclamation: | | 94 | | 015 | [SemVer Licensing & OS Support Expectations][015] | :exclamation: | | 95 | | 014 | [A Midwest PHP Special][014] | :exclamation: | | 96 | | 013 | [TDD & BDD In PHP][013] | :exclamation: | | 97 | | 012 | [A PHP Town Hall Mashup at Sunshine PHP][012] | :exclamation: | | 98 | | 011 | [Accessibility On The Web][011] | :exclamation: | | 99 | | 010 | [ReactJS and the Flux architecture][010] | :exclamation: | | 100 | | 009 | [Coding Securely In PHP][009] | :exclamation: | | 101 | | 008 | [Domain-Driven Design In PHP][008] | :exclamation: | | 102 | | 007 | [Git & Git-Flow - Open Source Part 1][007] | :exclamation: | | 103 | | 006 | [Faceoff: Taylor Otwell vs Phil Sturgeon][006] | :exclamation: | | 104 | | 005 | [PHP Internals - Past Present & Future][005] | :white_check_mark: | [Andy Huggins][@andy_huggins] | 105 | | 004 | [All About API's][004] | :white_check_mark: | [Andy Huggins][@andy_huggins] | 106 | | 003 | [A #WurstCon Special][003] | :exclamation: | | 107 | | 002 | [Functional Programming In PHP][002] | :white_check_mark: | [Sammy Kaye Powers][@SammyK] | 108 | | 001 | [The PHP Community, PHP CLI, & ElePHPants][001] | :white_check_mark: | [Sammy Kaye Powers][@SammyK] | 109 | 110 | [080]: https://www.phproundtable.com/episode/php-internals-preloading-ffi-typed-properties-and-more 111 | [079]: https://www.phproundtable.com/episode/general-data-protection-regulation-gdpr-for-php-devs 112 | [078]: https://www.phproundtable.com/episode/docblocks-annotations-psr-5-and-the-like 113 | [077]: https://www.phproundtable.com/episode/tech-interviews-for-self-taught-php-programmers 114 | [076]: https://www.phproundtable.com/episode/concurrency-generators-coroutines-oh-my 115 | [075]: https://www.phproundtable.com/episode/web-content-accessibility-guidelines-wcag-2-1 116 | [074]: https://www.phproundtable.com/episode/securely-managing-secrets-in-php 117 | [073]: https://www.phproundtable.com/episode/using-static-analyzers-to-improve-our-php-codebases 118 | [072]: https://www.phproundtable.com/episode/secret-project-revealed 119 | [071]: https://www.phproundtable.com/episode/extra-extra-php-72-released 120 | [070]: https://www.phproundtable.com/episode/all-things-wordpress 121 | [069]: https://www.phproundtable.com/episode/catching-up-with-php-friends 122 | [068]: https://www.phproundtable.com/episode/phps-dirty-little-segfault-secret-the-stack-bomb 123 | [067]: https://www.phproundtable.com/episode/imposter-syndrome-and-the-dunning-kruger-effect 124 | [066]: https://www.phproundtable.com/episode/my-transition-from-vagrant-to-docker 125 | [065]: https://www.phproundtable.com/episode/php-test-fest-2017 126 | [064]: https://www.phproundtable.com/episode/php-7-internals-scanning-parsing-ast-and-engine 127 | [063]: https://www.phproundtable.com/episode/a-php-tek-2017-special 128 | [062]: https://www.phproundtable.com/episode/all-things-laravel 129 | [061]: https://www.phproundtable.com/episode/dependency-injection-and-psr-11 130 | [060]: https://www.phproundtable.com/episode/logging-and-crash-reporting-in-php 131 | [059]: https://www.phproundtable.com/episode/php-7-1 132 | [058]: https://www.phproundtable.com/episode/httplug-guzzle-and-apis 133 | [057]: https://www.phproundtable.com/episode/all-things-zend-framework-apigility-certification 134 | [056]: https://www.phproundtable.com/episode/hourly-vs-value-based-pricing 135 | [055]: https://www.phproundtable.com/episode/acceptance-testing-with-behat 136 | [054]: https://www.phproundtable.com/episode/security-encryption-hashing-and-php 137 | [053]: https://www.phproundtable.com/episode/why-im-afraid-to-admit-im-a-php-programmer 138 | [052]: https://www.phproundtable.com/episode/behind-the-scenes-of-two-years-of-the-php-roundtable 139 | [051]: https://www.phproundtable.com/episode/what-happened-to-php-6 140 | [050]: https://www.phproundtable.com/episode/php-for-beginners 141 | [049]: https://www.phproundtable.com/episode/event-sourcing-in-php 142 | [048]: https://www.phproundtable.com/episode/docker-and-php 143 | [047]: https://www.phproundtable.com/episode/all-about-http2 144 | [046]: https://www.phproundtable.com/episode/character-encoding-and-utf-8-in-php 145 | [045]: https://www.phproundtable.com/episode/live-from-php-tek-2016 146 | [044]: https://www.phproundtable.com/episode/asynchronous-php 147 | [043]: https://www.phproundtable.com/episode/a-lone-star-php-2016-special 148 | [042]: https://www.phproundtable.com/episode/staying-relevant-in-an-ever-changing-web-development-world 149 | [041]: https://www.phproundtable.com/episode/the-php-framework-interop-group-past-present-future 150 | [040]: https://www.phproundtable.com/episode/using-graph-databases-in-php 151 | [039]: https://www.phproundtable.com/episode/part-2-turning-an-idea-into-code-for-production 152 | [038]: https://www.phproundtable.com/episode/proposed-features-of-php-71 153 | [037]: https://www.phproundtable.com/episode/orms-and-the-active-record-data-mapper-paradigms 154 | [036]: https://www.phproundtable.com/episode/discussions-from-room-11-on-stack-overflow 155 | [035]: https://www.phproundtable.com/episode/immutability-and-functional-concepts-in-php 156 | [034]: https://www.phproundtable.com/episode/debugging-is-more-than-var-dump 157 | [033]: https://www.phproundtable.com/episode/keeping-code-simple-in-a-design-pattern-world 158 | [032]: https://www.phproundtable.com/episode/running-a-rockin-php-user-group 159 | [031]: https://www.phproundtable.com/episode/checking-in-with-php-and-hhvm-internals 160 | [030]: https://www.phproundtable.com/episode/service-oriented-architecture-and-microservices 161 | [029]: https://www.phproundtable.com/episode/being-a-woman-in-the-php-community 162 | [028]: https://www.phproundtable.com/episode/the-alcoholic-and-unfit-php-culture 163 | [027]: https://www.phproundtable.com/episode/a-2015-laracon-us-special 164 | [026]: https://www.phproundtable.com/episode/documentation-and-developer-experience 165 | [025]: https://www.phproundtable.com/episode/php7-release-management 166 | [024]: https://www.phproundtable.com/episode/how-to-become-a-php-entrepreneur 167 | [023]: https://www.phproundtable.com/episode/how-the-bus-factor-may-negatively-impact-the-php-ecosystem 168 | [022]: https://www.phproundtable.com/episode/psr-7-streams-immutability-middleware-oh-my 169 | [021]: https://www.phproundtable.com/episode/part-1-turning-an-idea-into-code-for-production 170 | [020]: https://www.phproundtable.com/episode/a-loosely-coupled-mashup-phptek-2015 171 | [019]: https://www.phproundtable.com/episode/the-business-side-of-php-clients-customer-service-pricing-oh-my 172 | [018]: https://www.phproundtable.com/episode/f8-2015-facebook-developer-conference-and-the-new-php-sdk 173 | [017]: https://www.phproundtable.com/episode/how-to-convert-a-legacy-codebase-to-modern-php 174 | [016]: https://www.phproundtable.com/episode/contributing-to-php-7-with-the-gophp7-ext-project 175 | [015]: https://www.phproundtable.com/episode/semver-licensing-os-support-expectations-open-source-series-part-2 176 | [014]: https://www.phproundtable.com/episode/a-2015-midwest-php-special 177 | [013]: https://www.phproundtable.com/episode/test-driven-development-and-behavior-driven-development-in-php 178 | [012]: https://www.phproundtable.com/episode/a-2015-sunshine-php-special 179 | [011]: https://www.phproundtable.com/episode/accessibility-on-the-web 180 | [010]: https://www.phproundtable.com/episode/implementing-reactjs-and-the-flux-application-architecture 181 | [009]: https://www.phproundtable.com/episode/coding-securely-in-php 182 | [008]: https://www.phproundtable.com/episode/domain-driven-design-in-php 183 | [007]: https://www.phproundtable.com/episode/open-source-series-part-1-git-git-flow 184 | [006]: https://www.phproundtable.com/episode/faceoff-taylor-otwell-vs-phil-sturgeon-debating-all-the-things 185 | [005]: https://www.phproundtable.com/episode/php-internals-past-present-future 186 | [004]: https://www.phproundtable.com/episode/all-about-web-apis-raml-oauth-hateoas 187 | [003]: https://www.phproundtable.com/episode/a-2014-wurstcon-special 188 | [002]: https://www.phproundtable.com/episode/functional-programming-non-blocking-asynchronous-event-driven-in-php 189 | [001]: https://www.phproundtable.com/episode/the-php-community-php-from-the-command-line-and-elephpants 190 | 191 | [@SammyK]: https://twitter.com/SammyK 192 | [@andy_huggins]: https://twitter.com/andy_huggins 193 | [@StevenMaguire]: https://twitter.com/StevenMaguire 194 | [@chris48s]: https://github.com/chris48s 195 | [@kenguest]: https://twitter.com/kenguest 196 | [@dominicbordelon]: https://twitter.com/dominicbordelon 197 | [@petekeller2]: https://twitter.com/petekeller2 198 | [@cwt137]: https://twitter.com/cwt137 199 | [@shane-smith]: https://github.com/shane-smith 200 | [@mattsches]: https://twitter.com/mattsches 201 | [@yatil]: https://twitter.com/yatil 202 | --------------------------------------------------------------------------------