<?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"><channel><title><![CDATA[Andrea's WebDev log]]></title><description><![CDATA[Andrea's WebDev log]]></description><link>https://coding.andreaolivato.com</link><generator>RSS for Node</generator><lastBuildDate>Wed, 15 Apr 2026 11:23:30 GMT</lastBuildDate><atom:link href="https://coding.andreaolivato.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How you write your String matters: benchmarking PHP]]></title><description><![CDATA[There are a lot of ways in which you can specify, use and print  string in PHP. They all have different benefits and drawbacks and that's not the content of this article. The focus of these tests is to determine how using different string specificati...]]></description><link>https://coding.andreaolivato.com/how-you-write-your-string-matters-benchmarking-php</link><guid isPermaLink="true">https://coding.andreaolivato.com/how-you-write-your-string-matters-benchmarking-php</guid><category><![CDATA[PHP]]></category><category><![CDATA[Benchmark]]></category><category><![CDATA[PHP7]]></category><category><![CDATA[Testing]]></category><category><![CDATA[performance]]></category><dc:creator><![CDATA[Andrea Olivato]]></dc:creator><pubDate>Fri, 09 Jul 2021 15:56:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1625845924220/nvkXs06LQ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are a lot of ways in which you can specify, use and print  <a target="_blank" href="https://www.php.net/manual/en/language.types.string.php">string in PHP</a>. They all have different benefits and drawbacks and that's not the content of this article. The focus of these tests is to determine how using different string specifications affects the performances of your PHP code.</p>
<blockquote>
<p>TL;DR: Single quoted strings are the most performing, both for simple text and for concatenation with other variables.</p>
</blockquote>
<h1 id="tests">Tests</h1>
<p>Compared 3 types of string specification:</p>
<ul>
<li>Single Quoted (e.g. <code>echo 'string';</code>)</li>
<li>Double Quoted (e.g. <code>echo "string";</code>)</li>
<li>HEREDOC (e.g. <code>echo &lt;&lt;&lt;EOT string EOT;</code>)</li>
</ul>
<p>For each type of specification, 2 tests:</p>
<ul>
<li>Simple string (e.g. <code>'string'</code>)</li>
<li>String + a variable (e.g. <code>'string'.$var</code>)</li>
</ul>
<h1 id="iterations">Iterations</h1>
<p>In order to simulate a strong workload and have more data, the code ran 10 iterations with a 5-second pause. For each iteration 1 Million <code>echo</code> were executed, without any pause.</p>
<p>To make sure that the machine load doesn't skew the results, all the 3 different specifications are executed within the same iteration, one after the other, with the same 5-second delay. So at any point in time, the load should be equally distributed among the different specifications.</p>
<h1 id="buffer">Buffer</h1>
<p>Since the actual printing of the strings must not affect these tests, <code>ob_start()</code> and <code>ob_end_clean()</code> are used to not print anything, and <code>ob_clean()</code> is used within each iteration to free up the buffer.</p>
<h1 id="the-code">The Code</h1>
<p>This is the code used to run the tests.</p>
<pre><code class="lang-PHP"><span class="hljs-meta">&lt;?php</span>

define(<span class="hljs-string">'MAX_PER_ITERATION'</span>, <span class="hljs-number">10000000</span>);
define(<span class="hljs-string">'MAX_ITERATIONS'</span>, <span class="hljs-number">10</span>);
define(<span class="hljs-string">'SLEEP_TIME'</span>, <span class="hljs-number">5</span>);

