mastodon.ie is one of the many independent Mastodon servers you can use to participate in the fediverse.
Irish Mastodon - run from Ireland, we welcome all who respect the community rules and members.

Administered by:

Server stats:

1.8K
active users

#php

64 posts55 participants10 posts today
OTX Bot<p>Delivering Trojans Via ClickFix Captcha</p><p>A new social engineering technique exploiting ClickFix Captcha has emerged as an effective method for delivering various types of malware, including Quakbot. This technique deceives users and bypasses security measures by utilizing a seemingly harmless captcha. The process involves redirecting users to a ClickFix captcha that tricks them into executing a malicious command on their local machine. The command downloads and executes obfuscated PowerShell scripts, which then retrieve and deploy the actual malware payload. The attackers use sophisticated obfuscation techniques, including fake ZIP files and PHP-based droppers, to evade detection and analysis. This method's success lies in exploiting user trust in captchas and legitimate-looking websites, increasing the likelihood of unknowing malware execution.</p><p>Pulse ID: 67ebfca624fc8265928a8775<br>Pulse Link: <a href="https://otx.alienvault.com/pulse/67ebfca624fc8265928a8775" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">otx.alienvault.com/pulse/67ebf</span><span class="invisible">ca624fc8265928a8775</span></a> <br>Pulse Author: AlienVault<br>Created: 2025-04-01 14:48:06</p><p>Be advised, this data is unverified and should be considered preliminary. Always do further verification.</p><p><a href="https://social.raytec.co/tags/CAPTCHA" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>CAPTCHA</span></a> <a href="https://social.raytec.co/tags/CyberSecurity" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>CyberSecurity</span></a> <a href="https://social.raytec.co/tags/InfoSec" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>InfoSec</span></a> <a href="https://social.raytec.co/tags/Mac" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Mac</span></a> <a href="https://social.raytec.co/tags/Malware" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Malware</span></a> <a href="https://social.raytec.co/tags/OTX" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>OTX</span></a> <a href="https://social.raytec.co/tags/OpenThreatExchange" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>OpenThreatExchange</span></a> <a href="https://social.raytec.co/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> <a href="https://social.raytec.co/tags/PowerShell" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PowerShell</span></a> <a href="https://social.raytec.co/tags/Rust" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Rust</span></a> <a href="https://social.raytec.co/tags/SocialEngineering" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>SocialEngineering</span></a> <a href="https://social.raytec.co/tags/Trojan" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Trojan</span></a> <a href="https://social.raytec.co/tags/ZIP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>ZIP</span></a> <a href="https://social.raytec.co/tags/bot" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>bot</span></a> <a href="https://social.raytec.co/tags/AlienVault" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>AlienVault</span></a></p>
Gina Peter Banyard<p><a href="https://floss.social/@servo/114263266479139385" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">floss.social/@servo/1142632664</span><span class="invisible">79139385</span></a> I don't have any stake in <span class="h-card" translate="no"><a href="https://floss.social/@servo" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>servo</span></a></span>, but I very much agree with <span class="h-card" translate="no"><a href="https://kolektiva.social/@delan" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>delan</span></a></span> against the use of AI.</p><p>Already having need to deal with multiple people using AI to comment on <a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> doc issues to just regurgitate nonsense that confuses the author or said issue by trying to be "helpful" is a recurring thing that wastes my time and makes me angry.</p>
Temma PHP Framework<p>Refactoring Challenge: Does your PHP code run multiple SQL queries inside a loop? Optimize it by fetching data in a single query. How would you improve it? </p><p><a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> <a href="https://phpc.social/tags/Refactoring" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Refactoring</span></a></p>
Ben Ramsey<p>In my public PHP libraries, I've taken to using `strspn()` to determine whether a string has allowed characters, e.g.:</p><p>```<br>strspn($string, CHARS) === strlen($string)<br>```</p><p>I can't remember why I started doing this, and I haven't run the benchmarks, but this might be more performant than using regular expressions. Does anyone already know if that's the case?</p><p>There's no `mb_strspn()`, so what would you use if you were trying to avoid regex and needed to match multibyte characters.</p><p><a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a></p>
Andrew Mark McCall<p>anyone got any job leads for 3-5 years professional experience with Javascript, react, Golang, PHP, Docker? <a href="https://indieweb.social/tags/fedihire" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>fedihire</span></a> <a href="https://indieweb.social/tags/getfedihired" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>getfedihired</span></a> <a href="https://indieweb.social/tags/javascript" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>javascript</span></a> <a href="https://indieweb.social/tags/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>php</span></a> <a href="https://indieweb.social/tags/react" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>react</span></a> <a href="https://indieweb.social/tags/golang" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>golang</span></a> <a href="https://indieweb.social/tags/docker" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>docker</span></a></p>
Tideways<p>We’re happy to be here 👋 </p><p>As <a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> and <a href="https://phpc.social/tags/performance" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>performance</span></a> are not only our favorite pass-time but also our profession at Tideways, we look forward to talking performance with you.</p><p>We are contributors to <span class="h-card" translate="no"><a href="https://phpc.social/@thephpf" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>thephpf</span></a></span> and to PHP core.</p><p>So, let’s dive deep into performance-related topics, share insights and discuss pet peeves!</p><p>Check out our blog for more technical articles: <a href="https://tideways.com/profiler/blog" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="">tideways.com/profiler/blog</span><span class="invisible"></span></a></p>
Larry Garfield<p>When should you use <a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> Enums, and when shouldn't you?</p><p><a href="https://peakd.com/hive-168588/@crell/on-the-use-of-enums" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">peakd.com/hive-168588/@crell/o</span><span class="invisible">n-the-use-of-enums</span></a></p>
MelHamnavoe<p>Transform your lunch break into a fun learning experience with this month’s <span class="h-card" translate="no"><a href="https://phparch.social/@phparch" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>phparch</span></a></span> issue.<br><span class="h-card" translate="no"><a href="https://phpc.social/@dragonmantank" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dragonmantank</span></a></span> article on class design is my lesson for today. <a href="https://phpc.social/tags/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>php</span></a> </p><p><a href="https://www.phparch.com/magazine/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://www.</span><span class="">phparch.com/magazine/</span><span class="invisible"></span></a></p>
David Bisset<p>"PHP is now the best choice for web based software".</p><p>I would say "ONE of the best" (depends). Not that I took the "Yo <a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> is dead" remarks in the past seriously (outside of a moment when Ruby on Rails was hot). But reminders never hurt.</p><p><a href="https://www.vincentschmalbach.com/php-is-now-the-best-choice-for-web-based-software/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://www.</span><span class="ellipsis">vincentschmalbach.com/php-is-n</span><span class="invisible">ow-the-best-choice-for-web-based-software/</span></a> <a href="https://phpc.social/tags/Laravel" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Laravel</span></a></p>
Rémi Eismann<p>One day, one decomposition<br>A214423: Numbers n palindromic in only one base b, 2 &lt;= b &lt;= 10</p><p>3D graph, threejs - webGL ➡️ <a href="https://decompwlj.com/3Dgraph/A214423.html" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">decompwlj.com/3Dgraph/A214423.</span><span class="invisible">html</span></a><br>2D graph, first 500 terms ➡️ <a href="https://decompwlj.com/2Dgraph500terms/A214423.html" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">decompwlj.com/2Dgraph500terms/</span><span class="invisible">A214423.html</span></a></p><p><a href="https://mathstodon.xyz/tags/decompwlj" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>decompwlj</span></a> <a href="https://mathstodon.xyz/tags/math" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>math</span></a> <a href="https://mathstodon.xyz/tags/mathematics" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>mathematics</span></a> <a href="https://mathstodon.xyz/tags/sequence" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>sequence</span></a> <a href="https://mathstodon.xyz/tags/OEIS" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>OEIS</span></a> <a href="https://mathstodon.xyz/tags/javascript" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>javascript</span></a> <a href="https://mathstodon.xyz/tags/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>php</span></a> <a href="https://mathstodon.xyz/tags/3D" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>3D</span></a> <a href="https://mathstodon.xyz/tags/numbers" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>numbers</span></a> <a href="https://mathstodon.xyz/tags/palindromic" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>palindromic</span></a> <a href="https://mathstodon.xyz/tags/base" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>base</span></a> <a href="https://mathstodon.xyz/tags/graph" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>graph</span></a> <a href="https://mathstodon.xyz/tags/threejs" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>threejs</span></a> <a href="https://mathstodon.xyz/tags/webGL" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>webGL</span></a></p>
Symfony Station 🇺🇦🇨🇦🇬🇱<p>The PHP Foundation: Impact and Transparency Report 2024. <a href="https://drupal.community/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a><br><a href="https://thephp.foundation/blog/2025/03/31/transparency-and-impact-report-2024/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">thephp.foundation/blog/2025/03</span><span class="invisible">/31/transparency-and-impact-report-2024/</span></a></p>
Reuben Walker aka mobileatom<p>The PHP Foundation: Impact and Transparency Report 2024. <a href="https://flipboard.com/tag/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a></p><p><a href="https://thephp.foundation/blog/2025/03/31/transparency-and-impact-report-2024/?utm_source=flipboard&amp;utm_medium=activitypub" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">thephp.foundation/blog/2025/03</span><span class="invisible">/31/transparency-and-impact-report-2024/?utm_source=flipboard&amp;utm_medium=activitypub </span></a></p><p>Posted into SYMFONY FOR THE DEVIL <span class="h-card" translate="no"><a href="https://flipboard.com/@mobileatom/symfony-for-the-devil-allupr6jz" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>symfony-for-the-devil-mobileatom</span></a></span></p>
Ben Ramsey<p><span class="h-card" translate="no"><a href="https://mstdn.plus/@umpiredb" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>umpiredb</span></a></span> Have you tried using PDO instead? It throws exceptions on errors and returns better values when the result set is empty.</p><p><a href="https://phpc.social/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a></p>
Umpire DB<p><a href="https://mstdn.plus/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> operations on <a href="https://mstdn.plus/tags/mysqli" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>mysqli</span></a> are a treat. They return either the expected object, or a true/false boolean. <br> <br>Connection fails? Boolean. Succeeds? Connection object. Preparing an <a href="https://mstdn.plus/tags/SQL" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>SQL</span></a> statement fails? Boolean. Succeeds? Statement object. Binding parameters to prepared statement fails? Boolean. Succeeds? Boolean. Executing the statement fails? Boolean. Succeeds? Boolean as well, or an associative array, depending on intent. <br> <br>And thanks.</p>
Davey Shafik 🦁🐉🏳️‍🌈<p>In case you missed it earlier today, I'm excited to share the first video preview of Beacon, a Feature Flag Management Platform for <a href="https://phpc.social/tags/Laravel" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Laravel</span></a>. Beacon provides a central place for managing Pennant feature flag configurations across all of your Laravel apps</p><p>Watch now: <a href="https://youtu.be/0yTkINxeUY4" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="">youtu.be/0yTkINxeUY4</span><span class="invisible"></span></a></p><p><a href="https://phpc.social/tags/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>php</span></a></p>
anubis2814For 2 years I was self teaching <a href="https://friendica.myportal.social/search?tag=PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a> for a fediverse helping project, now I've switched to <a href="https://friendica.myportal.social/search?tag=python" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>python</span></a> and I'm actually finding it temporarily almost harder because I don't realize that python does certain things automatically and requires no effort so when I look up how to do something I have problems finding it because its just a given lol
Davey Shafik 🦁🐉🏳️‍🌈<p>Today, I'm excited to share the first video preview of Beacon, a Feature Flag Management Platform for <a href="https://phpc.social/tags/Laravel" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>Laravel</span></a>. Built on top of Laravel Pennant, Beacon provides a central place for managing feature flag configs across all of your Laravel apps &amp; environments.</p><p>Watch now: <a href="https://youtu.be/0yTkINxeUY4" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="">youtu.be/0yTkINxeUY4</span><span class="invisible"></span></a></p><p><a href="https://phpc.social/tags/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>php</span></a></p>
Symfony Station 🇺🇦🇨🇦🇬🇱<p>Écrire un routeur sans framework, en PHP natif. <a href="https://drupal.community/tags/PHP" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a><br><a href="https://developpeur-freelance.io/routeur-php-natif/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">developpeur-freelance.io/route</span><span class="invisible">ur-php-natif/</span></a></p>
Reuben Walker aka mobileatom<p>Écrire un routeur sans framework, en PHP natif. <a href="https://flipboard.com/tag/php" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>PHP</span></a></p><p><a href="https://developpeur-freelance.io/routeur-php-natif/?utm_source=flipboard&amp;utm_medium=activitypub" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">developpeur-freelance.io/route</span><span class="invisible">ur-php-natif/?utm_source=flipboard&amp;utm_medium=activitypub </span></a></p><p>Publié dans SYMFONY FOR THE DEVIL <span class="h-card" translate="no"><a href="https://flipboard.com/@mobileatom/symfony-for-the-devil-allupr6jz" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>symfony-for-the-devil-mobileatom</span></a></span></p>
Terence Eden’s Blog<p><strong>Pretty Print HTML using PHP 8.4's new HTML DOM</strong></p><p><a href="https://shkspr.mobi/blog/2025/03/pretty-print-html-using-php-8-4s-new-html-dom/" rel="nofollow noopener noreferrer" translate="no" target="_blank"><span class="invisible">https://</span><span class="ellipsis">shkspr.mobi/blog/2025/03/prett</span><span class="invisible">y-print-html-using-php-8-4s-new-html-dom/</span></a></p><p>Those whom the gods would send mad, they first teach recursion.</p><p>PHP 8.4 introduces a new <a href="https://www.php.net/manual/en/class.dom-htmldocument.php" rel="nofollow noopener noreferrer" target="_blank">Dom\HTMLDocument class</a> it is a modern HTML5 replacement for the ageing XHTML based DOMDocument. You can <a href="https://wiki.php.net/rfc/domdocument_html5_parser" rel="nofollow noopener noreferrer" target="_blank">read more about how it works</a> - the short version is that it reads and correctly sanitises HTML and turns it into a nested object. Hurrah!</p><p>The one thing it <em>doesn't</em> do is pretty-printing. When you call <code>$dom-&gt;saveHTML()</code> it will output something like:</p><pre><code>&lt;html lang="en-GB"&gt;&lt;head&gt;&lt;title&gt;Test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;Testing&lt;/h1&gt;&lt;main&gt;&lt;p&gt;Some &lt;em&gt;HTML&lt;/em&gt; and an &lt;img src="example.png"&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;List&lt;/li&gt;&lt;li&gt;Another list&lt;/li&gt;&lt;/ol&gt;&lt;/main&gt;&lt;/body&gt;&lt;/html&gt;</code></pre><p>Perfect for a computer to read, but slightly tricky for humans.</p><p>As was <a href="https://libraries.mit.edu/150books/2011/05/11/1985/" rel="nofollow noopener noreferrer" target="_blank">written by the sages</a>:</p><blockquote><p>A computer language is not just a way of getting a computer to perform operations but rather … it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.</p></blockquote><p>HTML <em>is</em> a programming language. Making markup easy to read for humans is a fine and noble goal. The aim is to turn the single line above into something like:</p><pre><code>&lt;html lang="en-GB"&gt; &lt;head&gt; &lt;title&gt;Test&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;h1&gt;Testing&lt;/h1&gt; &lt;main&gt; &lt;p&gt;Some &lt;em&gt;HTML&lt;/em&gt; and an &lt;img src="example.png"&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;List&lt;/li&gt; &lt;li&gt;Another list&lt;/li&gt; &lt;/ol&gt; &lt;/main&gt; &lt;/body&gt;&lt;/html&gt;</code></pre><p>Cor! That's much better!</p><p>I've cobbled together a script which is <em>broadly</em> accurate. There are a million-and-one edge cases and about twice as many personal preferences. This aims to be quick, simple, and basically fine. I am indebted to <a href="https://topic.alibabacloud.com/a/php-domdocument-recursive-formatting-of-indented-html-documents_4_86_30953142.html" rel="nofollow noopener noreferrer" target="_blank">this random Chinese script</a> and to <a href="https://github.com/wasinger/html-pretty-min" rel="nofollow noopener noreferrer" target="_blank">html-pretty-min</a>.</p><p><strong>Step By Step</strong></p><p>I'm going to walk through how everything works. This is as much for my benefit as for yours! This is beta code. It sorta-kinda-works for me. Think of it as a first pass at an attempt to prove that something can be done. Please don't use it in production!</p><p><strong>Setting up the DOM</strong></p><p>The new HTMLDocument should be broadly familiar to anyone who has used the previous one.</p><pre><code>$html = '&lt;html lang="en-GB"&gt;&lt;head&gt;&lt;title&gt;Test&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;Testing&lt;/h1&gt;&lt;main&gt;&lt;p&gt;Some &lt;em&gt;HTML&lt;/em&gt; and an &lt;img src="example.png"&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;List&lt;li&gt;Another list&lt;/body&gt;&lt;/html&gt;'$dom = Dom\HTMLDocument::createFromString( $html, LIBXML_NOERROR, "UTF-8" );</code></pre><p>This automatically adds <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code> elements. If you don't want that, use the <a href="https://www.php.net/manual/en/libxml.constants.php#constant.libxml-html-noimplied" rel="nofollow noopener noreferrer" target="_blank"><code>LIBXML_HTML_NOIMPLIED</code> flag</a>:</p><pre><code>$dom = Dom\HTMLDocument::createFromString( $html, LIBXML_NOERROR | LIBXML_HTML_NOIMPLIED, "UTF-8" );</code></pre><p><strong>Where not to indent</strong></p><p>There are certain elements whose contents shouldn't be pretty-printed because it might change the meaning or layout of the text. For example, in a paragraph:</p><pre><code>&lt;p&gt; Some &lt;em&gt; HT &lt;strong&gt;M&lt;/strong&gt; L &lt;/em&gt;&lt;/p&gt;</code></pre><p>I've picked these elements from <a href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#text-level-semantics" rel="nofollow noopener noreferrer" target="_blank">text-level semantics</a> and a few others which I consider sensible. Feel free to edit this list if you want.</p><pre><code>$preserve_internal_whitespace = [ "a", "em", "strong", "small", "s", "cite", "q", "dfn", "abbr", "ruby", "rt", "rp", "data", "time", "pre", "code", "var", "samp", "kbd", "sub", "sup", "b", "i", "mark", "u", "bdi", "bdo", "span", "h1", "h2", "h3", "h4", "h5", "h6", "p", "li", "button", "form", "input", "label", "select", "textarea",];</code></pre><p>The function has an option to <em>force</em> indenting every time it encounters an element.</p><p><strong>Tabs 🆚 Space</strong></p><p>Tabs, obviously. Users can set their tab width to their personal preference and it won't get confused with semantically significant whitespace.</p><pre><code>$indent_character = "\t";</code></pre><p><strong>Recursive Function</strong></p><p>This function reads through each node in the HTML tree. If the node should be indented, the function inserts a new node with the requisite number of tabs before the existing node. It also adds a suffix node to indent the next line appropriately. It then goes through the node's children and recursively repeats the process.</p><p><strong>This modifies the existing Document</strong>.</p><pre><code>function prettyPrintHTML( $node, $treeIndex = 0, $forceWhitespace = false ){ global $indent_character, $preserve_internal_whitespace; // If this node contains content which shouldn't be separately indented // And if whitespace is not forced if ( property_exists( $node, "localName" ) &amp;&amp; in_array( $node-&gt;localName, $preserve_internal_whitespace ) &amp;&amp; !$forceWhitespace ) { return; } // Does this node have children? if( property_exists( $node, "childElementCount" ) &amp;&amp; $node-&gt;childElementCount &gt; 0 ) { // Move in a step $treeIndex++; $tabStart = "\n" . str_repeat( $indent_character, $treeIndex ); $tabEnd = "\n" . str_repeat( $indent_character, $treeIndex - 1); // Remove any existing indenting at the start of the line $node-&gt;innerHTML = trim($node-&gt;innerHTML); // Loop through the children $i=0; while( $childNode = $node-&gt;childNodes-&gt;item( $i++ ) ) { // Was the *previous* sibling a text-only node? // If so, don't add a previous newline if ( $i &gt; 0 ) { $olderSibling = $node-&gt;childNodes-&gt;item( $i-1 ); if ( $olderSibling-&gt;nodeType == XML_TEXT_NODE &amp;&amp; !$forceWhitespace ) { $i++; continue; } $node-&gt;insertBefore( $node-&gt;ownerDocument-&gt;createTextNode( $tabStart ), $childNode ); } $i++; // Recursively indent all children prettyPrintHTML( $childNode, $treeIndex, $forceWhitespace ); }; // Suffix with a node which has "\n" and a suitable number of "\t" $node-&gt;appendChild( $node-&gt;ownerDocument-&gt;createTextNode( $tabEnd ) ); }}</code></pre><p><strong>Printing it out</strong></p><p>First, call the function. <strong>This modifies the existing Document</strong>.</p><pre><code>prettyPrintHTML( $dom-&gt;documentElement );</code></pre><p>Then call <a href="https://www.php.net/manual/en/dom-htmldocument.savehtml.php" rel="nofollow noopener noreferrer" target="_blank">the normal <code>saveHtml()</code> serialiser</a>:</p><pre><code>echo $dom-&gt;saveHTML();</code></pre><p>Note - this does not print a <code>&lt;!doctype html&gt;</code> - you'll need to include that manually if you're intending to use the entire document.</p><p><strong>Licence</strong></p><p>I consider the above too trivial to licence - but you may treat it as MIT if that makes you happy.</p><p><strong>Thoughts? Comments? Next steps?</strong></p><p>I've not written any formal tests, nor have I measured its speed, there may be subtle-bugs, and catastrophic errors. I know it doesn't work well if the HTML is already indented. It mysteriously prints double newlines for some unfathomable reason.</p><p>I'd love to know if you find this useful. Please <a href="https://gitlab.com/edent/pretty-print-html-using-php/" rel="nofollow noopener noreferrer" target="_blank">get involved on GitLab</a> or drop a comment here.</p><p><a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/howto/" target="_blank">#HowTo</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/html/" target="_blank">#HTML</a> <a rel="nofollow noopener noreferrer" class="hashtag u-tag u-category" href="https://shkspr.mobi/blog/tag/php/" target="_blank">#php</a></p>