<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[php - Stapps.io]]></title><description><![CDATA[php - Stapps.io]]></description><link>https://blog.stapps.io/</link><generator>Ghost 0.11</generator><lastBuildDate>Sun, 04 Jan 2026 17:56:01 GMT</lastBuildDate><atom:link href="https://blog.stapps.io/tag/php/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Easy PHP version switching on Ubuntu (allows for running multiple versions at the same time)]]></title><description><![CDATA[<p>This article assumes you're using PHP FPM, we'll also show you how to switch PHP versions on the command line at the bottom as well. </p>

<p>You'll need to install the different PHP versions and make sure modules and config matches up. <br>
If you already have php7.4 installed and you're</p>]]></description><link>https://blog.stapps.io/easy-php-version-switching-on-ubuntu/</link><guid isPermaLink="false">a1b72215-48f1-46f6-b391-83406253b011</guid><category><![CDATA[php]]></category><category><![CDATA[tips]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Mon, 18 Mar 2024 23:57:53 GMT</pubDate><content:encoded><![CDATA[<p>This article assumes you're using PHP FPM, we'll also show you how to switch PHP versions on the command line at the bottom as well. </p>

<p>You'll need to install the different PHP versions and make sure modules and config matches up. <br>
If you already have php7.4 installed and you're looking to install 8.3 you could add 8.3 in while leaving 7.4 by installing it by version number with your OS package manager, e.g. with <code>apt</code> on Ubuntu:  </p>

<pre><code class="language-bash">sudo apt install php8.3-{cli,fpm}  
</code></pre>

<p>However, before installing the new version, you'll need to make sure your PHP pools don't reference a central/single sock file as installing the new fpm may auto switch it to the new version. E.g.  </p>

<pre><code class="language-bash">sudo vim /etc/php/7.4/fpm/pool.d/www.conf  
</code></pre>

<p>Check if it references <code>/var/run/php/php-fpm.sock</code> and update it to the version it's on like <code>/var/run/php/php7.4-fpm.sock</code>. <br>
You'll then also need to make this update in your nginx or apache file and reload php-fpm first, then nginx or apache. </p>

<p>Once you've installed your new PHP versions, check both php fpm versions are running with:  </p>

<pre><code class="language-bash">systemctl status php7.4-fpm  
systemctl status php8.3-fpm  
</code></pre>

<p>To help compare config files you could use a tool like <code>meld</code>, <code>vimdiff</code> or <code>diff</code>, e.g.:  </p>

<pre><code class="language-bash">sudo meld /etc/php/7.4/cli/php.ini /etc/php/8.3/cli/php.ini  
</code></pre>

<p>Make sure to compare both the <code>cli</code> and <code>fpm</code> config files.</p>

<p>Also to help compare PHP modules you can use <code>meld</code>, <code>vimdiff</code> or <code>diff</code> again like so:  </p>

<pre><code class="language-bash">meld &lt;(php7.4 -m) &lt;(php8.3 -m)  
</code></pre>

<p>Then install missing ones, for example if you spot <code>gd</code>, <code>gmp</code>, <code>intl</code>, <code>xml</code>, <code>curl</code> and <code>bcmath</code> missing you could install them with:  </p>

<pre><code class="language-bash">sudo apt install php8.3-{gd,gmp,intl,xml,curl,bcmath}  
</code></pre>

<p>Then compare the modules again.</p>

