colinodell.com - Blog
https://www.colinodell.com/
Blog posts from the desk of Colin O'DellenDIY "On Air" light automation for Google Meet
https://www.colinodell.com/blog/202207/diy-on-air-light-automation-google-meet-chrome-extension
<p>Like any good project, this one started with a problem: how do I let my wife know I'm in a meeting so she doesn't let the dog barge in? (I work remotely and my office is the only way to get to the backyard.)</p>
<p>The solution: <strong>build my own "On Air" light that turns on/off automatically when I'm in a meeting!</strong> Sure, there are commercially-available products that do exactly this, but where's the fun in buying something when I have the skills and equipment to build my own? Just how hard could it be? (famous last words)</p>
<h2>False Starts</h2>
<p>My first idea was to detect whether the camera or microphone was in use so my solution would work with any conferencing software. It turns out this isn't easy to do with MacOS. The closest I got was using <a href="https://github.com/antonfisher/go-media-devices-state">this Golang library</a> - it gives the correct state of the hardware at first, but <a href="https://github.com/antonfisher/go-media-devices-state/issues/2">subsequent checks within the same process fail to detect state changes</a>, and I don't know enough Objective C and MacOS API internals to figure out the solution.</p>
<p>So ultimately I gave up on that approach and settled on a more naive solution - create a Chrome extension that detects whether a meeting is active. Sounds easy enough, right? Extensions even have a nice feature allowing you to <a href="https://developer.chrome.com/docs/extensions/mv3/content_scripts/#static-declarative">run code whenever a page matches a certain URL pattern</a>! This works great for knowing that I'm in a meeting, but then how do I detect if I've left? <code>window.onunload</code> seems useful on the surface but isn't reliable enough. I also considered sending periodic <code>still-in-a-meeting</code> messages from the content script to the background script and waiting for a timeout to indicate that I've left, but that doesn't allow for instantaneous updates, and it also fails to reset the state if Chrome is closed before the timeout occurs.</p>
<h2>A Solution Appears!</h2>
<p>I ultimately settled on using just a <a href="https://developer.chrome.com/docs/extensions/mv3/service_workers/">service worker in a Chrome extension</a> to listen to tab state changes. Any time a tab is opened, removed, or navigates to a new URL, I check whether any tab contains a URL that looks like an active Google Meet; for example:</p>
<ul><li>
<code>https://meet.google.com/xxx-xxxx-xxx</code>
</li>
<li>
<code>https://meet.google.com/_meet/xxx-xxxx-xxx</code>
</li>
</ul><p>The logic ends up being really simple:</p>
<pre><code class="language-js">const tabs = await chrome.tabs.query({
url: "https://meet.google.com/*-*-*",
});
const isInMeeting = tabs.length > 0;
</code></pre>
<p>I then check it against the previous state (to avoid sending redundant "not-in-a-meeting" messages when I'm opening/closing/navigating other non-Meet tabs). The last step was building out a configuration page to tell the extension how to update this state in Home Assistant:</p>
<p><img alt="extension" src="/sites/default/files/inline-images/screenshot.png" /></p>
<p>And then created a virtual toggle switch in Home Assistant that my extension could toggle remotely:</p>
<p><img alt="Input boolean entity" src="/sites/default/files/inline-images/2022-06-19_15-21.png" /></p>
<p>And that's it! I now had <a href="https://github.com/colinodell/google-meet-hass-extension">a working Chrome extension</a> that would detect my meeting presence and allow me to automate based on this in Home Assistant.</p>
<h2>The Light</h2>
<p>I briefly considered building a true "On Air" light <a href="https://learn.adafruit.com/3d-printed-iot-on-air-sign-for-twitch?embeds=allow">like this one</a> but decided against it because 3D prints take forever. I ended up flashing my previously-built (and unused) <a href="https://learn.adafruit.com/feather-weather-lamp">Weather Lamp</a> with <a href="https://www.home-assistant.io/integrations/wled/">WLED</a> so I could control it via Home Assistant.</p>
<p>Once I had both the extension data and WLED connected in Home Assistant, it was just a matter of creating an automation between the two!</p>
<img alt="Node-RED flow" src="/sites/default/files/inline-images/2022-06-19_15-17.png" /><p>(I used Node-RED for this, but HA's built-in automation system would work just fine.)</p>
<p>And here's the final result! When I'm not in a meeting, the light is green:</p>
<p><img class="img-responsive" alt="Green light" src="/sites/default/files/inline-images/PXL_20220619_183535553.jpg" /></p>
<p>And it turns red when I'm in a meeting:</p>
<p><img class="img-responsive" alt="Red light" src="/sites/default/files/inline-images/PXL_20220619_183603671.jpg" /></p>
<p>(I mounted this down low simply because it was closer to the outlet in the closet and would minimize the length of exposed USB cable)</p>
<p>And after documenting this project I later made a few tweaks:</p>
<ol><li>Animated the red in-meeting state to flash and spin the LEDs</li>
<li>Improved the automation to turn the light off when I'm not in the office</li>
<li>Rewrote the extension using Typescript, React, and async/await to practice my burgeoning frontend skills</li>
</ol><h2>Build Your Own!</h2>
<p>You can build your own DIY "On Air" light using the same basic building blocks like <a href="https://github.com/colinodell/google-meet-hass-extension">the Chrome extension</a>, tweaking them as needed.</p>
<p>For example, you can build or use any type of light you want - just integrate it with Home Assistant! Or you could fork my extension and add support for some other type of meeting software. The nice thing about DIY open-source solutions is the ability to customize it to fit your needs exactly!</p>Sat, 02 Jul 2022 21:57:31 -0400Colin O'Dellhttps://www.colinodell.com/blog/202207/diy-on-air-light-automation-google-meet-chrome-extensionleague/commonmark 2.0.0 Released!
https://www.colinodell.com/blog/202107/league-commonmark-2-0-0-released
<p>After 96 releases, 368 pull requests, and over 48 million downloads, I'm pleased to share that the next major version of <strong><a href="https://github.com/thephpleague/commonmark/releases/tag/2.0.0">league/commonmark 2.0.0 stable</a> is now generally available! 🎉🎉</strong></p>
<p>You can install the latest version via Composer:</p>
<pre><code class="language-bash">composer require league/commonmark:^2.0
</code></pre>
<h3>What's new in 2.0?</h3>
<p>There's so much to cover, but here are the key improvements and changes:</p>
<ul><li>
<strong>Up to <a href="https://www.reddit.com/r/PHP/comments/o912bi/leaguecommonmark_200beta2_now_available_for/h38wg15/">50% faster and 21% less memory usage</a></strong>, especially when dealing with larger Markdown documents</li>
<li>
<strong>Three new extensions</strong> for <a href="https://commonmark.thephpleague.com/extensions/front-matter/">Front Matter</a>, <a href="https://commonmark.thephpleague.com/extensions/description-lists/">Description Lists</a>, and <a href="https://commonmark.thephpleague.com/extensions/default-attributes/">Default HTML Attributes</a>
</li>
<li>A new <strong><a href="https://commonmark.thephpleague.com/xml/">XML renderer</a></strong> to simplify AST debugging</li>
<li>Completely revamped parsing engine for <strong>faster speed and more precise parsing control</strong> (for blocks, inlines, and delimiters)</li>
<li>A unified rendering approach for both blocks and inlines</li>
<li>Compatibility with PSR-14 event dispatcher libraries</li>
<li>Psalm purity markers throughout the codebase</li>
<li>Minimal BC-breaks for most users</li>
<li>Tons more!</li>
</ul><h3>Upgrading from 1.x</h3>
<p>The upgrade process will vary based on whether you have custom functionality or are simply using the library as-is. I've therefore split <a href="https://commonmark.thephpleague.com/2.0/upgrading/">the upgrading guide</a> into three parts to help you understand the changes that impact you:</p>
<ul><li>
<strong><a href="https://commonmark.thephpleague.com/2.0/upgrading/consumers/">For Consumers</a></strong> - you use the library as-is and maybe even enable some additional extensions</li>
<li>
<strong><a href="https://commonmark.thephpleague.com/2.0/upgrading/integrators/">For Integrators</a></strong> - you maintain an integration between this library and something else, like a CMS or framework</li>
<li>
<strong><a href="https://commonmark.thephpleague.com/2.0/upgrading/developers/">For Developers</a></strong> - you write custom extensions and like to tinker under-the-hood</li>
</ul><h3>The Future of 1.x</h3>
<p>Per <a href="https://github.com/thephpleague/commonmark#%EF%B8%8F-maintenance--support">the usual policies</a>, the 1.6 branch will continue to receive bug fixes for <em>at least</em> 3 months and security updates for 6 months, if not longer, depending on the severity of any issues. No further minor releases (like 1.7.0) will be made, meaning that <strong>all new features and spec compliance updates will only be added to 2.0 and higher</strong>. You are therefore <strong>strongly encouraged to upgrade</strong> to the new version if/when you can.</p>
<p>If for any reason you can't upgrade immediately, that's alright - 1.6 is very stable and should work just fine until you're able to upgrade. And of course, if you're stuck on an older version of PHP you can keep using 1.6 too.</p>
<p>If you're using Laravel, note that <a href="https://github.com/laravel/framework/pull/37953">support for league/commonmark v1 is being dropped in Larvel 9</a>. Other frameworks and integrations will also like drop 1.x support from <strong>new major releases</strong> over the rest of this year.</p>
<h3>Roadmap for 2.1 and 3.0</h3>
<p>You didn't think development was over now that 2.0.0 is released, did you? We're already planning some exciting new features for future versions:</p>
<h4><a href="https://github.com/thephpleague/commonmark/milestone/20">Coming in 2.1</a></h4>
<ul><li>
<a href="https://github.com/thephpleague/commonmark/issues/421">An Emoji extension!</a>
</li>
<li>
<a href="https://github.com/thephpleague/commonmark/issues/674">A thorough review of all regular expressions to help boost performance further</a>
</li>
</ul><h4><a href="https://github.com/thephpleague/commonmark/milestone/19">Coming in 3.0</a></h4>
<ul><li>Two-way conversion from Markdown/HTML/XML to Markdown/HTML/XML, including <a href="https://github.com/thephpleague/commonmark/issues/419">pretty-printing Markdown</a>
</li>
<li>
<a href="https://github.com/thephpleague/commonmark/issues/511">The ability to programmatically toggle task list items and save the updated Markdown</a>
</li>
</ul><p><em>(The features above are subject to change)</em></p>
<h3>Thank You</h3>
<p>I owe a huge debt of thanks to everyone who helped make this possible, including (in no particular order):</p>
<ul><li>Every developer who has installed, used, shared, or <a href="https://github.com/thephpleague/commonmark/graphs/contributors">contributed</a> to this project</li>
<li>Everyone in the PHP League for their mentorship and assistance over the years</li>
<li>John MacFarlane, GitHub, Atlassian, and others for working on the CommonMark spec, GFM spec, and reference parsers that this project is based on</li>
<li>Everyone who sponsors my open-source welcome, especially <a href="https://github.com/sponsors/colinodell">Geoff Thompson, Taylor Otwell, Dan Brown, Josh Bruce, and Spatie</a>
</li>
<li>The entire PHP community</li>
</ul>Sat, 24 Jul 2021 13:33:06 -0400Colin O'Dellhttps://www.colinodell.com/blog/202107/league-commonmark-2-0-0-releasedAuto-Updating Twitter Banners
https://www.colinodell.com/blog/202107/autoupdating-twitter-banners
<p>If you <a href="https://twitter.com/colinodell">follow me on Twitter</a> you might have noticed a fancy new banner image:</p>
<p><a href="https://twitter.com/colinodell"><img class="img-thumbnail img-responsive" alt="Auto-generated Twitter banner image" src="/sites/default/files/inline-images/Selection-2021-07-03-09%3A18%3A29.png" /></a></p>
<p>This is powered by <a href="https://github.com/erikaheidi/dynacover"><strong>dynacover</strong></a> - a really nifty tool created by <a href="https://twitter.com/erikaheidi">Erika Heidi</a> that automagically generates and uploads dynamic Twitter banner images! I'm running a slightly modified instance with a custom template that updates every 10 minutes via cron. Currently, my banner is showing my recent Twitter followers as well as my GitHub sponsors, though I'm thinking of some other interesting things I can pull into it in the near future.</p>
<h2>Try it out</h2>
<p>Want to see it in action by having your avatar appear in my banner?</p>
<ol><li>
<a href="https://twitter.com/colinodell">Follow me on Twitter</a> or <a href="https://github.com/sponsors/colinodell">sponsor me on GitHub</a>
</li>
<li>Wait up to 10 minutes</li>
<li>Reload my Twitter profile and see yourself in my banner!</li>
</ol><p>A huge thanks to Erika for releasing this awesome project!</p>Sat, 03 Jul 2021 09:17:44 -0400Colin O'Dellhttps://www.colinodell.com/blog/202107/autoupdating-twitter-bannersFollow me on Polywork
https://www.colinodell.com/blog/202107/follow-me-on-polywork
<p>If you <a href="https://twitter.com/colinodell">follow me on Twitter</a> you've probably seen that I've recently joined <a href="https://www.polywork.com/">Polywork</a> - a new social network unlike any others.</p>
<p>Polywork has a unique concept - instead of focusing on just your personal or professional life, your profile focuses on highlighting you as a multi-faceted individual. There's no commenting, no competing for likes, no recruiters, no politics - just you and your story:</p>
<p><a href="https://www.polywork.com/colinodell"><img class="img img-thumbnail img-responsive" alt="Polywork Screenshot" src="/sites/default/files/inline-images/screencapture-polywork-colinodell-2021-07-02-17_44_55.jpg" /></a></p>
<p>I love how it presents <a href="https://www.polywork.com/colinodell">my profile</a> as a multi-faceted story with a timeline showing my personal growth and evolution over time. I've been busy adding different role changes, open-source releases, conference engagements, and more to my timeline. (Although no automated import tools exist yet, I've heard they're working on some features, so fingers-crossed we'll get things like RSS feed imports soon!)</p>
<p>The platform is still invite-only, but they've graciously provided me with <strong>50 VIP invite codes to share</strong> so you can join too! To join, simply:</p>
<ol><li>Visit https://www.polywork.com/users/sign_up_vip to create your account</li>
<li>Enter code <strong><code>colinodell</code></strong> when prompted</li>
<li>
<a href="https://www.polywork.com/colinodell">Follow me</a> once you're on and I'll follow you back 😉</li>
</ol><p>See you there!</p>
<p><em>(And no, this is not a paid advertisement - I've genuinely enjoyed exploring the platform and wanted to share it with everyone!)</em></p>Fri, 02 Jul 2021 17:37:17 -0400Colin O'Dellhttps://www.colinodell.com/blog/202107/follow-me-on-polyworkleague/commonmark 2.0.0-beta2 now available for testing
https://www.colinodell.com/blog/202106/leaguecommonmark-200beta2-now-available-testing
<p>With the 2.0.0 stable release of <a href="https://github.com/thephpleague/commonmark"><code>league/commonmark</code></a> scheduled for <a href="https://github.com/thephpleague/commonmark/milestone/15">next month</a>, <strong>I'm pleased to share that <a href="https://github.com/thephpleague/commonmark/releases">the first 2.0 beta releases are now available</a>!</strong> Current users of this library are highly encouraged to test this new branch and provide feedback.</p>
<p>You can install the beta release via Composer:</p>
<pre><code class="language-bash">composer require league/commonmark:^2.0@beta
</code></pre>
<h3>What's new in 2.0?</h3>
<p>There's so much to cover - I'll likely need to write a separate blog post about that. But here are the key improvements and changes:</p>
<ul><li>
<strong>Up to 50% faster and 21% less memory usage</strong>, especially when dealing with larger Markdown documents</li>
<li>
<strong>Three new extensions</strong> for <a href="https://commonmark.thephpleague.com/extensions/front-matter/">Front Matter</a>, <a href="https://commonmark.thephpleague.com/extensions/description-lists/">Description Lists</a>, and <a href="https://commonmark.thephpleague.com/extensions/default-attributes/">Default HTML Attributes</a>
</li>
<li>A new <strong><a href="https://commonmark.thephpleague.com/xml/">XML renderer</a></strong> to simplify AST debugging</li>
<li>Completely revamped parsing engine for faster speed and more precise parsing control (for blocks, inlines, and delimiters)</li>
<li>A unified rendering approach for both blocks and inlines</li>
<li>Compatibility with PSR-14 event dispatcher libraries</li>
<li>Psalm purity markers throughout the codebase</li>
<li>Tons more!</li>
</ul><p>I'll share more details on this, including the new benchmarks, closer to the 2.0.0 stable release. In the meantime, I'd highly recommend reviewing the <a href="https://commonmark.thephpleague.com/2.0/upgrading/">upgrading guide</a> and <a href="https://github.com/thephpleague/commonmark/blob/main/CHANGELOG.md"><code>CHANGELOG</code></a> for additional details on what's changed and how you can start testing 2.0 today.</p>
<p>This is going to be the most exciting release and I can't wait to share it with all of you!</p>
<p><em>Correction: A previous revision of this post claimed "up to 70%" performance improvement. I divided by the wrong number - it's actually 50%.</em></p>Sun, 27 Jun 2021 12:30:54 -0400Colin O'Dellhttps://www.colinodell.com/blog/202106/leaguecommonmark-200beta2-now-available-testingFixing Broken Squad Chat Audio Issues in Battlefield V
https://www.colinodell.com/blog/202106/fixing-broken-squad-chat-audio-issues-battlefield-v
<p class="alert alert-info">I know this isn't a normal topic for this blog, but after helping a fellow player on a private Battlefield 5 forum I wanted to share the fix with the broader internet.</p>
<p>Basically, if you have any of these in-game issues with in-squad VoIP:</p>
<ul><li>No sound at all</li>
<li>Lots of static</li>
<li>Low volume</li>
<li>Sound coming from the wrong speakers</li>
</ul><p>There's a strong chance the issue is that your <strong>default communications device</strong> is not set to the right device in Windows' audio settings:</p>
<p><img alt="Windows sound settings" class="img-responsive" src="/sites/default/files/inline-images/windows-audio-settings.png" /></p>
<p>I can't guarantee this will fix all squad chat problems in BF5, but hopefully it helps you 😉</p>
<p><em>(<a href="https://unsplash.com/photos/EHLd2utEf68">Teaser image from Unsplash</a>)</em></p>Sun, 13 Jun 2021 19:27:15 -0400Colin O'Dellhttps://www.colinodell.com/blog/202106/fixing-broken-squad-chat-audio-issues-battlefield-vleague/commonmark 1.6.0 Released!
https://www.colinodell.com/blog/202105/leaguecommonmark-160-released
<p><strong>I'm excited to share that <a href="https://github.com/thephpleague/commonmark/releases/tag/1.6.0">version 1.6.0 of league/commonmark has been released</a>!</strong> This will be the last minor release of the 1.x branch - all efforts will now be focused on wrapping up development of 2.0.0!</p>
<p>Please see <a href="https://commonmark.thephpleague.com/1.6/upgrading/">https://commonmark.thephpleague.com/1.6/upgrading/</a> for important information about this release and the upcoming 2.0.0 version.</p>
<p>If you'd like to help fund development of this library, please check out <a href="https://www.colinodell.com/sponsor">my Sponsor page</a>. We also have some <a href="https://www.moderngeekware.com/search?q=markdown">Markdown t-shirts and mugs</a> on <a href="https://www.moderngeekware.com/">ModernGeekware.com</a>:</p>
<div class="row">
<div class="col-sm-6">
<a href="https://www.moderngeekware.com/products/markdown-logo-premium-unisex-t-shirt" title="Markdown t-shirt"><img class="img-responsive" src="https://cdn.shopify.com/s/files/1/0537/0101/7793/products/unisex-premium-t-shirt-dark-grey-heather-5ffbd1a5b89da_1024x1024@2x.jpg?v=1612041225" /></a>
</div>
<div class="col-sm-6">
<a href="https://www.moderngeekware.com/products/markdown-mug" title="Markdown mug"><img class="img-responsive" src="https://cdn.shopify.com/s/files/1/0537/0101/7793/products/11-oz-mug-mockup-featuring-a-man-drinking-coffee-while-working-from-home-43554-r-el2_1024x1024@2x.png?v=1612041270" /></a>
</div>
</div>
<p>All proceeds go towards helping with the development and maintenance of this library.</p>
<p>Hope you enjoy this new release and I look forward to releasing 2.0.0 very soon. Cheers!</p>Sat, 01 May 2021 15:24:28 -0400Colin O'Dellhttps://www.colinodell.com/blog/202105/leaguecommonmark-160-releasedPHP 8.1 is Getting Enumerations!
https://www.colinodell.com/blog/202102/php-81-getting-enumerations
<p>The <a href="https://wiki.php.net/rfc/enumerations">PHP RFC for enumerations</a> just passed a 44-7 vote to be accepted as a new feature in the upcoming PHP 8.1 release!</p>
<p>Enumerations, also known as "enums", are a special data type that can only contain specific, predefined (or "enumerated") values. They behave somewhat similar to constants, in that their names can be referenced in code, but they allow for stronger typing.</p>
<p>The classic use case illustrated by the RFC is of an enum that defines different suits of playing cards:</p>
<pre><code class="language-php">enum Suit {
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}
</code></pre>
<p>From the RFC:</p>
<blockquote>
<p>This declaration creates a new enumerated type named <code>Suit</code>, which has four and only four legal values: <code>Suit::Hearts</code>, <code>Suit::Diamonds</code>, <code>Suit::Clubs</code>, and <code>Suit::Spades</code>. Variables may be assigned to one of those legal values. A function may be type checked against an enumerated type, in which case only values of that type may be passed.</p>
</blockquote>
<pre><code class="language-php">function pick_a_card(Suit $suit) { ... }
$val = Suit::Diamonds;
pick_a_card($val); // OK
pick_a_card(Suit::Clubs); // OK
pick_a_card('Spades'); // TypeError: pick_a_card(): Argument #1 ($suit)
// must be of type Suit, string given
</code></pre>
<p>Enums can do more than just that - check out <a href="https://wiki.php.net/rfc/enumerations">the RFC</a> for a list of examples and capabilities.</p>
<p>I'm personally super excited about this feature and can't wait to start using them in my projects!</p>Wed, 17 Feb 2021 15:08:30 -0500Colin O'Dellhttps://www.colinodell.com/blog/202102/php-81-getting-enumerationsIntroducing ModernGeekware.com - Tees, Mugs, and more for Developers and Geeks
https://www.colinodell.com/blog/202101/introducing-moderngeekwarecom-tees-mugs-and-more-developers-and-geeks
<p>As a developer, I LOVE my geeky t-shirts and mugs, but it's hard to find quality products with designs I like. I've therefore been hard at work these last few weekends putting together my new project: <a href="https://www.moderngeekware.com">www.moderngeekware.com</a></p>
<p class="text-center"><a href="https://www.moderngeekware.com"><img alt="" class="img-thumbnail" data-entity-type="" data-entity-uuid="" src="https://www.colinodell.com/sites/default/files/styles/responsive/public/2021-01/Screenshot%202021-01-31%20130328.png?itok=tUmxsCFp" style="width: 85%" /></a></p>
<p><strong>I'm excited to share that <a href="https://www.moderngeekware.com/pages/promotions">ModernGeekware.com</a> just launched this Sunday!</strong> There are currently 28 products in the store and I hope to add more in the coming days and weeks. Everything here was designed by me mostly because they're all things I'd want to buy and wear myself. (In fact, I'm my own first customer!) I figured perhaps others might like them too, thus this store was born.</p>
<p>This is my first personal ecommerce site so I would really love to hear what you think about it! Do I have a good mix of products? Anything that I'm missing?</p>
<p>And if you see something you like, check out <a href="https://www.moderngeekware.com/pages/promotions">https://www.moderngeekware.com/pages/promotions</a> for a coupon code and a contest form to win anything from the store for free!</p>
Sun, 31 Jan 2021 14:38:46 -0500Colin O'Dellhttps://www.colinodell.com/blog/202101/introducing-moderngeekwarecom-tees-mugs-and-more-developers-and-geeksHow To Install PHP 8.0
https://www.colinodell.com/blog/202011/how-install-php-80
<p><a href="https://www.php.net/releases/8.0/en.php">PHP 8.0 has just been released</a>! This new major version adds several significant features and improvements to the language like <a href="https://www.php.net/releases/8.0/en.php#attributes">attributes</a>, <a href="https://www.php.net/manual/en/control-structures.match.php">match expressions</a>, <a href="https://wiki.php.net/rfc/jit">Just-In-Time compilation (JIT)</a>, and <a href="https://secure.php.net/manual/en/migration80.php">much more</a>!</p>
<p>Here's a brief guide on how to install PHP 8.0 on Linux, Windows, and Mac OS X:</p>
<h2>Ubuntu</h2>
<p>PHP 8.0 and commonly-used extensions can be installed by adding <a href="https://launchpad.net/~ondrej/+archive/ubuntu/php">Ondřej Surý's PPA</a>:</p>
<pre><code class="language-bash">sudo apt install -y software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
</code></pre>
<p>You can then install PHP 8.0 with all common extensions and SAPIs like so:</p>
<pre><code class="language-bash">sudo apt install php8.0
</code></pre>
<p>Or you can specify individual packages like this instead:</p>
<pre><code class="language-bash">sudo apt install php8.0-cli php8.0-fpm php8.0-bcmath php8.0-curl php8.0-gd php8.0-intl php8.0-mbstring php8.0-mysql php8.0-opcache php8.0-sqlite3 php8.0-xml php8.0-zip
</code></pre>
<p>This method is supported on:</p>
<ul><li>Ubuntu 16.04 (Xenial)</li>
<li>Ubuntu 18.04 (Bionic)</li>
<li>Ubuntu 20.01 (Focal)</li>
<li>Ubuntu 20.10 (Groovy)</li>
</ul><h2>Debian</h2>
<p><a href="https://packages.sury.org/php/">Ondřej Surý also provides PHP 8.0 packages</a> for Debian. Add the repository with these commands:</p>
<pre><code class="language-bash">sudo apt install -y apt-transport-https lsb-release ca-certificates wget
sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/php.list
sudo apt update
</code></pre>
<p>And then either install PHP 8.0 with all the defaults like this:</p>
<pre><code class="language-bash">sudo apt install php8.0
</code></pre>
<p>Or list the exact packages you want instead:</p>
<pre><code class="language-bash">sudo apt install php8.0-cli php8.0-fpm php8.0-bcmath php8.0-curl php8.0-gd php8.0-intl php8.0-mbstring php8.0-mysql php8.0-opcache php8.0-sqlite3 php8.0-xml php8.0-zip
</code></pre>
<p>This method is supported on:</p>
<ul><li>Debian 9 (Stretch)</li>
<li>Debian 10 (Buster)</li>
</ul><h2>CentOS / RHEL & Fedora</h2>
<p><a href="https://rpms.remirepo.net/">Remi's RPM repository</a> has RPMs for the latest PHP 8.0 builds.</p>
<p><strong>RHEL/Centos 8</strong> or <strong>Fedora modular</strong>:</p>
<pre><code class="language-bash">dnf module reset php
dnf module install php:remi-8.0
</code></pre>
<p><strong>RHEL/Centos 7</strong> or <strong>Fedora</strong>:</p>
<pre><code class="language-bash">yum-config-manager --enable remi-php80
yum update php\*
</code></pre>
<p>Or for <strong>parallel installation as a software collection</strong>, if you prefer to keep existing versions:</p>
<pre><code class="language-bash">yum install php80
</code></pre>
<p>Refer to <a href="https://blog.remirepo.net/post/2020/11/26/PHP-version-8.0.0-is-released">Remi's blog post</a> for additional information on how to install this depending on which OS version you're running.</p>
<h2>Mac OS X</h2>
<p>Shivam Mathur has a <a href="https://github.com/shivammathur/homebrew-php">Homebrew tap for easily installing PHP 8.0</a>:</p>
<pre><code class="language-bash"># Update homebrew
brew update
# Add the tap
brew tap shivammathur/php
# Install PHP 8.0
brew install shivammathur/php/[email protected]
</code></pre>
<h2>Windows</h2>
<p>Windows users can find the PHP 8.0 distributions on the <a href="https://windows.php.net/download">windows.php.net</a> website.</p>
<h2>Docker</h2>
<p><a href="https://hub.docker.com/_/php/">Official PHP images can be found on Docker Hub</a>.</p>
<p class="alert alert-warning">As of PHP 8.0's release date, the <code>php:8.0</code> image hasn't been tagged yet; once it is, you can use that for your base images.</p>
<p>Docker is also a great way to tinker with PHP 8.0 in a local interactive shell without installing it first! Simply run this in your terminal:</p>
<pre><code class="language-bash">docker run -it --rm php:8.0
</code></pre>Sat, 28 Nov 2020 08:19:05 -0500Colin O'Dellhttps://www.colinodell.com/blog/202011/how-install-php-80