<span class="hljs-keyword">echo</span> <span class="hljs-string">"TEST 1: Simple String\n"</span>;
$times = [
    <span class="hljs-string">'quote'</span> =&gt; [],
    <span class="hljs-string">'doublequote'</span> =&gt; [],
    <span class="hljs-string">'heredoc'</span> =&gt; []
];
<span class="hljs-keyword">for</span> ($k = <span class="hljs-number">1</span>; $k &lt;= MAX_ITERATIONS; $k++) {
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"Iteration "</span>.$k.<span class="hljs-string">"\n"</span>;

    <span class="hljs-comment">/* Start Single Quote tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tQuote\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">'string'</span>;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'quote'</span>][] = $diff;
    sleep(SLEEP_TIME);

    <span class="hljs-comment">/* Start Double Quote tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tDouble Quote\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"string"</span>;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'doublequote'</span>][] = $diff;
    sleep(SLEEP_TIME);

    <span class="hljs-comment">/* Start HEREDOC tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tHeredoc\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">&lt;&lt;&lt; EOT
            string
        EOT</span>;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'heredoc'</span>][] = $diff;
    sleep(SLEEP_TIME);
}
<span class="hljs-keyword">foreach</span> ($times <span class="hljs-keyword">as</span> $type =&gt; $results) {
    <span class="hljs-keyword">echo</span> $type.<span class="hljs-string">"\n"</span>;
    <span class="hljs-keyword">foreach</span> ($results <span class="hljs-keyword">as</span> $r) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"\t\t"</span>.$r.<span class="hljs-string">"\n"</span>;
    }
    $avg = array_sum($results) / sizeof($results);
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tAvg: "</span>.$avg.<span class="hljs-string">"\n"</span>;
}

sleep(<span class="hljs-number">100</span>);

<span class="hljs-keyword">echo</span> <span class="hljs-string">"TEST 2: String with Variable\n"</span>;
$times = [
    <span class="hljs-string">'quote'</span> =&gt; [],
    <span class="hljs-string">'doublequote'</span> =&gt; [],
    <span class="hljs-string">'heredoc'</span> =&gt; []
];
$variable = <span class="hljs-string">'string2'</span>;
<span class="hljs-keyword">for</span> ($k = <span class="hljs-number">1</span>; $k &lt;= MAX_ITERATIONS; $k++) {
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"Iteration "</span>.$k.<span class="hljs-string">"\n"</span>;

    <span class="hljs-comment">/* Start Single Quote tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tQuote\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">'string'</span>.$variable;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'quote'</span>][] = $diff;
    sleep(SLEEP_TIME);

    <span class="hljs-comment">/* Start Double Quote tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tDouble Quote\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"string <span class="hljs-subst">$variable</span>"</span>;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'doublequote'</span>][] = $diff;
    sleep(SLEEP_TIME);

    <span class="hljs-comment">/* Start HEREDOC tests */</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tHeredoc\n"</span>;
    ob_start();
    $start = microtime(<span class="hljs-literal">true</span>);
    <span class="hljs-keyword">for</span> ($i = <span class="hljs-number">0</span>; $i &lt; MAX_PER_ITERATION; $i++) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">&lt;&lt;&lt; EOT
            string <span class="hljs-subst">{$variable}</span>
        EOT</span>;
        ob_clean();
    }
    $diff = (microtime(<span class="hljs-literal">true</span>) - $start);
    ob_end_clean();
    $times[<span class="hljs-string">'heredoc'</span>][] = $diff;
    sleep(SLEEP_TIME);
}
<span class="hljs-keyword">foreach</span> ($times <span class="hljs-keyword">as</span> $type =&gt; $results) {
    <span class="hljs-keyword">echo</span> $type.<span class="hljs-string">"\n"</span>;
    <span class="hljs-keyword">foreach</span> ($results <span class="hljs-keyword">as</span> $r) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"\t\t"</span>.$r.<span class="hljs-string">"\n"</span>;
    }
    $avg = array_sum($results) / sizeof($results);
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"\tAvg: "</span>.$avg.<span class="hljs-string">"\n"</span>;
}
</code></pre>
<h1 id="summary-results">Summary Results</h1>
<p>Unsurprisingly, the <strong>Single Quoted strings are the fastest</strong>: as they don't require parsing for variables or special characters (e.g. <code>\n</code>), they run quicker than the others both for simple strings and for variables.</p>
<ul>
<li>Simple String: <code>0.3838947773</code> seconds for 1 Million executions</li>
<li>String+Variable: <code>0.532834816</code> seconds for 1 Million executions</li>
</ul>
<p><strong>Heredoc</strong> performs a bit slower than Single Quoted strings, but faster than Double Quoted ones, especially when without variables.</p>
<ul>
<li>Simple String: <code>0.387871933</code> seconds for 1 Million executions</li>
<li>String+Variable: <code>0.553892827</code> seconds for 1 Million executions</li>
</ul>
<p>Finally <strong>Double Quoted</strong> strings:</p>
<ul>
<li>Simple String: <code>0.3914105415</code> seconds for 1 Million executions</li>
<li>String+Variable: <code>0.5623492718</code> seconds for 1 Million executions</li>
</ul>
<h1 id="complete-results">Complete Results</h1>
<p>Below you can see a sneak peak of the final results. If you click on the image or  <a target="_blank" href="https://docs.google.com/spreadsheets/d/1D381g94mJwLDyUt8gqXf4A4l_RSYD1sHfaQ5g97f8J8/edit?usp=sharing">here</a> , you can access a shared spreadsheet with the complete data.</p>
<p> <a target="_blank" href="https://docs.google.com/spreadsheets/d/1D381g94mJwLDyUt8gqXf4A4l_RSYD1sHfaQ5g97f8J8/edit?usp=sharing"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1625845740107/XcI6Qh9Ih.png" alt="Screenshot 2021-07-09 at 11.39.27 PM.png" />
</a> </p>
<h1 id="systemversions">System/Versions</h1>
<ul>
<li>PHP 7.4.19</li>
<li>Amazon Linux 2 AMI </li>
<li>Kernel 4.14.232-177.418.amzn2.x86_64</li>
<li>16GB Memory</li>
<li>4 Virtual CPUs</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Fix `ld: library not found for -lgomp` when installing Imagick 3.5 via PHP pecl on Mac]]></title><description><![CDATA[Update 25 July 2021
As of 22 July 2021, version 3.5.1 is stable in the pecl channel and can be used to compile imagick for both PHP 7 and PHP 8.
pecl install imagick
The general command will not fail anymore
TL;DR
Install the older version (3.4.4) of...]]></description><link>https://coding.andreaolivato.com/fix-ld-library-not-found-for-lgomp-when-installing-imagick-35-via-php-pecl-on-mac</link><guid isPermaLink="true">https://coding.andreaolivato.com/fix-ld-library-not-found-for-lgomp-when-installing-imagick-35-via-php-pecl-on-mac</guid><category><![CDATA[PHP]]></category><category><![CDATA[Homebrew]]></category><category><![CDATA[Bugs and Errors]]></category><category><![CDATA[macOS]]></category><category><![CDATA[compiler]]></category><dc:creator><![CDATA[Andrea Olivato]]></dc:creator><pubDate>Mon, 21 Jun 2021 06:12:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1624254946052/NjZ8k9Uae.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="update-25-july-2021">Update 25 July 2021</h2>
<p>As of 22 July 2021, version 3.5.1 is stable in the <code>pecl</code> channel and can be used to compile <code>imagick</code> for both PHP 7 and PHP 8.</p>
<pre><code><span class="hljs-attribute">pecl</span> install imagick
</code></pre><p>The general command will not fail anymore</p>
<h2 id="tldr">TL;DR</h2>
<p>Install the older version (3.4.4) of Imagick forcing it via <code>pecl</code></p>
<pre><code><span class="hljs-attribute">pecl</span> install imagick-<span class="hljs-number">3</span>.<span class="hljs-number">4</span>.<span class="hljs-number">4</span>
</code></pre><h2 id="intro">Intro</h2>
<p>The last version (3.5) of the PHP extension for Imagemagick ( <a target="_blank" href="https://github.com/Imagick/imagick">Imagick</a> ) introduces a compilation error on Apple systems, which is independent from the PHP version (tested on 7.4 and 8) and Imagemagick version (tested on 6.x and 7.x) and is instead related to the missing/broken support for  <a target="_blank" href="https://gcc.gnu.org/projects/gomp/">gomp</a> of the gcc compiler.</p>
<p>This is not related to Apple Silicon either, as I've tested on an Intel machine.</p>
<h2 id="error">Error</h2>
<p>The error is thrown while compiling, after running</p>
<pre><code><span class="hljs-attribute">pecl</span> install imagick
</code></pre><p>The complete error is </p>
<pre><code>ld: library <span class="hljs-keyword">not</span> <span class="hljs-built_in">found</span> <span class="hljs-keyword">for</span> -lgomp
</code></pre><h2 id="potential-fixes">Potential Fixes</h2>
<p>There are several Stack Overflow threads talking about compilation errors due to Gomp. The most comprehensive I've found  <a target="_blank" href="https://stackoverflow.com/questions/20321988/error-enabling-openmp-ld-library-not-found-for-lgomp-and-clang-errors">is this</a>. </p>
<p>I've tried few of the fixes proposed in the answer, but most require compiling a different version of gcc,  which would make subsequent updates via homebrew unstable.</p>
<p>Also tried this other  <a target="_blank" href="https://stackoverflow.com/questions/43555410/enable-openmp-support-in-clang-in-mac-os-x-sierra-mojave/48746939#48746939">amazing thread</a> on Stack Overflow which suggests <code>llvm</code> and revised compiler flags, but it didn't work for this specific case, probably due to built-in parameters in the pecl compilation process.</p>
<h2 id="actual-fix">Actual Fix</h2>
<p>In the end the final fix was to downgrade the version of Imagick to 4.3.3, which compiles perfectly.</p>
<p>You can do so either by  <a target="_blank" href="https://github.com/Imagick/imagick/releases/tag/3.4.4">downloading the release</a>  from github or simply by forcing the version in pecl as follows:</p>
<pre><code><span class="hljs-attribute">pecl</span> install imagick-<span class="hljs-number">3</span>.<span class="hljs-number">4</span>.<span class="hljs-number">4</span>
</code></pre>]]></content:encoded></item><item><title><![CDATA[How to implement TikTok Login Kit for Web in PHP]]></title><description><![CDATA[TikTok has recently released their new API to allow Social Login via their platform. They called it Login Kit for Web.
With more Gen-Z and Millennials in the platform, allowing the simplified signup and login process via TikTok is the logical step fo...]]></description><link>https://coding.andreaolivato.com/how-to-implement-tiktok-login-kit-for-web-in-php</link><guid isPermaLink="true">https://coding.andreaolivato.com/how-to-implement-tiktok-login-kit-for-web-in-php</guid><category><![CDATA[PHP]]></category><category><![CDATA[social]]></category><category><![CDATA[social media]]></category><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><dc:creator><![CDATA[Andrea Olivato]]></dc:creator><pubDate>Thu, 17 Jun 2021 16:27:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1623947183512/lVps7siBY.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://www.tiktok.com/">TikTok</a> has recently released their new API to allow Social Login via their platform. They called it <a target="_blank" href="https://developers.tiktok.com/doc/login-kit-web">Login Kit for Web</a>.</p>
<p>With more Gen-Z and Millennials in the platform, allowing the simplified signup and login process via TikTok is the logical step for many Web Apps, including our very own <a target="_blank" href="https://lnk.bio/">Lnk.Bio</a>.</p>
<p>While the implementation is a very basic oauth2 flow, there were no published class nor guides specific to PHP implementation, so I thought useful to publish an <a target="_blank" href="https://github.com/andreaolivato/TikTok-LoginKit-PHP">Open-source class</a> and this quick tutorial based on such class.</p>
<h2 id="step-1-register-your-app">Step 1: Register your App</h2>
<p>First of all, you need to register in the <a target="_blank" href="https://lnk.bio/">TikTok Developers platform](https://developers.tiktok.com/). Process is easy and approval is quite fast; it took us just 24hrs to get approved with Lnk.Bio</a>.</p>
<blockquote>
<p>Pay attention to the approved redirect URLs. While the TikTok page calls them “Redirect Domains”, they actually require full URLs, so the full path of the page where you’re redirected after the TikTok login.</p>
</blockquote>
<p>After you register your application you will receive, as usual a <strong>Client Key</strong> and <strong>Client Secret</strong>.</p>
<h2 id="step-2-install-helper-class">Step 2: Install helper class</h2>
<p>Use Composer to install the PHP helper</p>
<pre><code>composer <span class="hljs-keyword">require</span> gimucco/tiktok-loginkit
</code></pre><p>If, for any reason, you’re not using Composer, you can download the class from <a target="_blank" href="https://github.com/andreaolivato/TikTok-LoginKit-PHP/releases/tag/v0.1">Github</a>. Current stable is v0.1.</p>
<h2 id="step-3-full-login-example">Step 3: Full Login Example</h2>
<p>The login flow is typical:</p>
<ul>
<li>Generate a Redirect Url to send the user to TikTok to authorise your app</li>
<li>Receive the Authorisation Token</li>
<li>Exchange the Authorisation Token with an Access Token that you can use for the rest of the calls</li>
<li>Make a sample call to retrieve the User Information</li>
</ul>
<p>Here’s a quick code sample</p>
<pre><code class="lang-php">session_start(); <span class="hljs-comment">// Important! Required for STATE Variable check and prevent CSRF attacks</span>
<span class="hljs-keyword">require_once</span> <span class="hljs-keyword">__DIR__</span>.<span class="hljs-string">'/../../../autoload.php'</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">gimucco</span>\<span class="hljs-title">TikTokLoginKit</span>;

$api_key = <span class="hljs-string">''</span>; <span class="hljs-comment">// Your API Key, as obtained from TikTok Developers portal</span>
$api_secret = <span class="hljs-string">''</span>; <span class="hljs-comment">// Your API Secret, as obtained from TikTok Developers portal</span>
$redirect_uri = <span class="hljs-string">''</span>; <span class="hljs-comment">// Where to return after authorization. Must be approved in the TikTok Developers portal</span>
$_TK = <span class="hljs-keyword">new</span> TikTokLoginKit($api_key, $api_secret, $redirect_uri);

<span class="hljs-keyword">if</span> (TikTokLoginKit\Connector::receivingResponse()) { <span class="hljs-comment">// Check if you're receiving the Authorisation Code</span>
    <span class="hljs-keyword">try</span> {
        $token = $_TK-&gt;verifyCode($_GET[TikTokLoginKit\Connector::CODE_PARAM]); <span class="hljs-comment">// Verify the Authorisation code and get the Access Token</span>

        <span class="hljs-comment">// ** Your logic to store the access token goes here</span>

        $user = $_TK-&gt;getUser(); <span class="hljs-comment">// Retrieve the User Object</span>

        <span class="hljs-comment">// ** Your logic to store or use the User Info goes here</span>

        <span class="hljs-comment">// Print some HTML as example</span>
        <span class="hljs-keyword">echo</span> <span class="hljs-string">&lt;&lt;&lt;HTML
        &lt;table width="500"&gt;
            &lt;tr&gt;
                &lt;td with="200"&gt;&lt;img src="<span class="hljs-subst">{$user-&gt;getAvatarLarger()}</span>"&gt;&lt;/td&gt;
                &lt;td&gt;
                    &lt;br /&gt;
                    &lt;strong&gt;ID&lt;/strong&gt;: <span class="hljs-subst">{$user-&gt;getOpenID()}</span>&lt;br /&gt;&lt;br /&gt;
                    &lt;strong&gt;Name&lt;/strong&gt;: <span class="hljs-subst">{$user-&gt;getDisplayName()}</span>
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/table&gt;
HTML</span>;
    } <span class="hljs-keyword">catch</span> (<span class="hljs-built_in">Exception</span> $e) {
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"Error: "</span>.$e-&gt;getMessage();
        <span class="hljs-keyword">echo</span> <span class="hljs-string">'&lt;br /&gt;&lt;a href="?"&gt;Retry&lt;/a&gt;'</span>;
    }
} <span class="hljs-keyword">else</span> { <span class="hljs-comment">// Print the initial login button that redirects to TikTok</span>
    <span class="hljs-keyword">echo</span> <span class="hljs-string">'&lt;a href="'</span>.$_TK-&gt;getRedirect().<span class="hljs-string">'"&gt;Log in with TikTok&lt;/a&gt;'</span>;
}
</code></pre>
<p>All done! If you have any suggestion on the class or its implementation please feel free to reach out on <a target="_blank" href="https://github.com/andreaolivato/TikTok-LoginKit-PHP">GitHub</a> or <a target="_blank" href="https://twitter.com/andreaolivato">Twitter</a>.</p>
]]></content:encoded></item></channel></rss>