<p>Using PHP FPM you can switch PHP version easily by switching which <code>/var/run/php/php7.4-fpm.sock</code> (this may also be <code>/run/php/php7.4-fpm.sock</code>) you reference in either the Apache or Nginx config (or whichever system you use to host. </p>

<p>E.g. in Nginx it's this line:  </p>

<pre><code class="language-bash">fastcgi_pass unix:/var/run/php7.4-fpm.sock  
</code></pre>

<p>Or Apache:  </p>

<pre><code class="language-bash">SetHandler "proxy:unix:/run/php/php7.4-fpm.sock|fcgi://localhost"  
</code></pre>

<p>Your line here may be a little different, the above assumes it's the default version number based sock files but there are alternatives. <br>
Here's 3 additional examples you may find:</p>

<ul>
<li><p>A single <code>/var/run/php-fpm.sock</code> instead of specific version.
If that's the case, it will likely be that your php fpm pool for that version points to that single sock file. Your pool will be configured by a file in <code>/etc/php/VERSION/fpm/pool.d/ e.g. /etc/php/7.4/fpm/pool.d/www.conf</code> <br>
You can either, leave the current one pointing here and make sure your new PHP version has the specific version number in the sock file name and update the reference to it in the nginx/apache config. Or, you could swap which php version uses that sock file by editing the current one to have the version in the file name and the new one to this main sock file. Then restart both versions of PHP FPM. </p></li>
<li><p>Multiple pools, one per site.
If you have multiple sites on the server you may have created a php pool for each of them to isolate them. If so, you'll need to copy over these configs to the new version (or at least the ones you want on the new version, maybe test with one first) so if it was <code>/etc/php/7.4/fpm/pool.d/site.com.conf</code> and you're switching to php8.3 then copy to <code>/etc/php/8.3/fpm/pool.d/site.com.conf</code> <br>
<code>SetHandler "proxy:unix:/run/php/php7.4-fpm-site.com.sock|fcgi://localhost"</code> and update the version number in the sock file if it had one, or add one in so it doesn't clash with the other.</p></li>
<li><p>Listing to a port instead of a sock file.
<code>
listen = 127.0.0.1:7401
</code>
In this example you have ports instead of files but they can be updated mostly the same as the sock files. You'll just need to remember or note down which ports relate to which versions &amp; update your nginx/apache configs as needed.</p></li>
</ul>

<p>Remember to reload nginx/apache after editing the configs and if you updated your php-fpm configs or pools, reload php-fpm for the versions you updated.</p>

<p>Then for the CLI you can switch with:  </p>

<pre><code class="language-bash">sudo update-alternatives --set php /usr/bin/php8.3  
</code></pre>

<p>You may also want to switch the php version <code>phar</code> files use as well, you can do this with by running both the following commands:  </p>

<pre><code class="language-bash">sudo update-alternatives --set phar /usr/bin/phar8.3  
sudo update-alternatives --set phar.phar /usr/bin/phar.phar8.3  
</code></pre>

<p>To make this easier, I added a bash function so I can call <code>php-version 7.4</code> or <code>php-version 8.3</code> to switch between them, and call <code>php-version</code> to have it list the php-versions I have available:  </p>

<pre><code class="language-bash"># switch php version for CLI
function php-version {  
    if [[ "$1" == "" ]]; then
        echo "Available versions:"
        currentVersion=$(php -v | grep -oP '(?&lt;=PHP )\d+.\d+')
        availableVersions=$(ls /usr/bin/php* | grep -oP '(?&lt;=/php)(\d+\.\d+)')
        echo $availableVersions | sed "s/$currentVersion/$currentVersion *current/"
        echo "Set default for cli with: php-version $currentVersion"
    else
        echo "Setting default php cli version to $1"
        sudo update-alternatives --set php /usr/bin/php$1
        sudo update-alternatives --set phar /usr/bin/phar$1
        sudo update-alternatives --set phar.phar /usr/bin/phar.phar$1
        echo "php -v:"
        php -v
    fi
}
</code></pre>

<p>Side note, you can also use <code>sudo update-alternatives --config php</code> to have it interactively show you php versions available and switch that way. </p>]]></content:encoded></item><item><title><![CDATA[Using Makefiles for simple build scripts]]></title><description><![CDATA[<p>Makefiles are probably one of the most useful tools in my belt. They allow me to create repeatable tasks which I can run with a  simple command. </p>

<p>You may ask, why not just run the commands separately, which obviously works, but you need to remember all those commands and the</p>]]></description><link>https://blog.stapps.io/using-makefiles-for-simple-build-scripts/</link><guid isPermaLink="false">10ae02f4-2160-480d-8208-e6e6ef9dbcac</guid><category><![CDATA[Design]]></category><category><![CDATA[Development]]></category><category><![CDATA[php]]></category><category><![CDATA[Makefile]]></category><category><![CDATA[Build]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Sun, 29 May 2016 17:35:28 GMT</pubDate><content:encoded><![CDATA[<p>Makefiles are probably one of the most useful tools in my belt. They allow me to create repeatable tasks which I can run with a  simple command. </p>

<p>You may ask, why not just run the commands separately, which obviously works, but you need to remember all those commands and the order of which you run them, or write them in a README or similar. Instead, Makefiles offer a simple way to build repeatable commands for a single or series of other commands in a way that you can quickly run when you come to a project. <em>Especially useful when you have new people take over a project, or when you yourself come back to a project a few months or so later.</em></p>

<p>You use them via the terminal / command line like so:  </p>

<pre><code class="language-bash">cd ~/projects/my-project  
make do-something-cool  
</code></pre>

<p>
Where <code>do-something-cool</code> is the command you want to run in the file. </p>

<p>Many people use Makefiles in different ways, I often don't use many of the more complex features Makefiles have and a number of the tutorials start with a steep learning curve using them. <br>
Instead I'll show you a simple example file from a real project I have.</p>

<p>In this example, I have a project where I need to build / minify some javascript and css for performance. I want to run a linter over some files to be sure the sytnax is a-ok, and then I have written some tests for the code and need to be able to run them quickly after i make changes.</p>

<p>Here's an example of this in a <code>Makefile</code> file.  </p>

<pre><code class="language-bash">build:  
    jsmin js/app.js &gt; js/app.min.js
    cssmin &lt; css/app.css &gt; css/app.min.css

test: lint unit-test

lint:  
    find . -name \*.php | xargs -L1 -P4 php -l

unit-test:  
    phpunit .
</code></pre>

<p><strong><em>If you copy this code, make sure you use tabs instead of spaces as Makefiles require them.</em></strong></p>

<p>Let's break down the above.</p>

<ol>
<li><code>make build</code> runs 2 commands, <a href="https://www.npmjs.com/package/jsmin">jsmin</a> and <a href="https://www.npmjs.com/package/cssmin">cssmin</a>. These are npm modules i have installed globally. They minify my js and css code.  </li>
<li><code>make test</code> runs 2 other commands but these are other make commands. First it runs lint (which could separately be run as <code>make lint</code>, this checks the syntax of my php files for the project, using <code>find</code> to find all the php files, piped to <code>xargs</code> which then allows me to run <code>php -l</code> for each file. Then it runs unit-test, again this could be run on it's own as <code>make unit-test</code> which runs my phpunit tests. But having a single <code>make test</code> command allows me to run both with ease.  </li>
</ol>

<p>There's plenty more resources out there for learning more about Makefile's, but hopefully this will show how simple and useful they can be. </p>

<p>It's pre installed on Linux &amp; Mac OSX, and on windows you'll need to download something like <a href="http://www.mingw.org/">MinGW</a> to get it installed.</p>]]></content:encoded></item><item><title><![CDATA[Ditto.php alpha release]]></title><description><![CDATA[<h1 id="dittophphttpsgithubcomstilliarddittophprawmasterdocsimagesdittophppng"><img src="https://github.com/stilliard/Ditto.php/raw/master/docs/images/dittophp.png" alt="Ditto.php" title=""></h1>

<p><a href="https://github.com/stilliard/Ditto.php">Ditto.php</a> composer package to quickly build a web proxy which replaces my old project under this name.</p>

<h2 id="usageexample">Usage example:</h2>

<pre><code class="language-bash">composer require stilliard/ditto.php dev-master  
</code></pre>

<script src="https://gist-it.appspot.com/github/stilliard/Ditto.php/blob/master/example/index.php"></script>

<p>Much more information can be found on it's <a href="https://github.com/stilliard/Ditto.php">Github repo</a></p>]]></description><link>https://blog.stapps.io/ditto-php-alpha-release/</link><guid isPermaLink="false">6b2f4026-a9e8-4fdd-b225-e434eb6cdc2f</guid><category><![CDATA[package]]></category><category><![CDATA[proxy]]></category><category><![CDATA[php]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Mon, 19 Jan 2015 14:55:31 GMT</pubDate><content:encoded><![CDATA[<h1 id="dittophphttpsgithubcomstilliarddittophprawmasterdocsimagesdittophppng"><img src="https://github.com/stilliard/Ditto.php/raw/master/docs/images/dittophp.png" alt="Ditto.php" title=""></h1>

<p><a href="https://github.com/stilliard/Ditto.php">Ditto.php</a> composer package to quickly build a web proxy which replaces my old project under this name.</p>

<h2 id="usageexample">Usage example:</h2>

<pre><code class="language-bash">composer require stilliard/ditto.php dev-master  
</code></pre>

<script src="https://gist-it.appspot.com/github/stilliard/Ditto.php/blob/master/example/index.php"></script>

<p>Much more information can be found on it's <a href="https://github.com/stilliard/Ditto.php">Github repo</a></p>]]></content:encoded></item><item><title><![CDATA[Twig Playground]]></title><description><![CDATA[<p>I've been playing around with Twig templating alot lately, we're implementing it in one of our core projects at work. </p>

<p>Twig a great language for templating, with filters and the ability to extend blocks of other templates it works perfectly for our development flow.</p>

<p>It's easy enough to download with</p>]]></description><link>https://blog.stapps.io/twig-playground/</link><guid isPermaLink="false">799f7344-0995-4866-b7fa-405d02fad54e</guid><category><![CDATA[twig]]></category><category><![CDATA[php]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Thu, 04 Dec 2014 09:44:36 GMT</pubDate><content:encoded><![CDATA[<p>I've been playing around with Twig templating alot lately, we're implementing it in one of our core projects at work. </p>

<p>Twig a great language for templating, with filters and the ability to extend blocks of other templates it works perfectly for our development flow.</p>

<p>It's easy enough to download with composer and get started with it, but I think I've been spoiled by alot of langauges with REPLs / interactive shells. <br>
So i build a little web interface that allows me to enter some test variables (via JSON), multiple files (to test out includes and extending) and a fast way to render the results.</p>

<p>It's called Twig playground: <br>
<a href="http://twig.stapps.io/">http://twig.stapps.io/</a></p>

<p>Plus it's open source: <br>
<a href="https://github.com/stilliard/twig-playground">https://github.com/stilliard/twig-playground</a></p>

<p>It's not perfect, but it works for now.</p>

<p><em>(To edit file names btw, just double click on the name, you can then also delete the file)</em></p>

<h2 id="givemeanexample">Give me an example:</h2>

<p>Ok, try it out creating the following 4 files as a simple demo:</p>

<p><em>index.html.twig:</em></p>

<pre><code class="language-twig">{% extends "layout.html.twig" %}

{% block main %}
&lt;h1&gt;{{ text | title }}&lt;/h1&gt;  
&lt;ul&gt;  
{% for item in items %}
    &lt;li&gt;{{ item.name }}&lt;/li&gt;
{% endfor %}
&lt;/ul&gt;  
{% endblock %}
</code></pre>

<p><em>layout.html.twig:</em></p>

<pre><code class="language-twig">&lt;!DOCTYPE html&gt;  
&lt;html&gt;  
&lt;head&gt;  
&lt;meta charset="utf-8"&gt;  
&lt;title&gt;Demo&lt;/title&gt;  
&lt;/head&gt;  
&lt;body&gt;

&lt;header&gt;{% include 'header.html.twig' %}&lt;/header&gt;

&lt;div class="main"&gt;  
{% block main %}{% endblock %}
&lt;/div&gt;

&lt;footer&gt;{% include 'footer.html.twig' %}&lt;/footer&gt;

&lt;/body&gt;  
&lt;/html&gt;  
</code></pre>

<p><em>header.html.twig:</em></p>

<pre><code class="language-twig">... header ...
</code></pre>

<p><em>footer.html.twig:</em></p>

<pre><code class="language-twig">... footer ...
</code></pre>

<hr>

<p>It also supports css output, just rename the first file as .css.twig</p>

<p>E.g. Try the following in the playground:</p>

<p><em>JSON variables:</em></p>

<pre><code class="language-javascript">{ "header_color": "blue" }
</code></pre>

<p><em>index.css.twig:</em></p>

<pre><code class="language-twig">{% include 'base.css' %}

.body { background: {{ header_color }}; }
</code></pre>

<p><em>base.css:</em></p>

<pre><code class="language-css">body { font: 13px/1.4 sans-serif; }  
.header { ...}
.footer { ... }
</code></pre>]]></content:encoded></item><item><title><![CDATA[Yet another CSV parsing php package, but what makes it different?]]></title><description><![CDATA[<p>So I'm a little bored with that state of most CSV parsing tools. <br>
I'm not saying there aren't some good lib's, but, either they seem to me to focus on specific uses or they are a maze of awesome classes to work with CSV's in every way under the sun.</p>]]></description><link>https://blog.stapps.io/yet_another_csv_parsing_php_package_but_what_makes_it_different_/</link><guid isPermaLink="false">136dedae-c0d5-413f-a94a-e59450254e6a</guid><category><![CDATA[csv]]></category><category><![CDATA[package]]></category><category><![CDATA[php]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Sat, 29 Mar 2014 15:29:00 GMT</pubDate><content:encoded><![CDATA[<p>So I'm a little bored with that state of most CSV parsing tools. <br>
I'm not saying there aren't some good lib's, but, either they seem to me to focus on specific uses or they are a maze of awesome classes to work with CSV's in every way under the sun.</p>

<p>I simply want a Parser for literally input and output, thats taking in an array, a string or a file, and outputting a string, an array or file(s), and a CSV object to work with the data and have some helpers for mapping over the data columns or rows, adding/removing/sorting rows, that sort of thing. <br>
Hell, most the time I'll probably just want the Parser, as in take this CSV file, and give me an array, or the reverse, but its useful to have that CSV object there for when i need it.</p>

<p>Anyway, that's what I've built, its a composer package up on packagist and github: <br>
<a href="https://github.com/stilliard/CsvParser">https://github.com/stilliard/CsvParser</a></p>

<h3 id="install">Install</h3>

<pre><code class="language-bash">composer require stilliard/csvparser dev-master  
</code></pre>

<h3 id="exampleusage">Example usage</h3>

<pre><code class="language-php">$array = [['id'=&gt;1, 'name'=&gt;'Bob'],['id'=&gt;2, 'name'=&gt;'Bill']];
$parser = new \CsvParser\Parser();
$csv = $parser-&gt;fromArray($array);
var_dump($parser-&gt;toString($csv));  
</code></pre>

<p>So the workflow here is just create a parser, feed in the input and that gives you a CSV object, then you can either do some with with that or pass back over the the parser for the output.</p>]]></content:encoded></item><item><title><![CDATA[Rightmove BLM file reader / parser]]></title><description><![CDATA[<p>Slightly late post but thought I'd mention a quick new composer package i recently pushed up. <br>
A simple BLM reader for use with Rightmoves .BLM files.</p>

<p><a href="https://github.com/stilliard/blmreader">View live on GitHub: <a href="https://github.com/stilliard/blmreader">https://github.com/stilliard/blmreader</a></a></p>

<p>Unlike the other lib's out there, this is pretty bare bones, it doesn't try to</p>]]></description><link>https://blog.stapps.io/rightmove_blm_file_reader_parser/</link><guid isPermaLink="false">b689a8c2-b8bf-49e6-b084-06beb9b33265</guid><category><![CDATA[package]]></category><category><![CDATA[php]]></category><dc:creator><![CDATA[Andrew Stilliard]]></dc:creator><pubDate>Sat, 29 Mar 2014 15:08:00 GMT</pubDate><content:encoded><![CDATA[<p>Slightly late post but thought I'd mention a quick new composer package i recently pushed up. <br>
A simple BLM reader for use with Rightmoves .BLM files.</p>

<p><a href="https://github.com/stilliard/blmreader">View live on GitHub: <a href="https://github.com/stilliard/blmreader">https://github.com/stilliard/blmreader</a></a></p>

<p>Unlike the other lib's out there, this is pretty bare bones, it doesn't try to offer predefined values and other such helpers, it simple takes in a file and outputs an array. This is pretty handy not only for rightmove files, but for people using rightmove's format but not actually using the same fields, or for when fields get added in the future you wont have to do any work as this way it will automatically allow you access to them :)</p>

<h3 id="install">Install</h3>

<pre><code class="language-bash">composer require stilliard/blmreader dev-master  
</code></pre>

<h3 id="exampleusage">Example usage</h3>

<pre><code class="language-php">$blm = new \BLM\Reader(dirname(__FILE__) . '/test.blm');
var_dump($blm-&gt;toArray());  
</code></pre>]]></content:encoded></item></channel></rss>