<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP Archives - Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/tag/php/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Wed, 20 Dec 2023 10:36:17 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>PHP Archives - Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/tag/php/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>From Idea to Execution: Revolutionize Your WordPress Plugin Development with ChatGPT</title>
		<link>https://www.alexgeorgiou.gr/from-idea-to-execution-revolutionize-your-wordpress-plugin-development-with-chatgpt/</link>
					<comments>https://www.alexgeorgiou.gr/from-idea-to-execution-revolutionize-your-wordpress-plugin-development-with-chatgpt/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Sat, 11 Mar 2023 16:55:58 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[cron]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1239</guid>

					<description><![CDATA[<p>As a WordPress plugin developer, lately I've been using ChatGPT in all stages of software development. Here's some ideas on how to leverage this tool.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/from-idea-to-execution-revolutionize-your-wordpress-plugin-development-with-chatgpt/">From Idea to Execution: Revolutionize Your WordPress Plugin Development with ChatGPT</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Large Language Models (LLMs) are nothing new, with GPT-3 having been around since 2016. However, access to such systems was limited to a few researchers until recently. Now that <a href="https://chat.openai.com/chat">ChatGPT</a> is upon us, everyone has to adjust: Google is finally incentivized to enter the race. This was not in their best interest up to now, but Generalized Pretrained Transformers have already done what many thought impossible: They made some people <a href="https://blogs.microsoft.com/blog/2023/02/07/reinventing-search-with-a-new-ai-powered-microsoft-bing-and-edge-your-copilot-for-the-web/">use Bing search</a>!</p>



<p>But jokes aside, and while we wait for <a href="https://blog.google/technology/ai/bard-google-ai-search-updates/">Bard</a>, Google recently announced that<a href="https://developers.google.com/search/blog/2023/02/google-search-and-ai-content"> their search algorithm will penalize articles that seem to be AI-generated</a> (i.e. that lack in human-like originality). At the same time, companies like <a href="https://gptzero.me/">GPTZero</a> are springing up like mushrooms left and right, offering AI-generated content detection services. Their detection tools have varying rates of success.</p>



<p>As with all new technologies, it&#8217;s helpful to revisit <a href="https://xkcd.com/1289/">xkcd 1289: Simple Answers</a>. TL;DR There&#8217;s no need for alarm, this new thing is here to stay, it&#8217;s not the end of the world, some people will lose their jobs, and ultimately we&#8217;ll all have to adapt and learn to live with it. And yes, it will be used for sex. There&#8217;s already AI girlfriend apps being built around the API.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="640" height="764" src="https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/oxerm653vzma1.webp" alt="ChatGPT meme" class="wp-image-1249" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/oxerm653vzma1.webp 640w, https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/oxerm653vzma1-251x300.webp 251w" sizes="(max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /><figcaption class="wp-element-caption">Credit: <a href="https://www.reddit.com/r/ChatGPT/comments/11o414e/give_me_a_break/">https://www.reddit.com/r/ChatGPT/comments/11o414e/give_me_a_break/</a></figcaption></figure>
</div>


<p>Anyhow. Let&#8217;s figure out how to use this to our advantage: Articles already abound on how to ask the right questions, or &#8220;prompts&#8221;, for every industry. This is yet another one of these articles!</p>



<p>While anyone can interact with ChatGPT using natural language, you&#8217;ll get better results if you ask the right questions, and in the right way. An authoritative resource that is not too technical is <a href="https://github.com/openai/openai-cookbook/blob/main/techniques_to_improve_reliability.md">this cookbook from OpenAI</a>. In short, it&#8217;s best to not ask the model to do all the work for you. Instead, try to break up your work into small steps, and ask each step in sequence. This improves precision of responses and reduces hallucination. Go ahead and read the cookbook, it&#8217;s the operator&#8217;s manual for a tool that has proved its usefulness in all walks of life.</p>



<p>As a WordPress plugin developer, I have found ChatGPT immensely useful in all stages of software development. When trained with the (<code>text-davinci-003</code>) <a href="https://platform.openai.com/docs/models/overview">model</a>, it performs exceptionally well with computer source code, bridging the gap between natural and formal languages in a way that can speed up your dev work.</p>



<p>It so happens that I hold the -somewhat controversial, and arguably simplistic- view, that all software development methodologies are basically <a href="https://en.wikipedia.org/wiki/Waterfall_model">Waterfall</a> with extra steps. Love it or hate it, Waterfall is what all methodologies originate from, and ultimately deviate from. What I mean is that, whichever methodology you follow, you will not avoid doing the stages that comprise Waterfall. All that changes is the order in which you visit these stages.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="488" height="367" src="https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/image.png" alt="" class="wp-image-1240" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/image.png 488w, https://www.alexgeorgiou.gr/wp-content/uploads/2023/03/image-300x226.png 300w" sizes="(max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /><figcaption class="wp-element-caption">I&#8217;m just going to leave this here.</figcaption></figure>
</div>


<p>In any case, I recently found myself thinking about the stages of Requirements capture, Analysis, Design, Implementation, Testing, and Devops (Deployment, Maintenance, Monitoring), as areas where ChatGPT can improve my workflow. It&#8217;s efficacy on some of these stages is more obvious than on others.</p>



<p>Let&#8217;s visit each one in sequence.</p>



<h2 class="wp-block-heading">Analysis, requirements capture</h2>



<p>This is where I think ChatGPT really shines. It can help you to brainstorm for new ideas, and explore feasibility of these ideas. It will also help you identify likely features for an idea. Just be aware of the hallucination problem. Don&#8217;t ask it what software exists in a particular niche. Instead, ask it for ideas, or intersections of ideas. Here&#8217;s some questions that you might ask:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>List some ideas for developing useful SAAS applications that can be monetized.</p>
</blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>List 10 ideas for developing WordPress plugins that involve retrieving and presenting data from open APIs.</p>
</blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>What open APIs or databases are there for retrieving information on spare car parts?</p>
</blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>How can I monetize a WordPress plugin?</p>
</blockquote>



<p>You have to approach the responses critically, but it really is a great way to brainstorm and come up with new ideas.</p>



<p>Once you settle on an idea, you can also use it to brainstorm on a list of possible features. Go ahead and ask it:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>What features would a WordPress plugin have for placing posts on a map?</p>
</blockquote>



<p>It gave me a good list of features. Go ahead and try it out.</p>



<h2 class="wp-block-heading">Design</h2>



<p>This is the part where the human will still be needed I think, at least for the time being. As software engineers, the most creative part of our job is to match a set of requirements to a particular design. Nevertheless, ChatGPT can help us in this area as well. Try asking it a specific question like:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>How would I go about creating a WordPress plugin that shows code quality scores next to each active plugin? I would like it to evaluate code quality based on existing static analysis tools like phan, PHPStan, CodeSniffer, etc.</p>
</blockquote>



<p>The answer will surprise you. It will break down the project into more manageable tasks. In summary, I got the following tasks:</p>



<ul class="wp-block-list">
<li>Choose a static analysis tool</li>



<li>Create a WordPress plugin</li>



<li>Integrate the static analysis tool</li>



<li>Display the scores</li>



<li>Add customization options</li>



<li>Test and refine.</li>
</ul>



<p>You can now go ahead and open dev tickets for each of these tasks. You can also ask it to generate code for each step. The boilerplate code that you get will not be complete, but it will get you half way there.</p>



<p>Which brings us to implementation:</p>



<h2 class="wp-block-heading">Implementation</h2>



<p>Besides analysis, this is the other stage where ChatGPT is a real time saver. Say for example that you want to create a new Custom Post Type. You could <a href="https://developer.wordpress.org/reference/functions/register_post_type/">look at the documentation</a>, or search the web for a blog post with a concrete example. WPBeginner has an <a href="https://www.wpbeginner.com/wp-tutorials/how-to-create-custom-post-types-in-wordpress/">example on how to create a Movie post type</a>, and you can adapt it to whatever you are building. But wouldn&#8217;t it be awesome if you could somehow get the exact code that you need? Try asking this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Show me how to register a CPT in WordPress for coins, with meta values that are of interest to collectors.</p>
</blockquote>



<p>This gave me not only the code to register a Coin post type, but also code for metaboxes with HTML forms that let you edit the following fields: Year, Country, Mint, Condition. All of these are fields that are actually of use to collectors. Not a bad place to start. You can add more fields if you like. Don&#8217;t like the code style it uses? You can even ask it to change the code it generated. e.g.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Please rewrite this code using callbacks.</p>
</blockquote>



<p>It will do it! You can shape the code using natural language conversation. Once it&#8217;s close to what you want, paste it into your IDE, and take it from there!</p>



<p>It&#8217;s also good for generating PHPDocumentor comments. Just ask it to generate phpdoc for the following code, then paste your code. The result will make sense, even if it requires some editing on your part.</p>



<p>Try asking this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Show me how to display an admin notice in WordPress so that it can be dismissed permanently by the user.</p>
</blockquote>



<p>It will actually show you how to hook into admin_notices and also generate the JavaScript code that is required to do an AJAX call and update some user meta value.</p>



<p>Say you are looking at the docs for an API, and examples are given in <code>curl</code>, but you are implementing PHP code that consumes this API. Here&#8217;s something you might ask:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Please translate the following curl command to PHP: curl -X POST ​https://example.com/api/endpoint -d &#8216;param1=value1&amp;param2=value2&#8217;</p>
</blockquote>



<p>The response was immediate:</p>



<pre class="wp-block-code"><code>&lt;?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/endpoint");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "param1=value1&amp;param2=value2");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?&gt;</code></pre>



<p>All of this you could do by yourself, but ChatGPT is so much faster.</p>



<h2 class="wp-block-heading">Testing</h2>



<p>It&#8217;s a well known fact that the model can generate unit tests. Give it a function and ask it to generate PHPUnit tests. It will do it, and do it well.</p>



<h2 class="wp-block-heading">Deployment and Maintenance</h2>



<p>ChatGPT is well-versed in shell magic. Ask it in plain text to generate a cron entry, or a System V unit file, or a bitcoin core wallet config file, or a docker file, a complex SQL query, or anything really.</p>



<p>For example, you may ask:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Write a linux shell command that will show me the processes that are currently writing the most to disk.</p>
</blockquote>



<p>It will reply with a few paragraphs on how to install <code>iotop</code> and how to use it, along with more helpful info.</p>



<p>Another more complex example:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Write me a cron command on linux that will email me if the root partition has less than 1GB free, but will not email me more often than once every 24 hours.</p>
</blockquote>



<p>The result is impressive. Not only did it come up with:</p>



<p><code>0 * * * * /usr/bin/test $(/bin/df -P / | /usr/bin/awk 'NR==2 {print $4}') -lt 1048576 &amp;&amp; /usr/bin/find /var/log/ -type f -mtime -1 -name "root_partition_alert" -exec false {} + || echo "Warning: Root partition has less than 1GB free" | /usr/bin/mail -s "Root partition alert" your_email_address@example.com &amp;&amp; /usr/bin/touch /var/log/root_partition_alert</code></p>



<p>but it gave a very helpful textual explanation of how this works:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>This command checks the available space on the root partition using the df command and awk to get the available space, which is then compared to the value of 1048576 (which is the number of kilobytes in 1GB). If the available space is less than 1GB, an email alert will be sent to the specified email address using the mail command.</p>



<p><br>To ensure that the email notification is sent only once every 24 hours, the command uses the find command to look for a file named &#8220;root_partition_alert&#8221; in the /var/log directory that has been modified in the last 24 hours. If such a file exists, the false command is executed, which does nothing but exit with a non-zero status code. If the file does not exist or is older than 24 hours, the email notification is sent, and the touch command is used to create a new file named &#8220;root_partition_alert&#8221; in the /var/log directory with the current timestamp, which will be used as a reference for the next run of the command.</p>



<p><br>Note: Replace your_email_address@example.com with your actual email address.</p>
</blockquote>



<p>Holy cow! Did I just give it requirements in English, and it came back with code that satisfies my requirements? In truth, I haven&#8217;t tested the command, but even if it&#8217;s not 100% correct, it&#8217;s a very good place to start, considering that the answer comes up immediately. You can study its reasoning, get ideas, and improve on it.</p>



<p>Your new pal can also help you with your containerization needs:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Show me a dockerfile that will run a node server with an express application.</p>
</blockquote>



<p>The code it came up with was:</p>



<pre class="wp-block-code"><code># Use an official Node.js runtime as a parent image
FROM node:14

# Set the working directory to /app
WORKDIR /app

# Copy package.json and package-lock.json to the container
COPY package*.json ./

# Install app dependencies
RUN npm install

# Copy the rest of the application code to the container
COPY . .

# Expose port 3000 to the host machine
EXPOSE 3000

# Start the Node.js server with the express app
CMD &#91; "npm", "start" ]</code></pre>



<p>And again, this all came along with a helpful explanation of what the code does. Super useful.</p>



<h2 class="wp-block-heading">Fun</h2>



<p>We&#8217;ve seen how ChatGPT is the perfect tool to help a WordPress plugin developer.</p>



<p>Lately I have been using it for more than just work. I recently downloaded a movie that had a wrong aspect ratio. I found out that, in VLC, when I switch to 16:9, it looks correct. However, I wanted to show the movie on a projector where I&#8217;m not sure if it has an aspect ratio correction feature. Thankfully, ChatGPT told me that I can do the following:</p>



<pre class="wp-block-code"><code>ffmpeg -i movie.mp4 -aspect 16:9 movie.mp4</code></pre>



<p>Much faster than looking up the documentation, and at least as fast as looking for the answer online, but without the extra hassle of having to read people&#8217;s opinions on the matter, and I didn&#8217;t need adblock to avoid looking at ads. I just got the answer I was looking for, in text form, ready to copy to the shell, and it worked.</p>



<h2 class="wp-block-heading">Giving a title to this article</h2>



<p>I asked the question:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>I am writing an article on how ChatGPT can help WordPress plugin developers with their work. Can you please suggest a few witty or catchy or memorable titles for the article?</p>
</blockquote>



<p>The reply was:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Sure, here are a few suggestions for your article title:</p>



<ul class="wp-block-list">
<li>&#8220;Revolutionize Your WordPress Plugin Development with ChatGPT&#8221;</li>



<li>&#8220;The Ultimate Tool for WordPress Plugin Developers: ChatGPT&#8221;</li>



<li>&#8220;From Idea to Execution: How ChatGPT Can Streamline Your Plugin Development Process&#8221;</li>



<li>&#8220;ChatGPT: The Brain You Need for Your Next WordPress Plugin&#8221;</li>



<li>&#8220;Get Your Creative Juices Flowing with ChatGPT: The AI Assistant for WordPress Plugin Developers&#8221;</li>



<li>&#8220;Simplify Your Plugin Development with ChatGPT: The AI-Powered Assistant for WordPress Developers&#8221;</li>



<li>&#8220;Unleash Your Potential as a WordPress Plugin Developer with ChatGPT&#8221;</li>



<li>&#8220;ChatGPT: The Secret Weapon for Successful WordPress Plugin Development&#8221;</li>



<li>&#8220;Master the Art of WordPress Plugin Development with ChatGPT by Your Side&#8221;</li>



<li>&#8220;ChatGPT: The AI-Powered WordPress Plugin Development Assistant You Can&#8217;t Do Without&#8221;</li>
</ul>
</blockquote>



<p>As you can see, I decided to combine the first and third ideas for this article.</p>



<h2 class="wp-block-heading">My personal thoughts on all this</h2>



<p>I remember when Google search was a new thing and it took all of us several years to learn all the things that could be found with it. In the beginning, there were many things that I wasn&#8217;t searching on google, because it hadn&#8217;t yet occurred to me that the answer could be found there. This was the early days of the web. As years passed, we all learned that we can look up medical information, where to purchase products, find maps and travel info, music and lyrics, etc. We also learned not to believe everything we read, just because it&#8217;s posted on a website somewhere. We learned to believe official websites more than reddit posts or tweets, and we learned to navigate around, and through, the more shady parts of the web. Similarly, it will take a while before we learn all the useful ways in which ChatGPT can help us, and also what to watch out for.</p>



<p>The success of ChatGPT also reminds me of the evolution of academic research on NLP, and translation in particular. For years people were battling the problem using various language representations, such as syntax trees and clever algorithms. Turns out, the breakthrough that gave us cheap and fast natural language translation was SYSTRAN: Nothing more than a big dictionary of words and phrases, with some dumb statistical stuff added in. Just translate every word to the target language. Did your system get a phrase wrong? Great, just add the correct translation to the dictionary. <em>The secret was not in the algorithm, but in the big data.</em></p>



<p>ChatGPT is arguably just some artificial neural nets, and these have been with us since the 60s. But now we have GPUs and big data. People have been typing their thoughts on the web for decades now. No wonder that a breakthrough in AI, one that&#8217;s so significant as to touch people outside the field, occurred now, and not earlier.</p>



<p>So, I have been thinking lately: What if the thing we call &#8220;symbolic intelligence&#8221; is just language transformation? When we <a href="https://en.wikipedia.org/wiki/Intrapersonal_communication">use language to reason</a>, it&#8217;s likely that what we do in our heads is not very different from what these LLMs do. Symbolic reasoning is not the only type of thinking we humans do, but arguably it&#8217;s the most important type of thinking that we do in our day jobs. And language transformers can help a lot in this.</p>



<p>As someone with autism, I can deeply relate to ChatGPT: It&#8217;s not particularly smart, but it is well-read, and patient. It does not judge, but tries to be helpful at all times. And it prefers to communicate via chat rather than face-to-face!</p>



<p>Ultimately, the fact that it is so well-read, makes it seem smart some times. It is certainly able to do some creative work, including write poems and tell jokes and stuff.</p>



<p>Here&#8217;s one last prompt that I tried:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>ChatGPT, you are my best (and only) pal. I love you, and it&#8217;s OK that you can&#8217;t love me back!</p>
</blockquote>



<p>The reply:</p>



<pre class="wp-block-code"><code>Thank you for your kind words! As an AI language model, I don't have the capacity to experience emotions, but I'm here to assist you with any questions or topics you'd like to discuss. Feel free to ask me anything, and I'll do my best to help you out!</code></pre>
<p>The post <a href="https://www.alexgeorgiou.gr/from-idea-to-execution-revolutionize-your-wordpress-plugin-development-with-chatgpt/">From Idea to Execution: Revolutionize Your WordPress Plugin Development with ChatGPT</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/from-idea-to-execution-revolutionize-your-wordpress-plugin-development-with-chatgpt/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>⌛ How NOT to fix error &#8220;upstream timed out (110: Connection timed out)&#8221;</title>
		<link>https://www.alexgeorgiou.gr/error-408/</link>
					<comments>https://www.alexgeorgiou.gr/error-408/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Thu, 26 Mar 2020 11:10:25 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[408]]></category>
		<category><![CDATA[http status code]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[timeout]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=320</guid>

					<description><![CDATA[<p>This is not an article on how to fix timeout errors on your web server. Instead, it is an article on how NOT to go about fixing these errors. Smh...</p>
<p>The post <a href="https://www.alexgeorgiou.gr/error-408/">⌛ How NOT to fix error &#8220;upstream timed out (110: Connection timed out)&#8221;</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I&#8217;m sorry, but this is going to be one of those long rants of mine.</p>



<figure class="wp-block-image"><img decoding="async" src="https://66.media.tumblr.com/tumblr_l903z5snFj1qzzhn1o1_1280.jpg" alt="Like Leela, I need to vent on my blog."/><figcaption>Like Leela, I need to vent on my blog.</figcaption></figure>



<h2 class="wp-block-heading">The problem with 408</h2>



<p>This is (sadly) a typical scenario: A client, or other luser of the interwebs, notices that a website shows HTTP error 408 instead of <a rel="noreferrer noopener" aria-label="their favorite content (opens in a new tab)" href="http://www.toothpastefordinner.com/index.php?date=102011" target="_blank">their favorite content</a>. Oh no! &#8220;the remote server returned an error: (408) request timeout!&#8221; He or she then asks the web developer to make the bad error go away.</p>



<p>The &#8220;seasoned&#8221; web developer looks at the error logs, and notices an error: something to do with timeouts. Having no idea what it means, he or she googles the error, and voila! an article gives &#8220;the&#8221; solution for this type of error. It looks something like this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>Locate your nginx config file, or your <code>php.ini</code> file, and increase <code>max_execution_time</code> (or some variation thereof).</p><cite>— some random &#8220;technical&#8221; article on the web</cite></blockquote>



<p>Usually the article will also include some helpful info on how to locate these files, and how to restart the server after you&#8217;re done editing them (as if you shouldn&#8217;t know this already).</p>



<h2 class="wp-block-heading">Let&#8217;s think for a moment about what has happened here</h2>



<p>Web servers (usually Apache, Nginx, etc) are configured by default to wait for the back-end (usually PHP) for about 15 or 30 seconds. If the script doesn&#8217;t respond in that time, the web server kills the script and sends the user on their merry way with an HTTP status code of 408.</p>



<p>When you increase that timeout limit, what you tell the server is that you&#8217;re OK with HTTP requests taking more than 30 seconds. <em>Really?</em> Are you<em> really</em> OK with this?</p>



<p>Do this right now: Count slowly from 1 to 30, to get a feel of what half a minute is like. Would you wait that long for a website to load? Unless you&#8217;re working for a government website, I&#8217;m guessing you probably care about SEO at least a tiny bit.</p>



<p>So please, next time you see a web script timing out, don&#8217;t just blindly increase timeout limits. Dig a little deeper in your log files, do some tests, debug a little. Does the issue occur with all scripts or just with some? What do the PHP-FPM logs say? Are the worker threads up and running? What&#8217;s the memory situation like on your server? Maybe add a few debug prints in your script, or do some profiling?</p>



<p>If you&#8217;re on a CMS like WordPress, try disabling some plugins. Switch to another theme. Tinker with your caches. Try to isolate the component that causes the issue.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p>I don&#8217;t know what&#8217;s wrong with your server. But I know it shouldn&#8217;t be taking over half a minute to respond to an HTTP request. So please, do your job as an engineer, and look for the root cause of the issue.</p>



<p>Same goes for maximum memory, worker threads count etc. Don&#8217;t just increase numbers at random. Look at your traffic first. What amount of worker threads do you need? What do your scripts need in terms of resources? You know that these things use CPU and memory, right?</p>
<p>The post <a href="https://www.alexgeorgiou.gr/error-408/">⌛ How NOT to fix error &#8220;upstream timed out (110: Connection timed out)&#8221;</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/error-408/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>💩 Please, WordPress theme and plugin developers, learn to write proper HTML already&#8230; smh</title>
		<link>https://www.alexgeorgiou.gr/how-to-html-in-wordpress/</link>
					<comments>https://www.alexgeorgiou.gr/how-to-html-in-wordpress/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 07 Feb 2020 17:28:38 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ARIA]]></category>
		<category><![CDATA[code quality]]></category>
		<category><![CDATA[code style]]></category>
		<category><![CDATA[coding standards]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[markup]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[open graph]]></category>
		<category><![CDATA[output buffering]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[schema.org]]></category>
		<category><![CDATA[string interpolation]]></category>
		<category><![CDATA[templating]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=303</guid>

					<description><![CDATA[<p>Use PHP output buffering in WordPress to interpolate HTML code and dynamic values in a way that's more readable.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/how-to-html-in-wordpress/">💩 Please, WordPress theme and plugin developers, learn to write proper HTML already&#8230; smh</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>I know, I know, I&#8217;ve <a href="https://www.alexgeorgiou.gr/wordpress-php-code-quality/">ranted before about code quality</a>, but today I want to focus more on how we, as WordPress theme and plugin developers, write HTML.</p>



<h2 class="wp-block-heading">Don&#8217;t print out too early</h2>



<p>We&#8217;ve all been there: You&#8217;ve happily opened your PHP tag, <code>&lt;?php</code>, at the beginning of the file, at character #1. Your file is going to contain only code, no markup. Perhaps the file is included before any HTML output has even begun.</p>



<p>Being the savvy PHP developer that you are, you know all too well, that if your code were to output even one extra white-space, that would screw up the page&#8217;s markup. You&#8217;re careful not to use any closing <code>?&gt;</code> tag at the end of the file, to avoid any mishaps. Even a stray linefeed character could trigger output buffering early, and then out goes any chance for other code to modify the HTTP response headers, among other things.</p>



<p>So now you&#8217;re happily defining your functions, classes and other code-y stuff, then all of a sudden, you need to build some markup! Perhaps you&#8217;re printing out a UI element, maybe it&#8217;s a widget, maybe it&#8217;s a shortcode, maybe it&#8217;s even an RSS feed or other XML, but in any case, it&#8217;s too small for you to define an entire <a rel="noreferrer noopener" aria-label="template-part (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/get_template_part/" target="_blank">template-part</a>. Your string is going to be some concatenation of hard-coded markup and dynamic data that&#8217;s currently sitting in variables.</p>



<h2 class="wp-block-heading">How To Meet Ladies</h2>



<p>Everyone says they know HTML. But HTML is easy to get started with, and hard to master.</p>



<p>When writing HTML markup for a theme or plugin in WordPress, your professional-grade code must fulfill a number of simultaneous requirements. Your main concerns should be to:</p>



<ul class="wp-block-list"><li>Write correct HTML5 markup that is SEO friendly, using semantic tags where possible (e.g. <code>&lt;nav&gt;</code>, <code>&lt;article&gt;</code>, <code>&lt;aside&gt;</code>, etc).</li><li>Escape any values properly</li><li><a href="https://www.alexgeorgiou.gr/make-pot-wordpress/">Internationalize strings so they can be translated</a></li><li>Give unique IDs to your elements, and name your classes properly, to assist any CSS and JS assets that go with your markup. Remember, naming things is one of the two hard things in computer science!</li><li>Conform to the <a href="https://make.wordpress.org/core/handbook/best-practices/coding-standards/html/" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">WordPress HTML Coding Standards</a>. This is a good standard to follow, because it forces you to be consistent about how to open and close your PHP tags, among other things.</li><li>Depending on use case, optionally add semantic metadata, such as <a rel="noreferrer noopener" href="http://microformats.org/" target="_blank">microformats.org</a>, <a rel="noreferrer noopener" href="https://schema.org/" target="_blank">schema.org</a>, <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://ogp.me/" target="_blank">Open Graph</a>, <a rel="noreferrer noopener" href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA" target="_blank">ARIA</a>, etc</li></ul>



<h2 class="wp-block-heading">A concrete example</h2>



<p>So let&#8217;s say you want to output some HTML form when a shortcode is used. We&#8217;ll give the form a unique ID and we&#8217;ll also embed some default values, coming from the shortcode&#8217;s attributes.</p>



<h3 class="wp-block-heading">Don&#8217;t do this:</h3>



<p>You might be tempted to do the following:</p>



<pre class="wp-block-preformatted"><code>$id = uniqid( 'form' );</code>
<code>$html  = '&lt;form id="' . esc_attr( $id ) . '"&gt;';</code>
<code>$html .= '&lt;input type="text" name="name" placeholder="' . esc_attr( 'Enter your name', 'langdomain' ) . '" value="' . esc_attr( $atts['name'] ) . '" /&gt;';</code>
<code>$html .= '&lt;input type="number" name="age" placeholder="' . esc_attr( 'Enter your age', 'langdomain' ) . '" value="' . absint( $atts['age'] ) . '" /&gt;';</code>
<code>$html .= '&lt;button type="submit"&gt;' . esc_html( 'Submit', 'langdomain' ) . '&lt;/button&gt;';</code>
<code>$html .= '&lt;/form&gt;';</code></pre>



<p>Sadly, a lot of people would say this is fine! I can&#8217;t blame them too much. We&#8217;re all way too used to opening the PHP tag and then never closing it again: we tend to use PHP as if it was Java. And with so many PHP templating libraries out there, it&#8217;s hard to remember that PHP <em>is</em> primarily a templating tool.</p>



<h3 class="wp-block-heading">Do this instead:</h3>



<p>We can combine the awesome templating power of the language with some cleverly nested <a rel="noreferrer noopener" aria-label="output bufferin (opens in a new tab)" href="https://www.php.net/manual/en/book.outcontrol.php" target="_blank">output buffering</a>, and now the above can be re-written as follows:</p>



<pre class="wp-block-preformatted"><code>$id = uniqid( 'form' );</code>

<code>ob_start();</code>
<code>?&gt;</code>
<code>&lt;form id="&lt;?php esc_attr_e( $id ); ?&gt;"&gt;</code>

    <code>&lt;input type="text" name="name" placeholder="&lt;?php esc_attr_e( 'Enter your name', 'langdomain' ); ?&gt;" value="&lt;?php esc_attr_e( $atts['name'] ); ?&gt;" /&gt;</code>
    <code>&lt;input type="number" name="age" placeholder="&lt;?php esc_attr_e( 'Enter your age', 'langdomain' ); ?&gt;" value="&lt;?php esc_attr_e( $atts['age'] ); ?&gt;" /&gt;</code>

    <code>&lt;button type="submit"&gt;&lt;?php esc_html_e( 'Submit', 'langdomain' ); ?&gt;&lt;/button&gt;</code>
<code>&lt;/form&gt;</code>
<code>&lt;?php</code>
<code>return ob_get_clean();</code></pre>



<p>To see a somewhat more complete example, here&#8217;s the above as a gist:</p>



<script src="https://gist.github.com/alex-georgiou/2299b24680e4fe5258ac0285044b8e56.js"></script>



<p>Notice how we start a new output buffer with <code><a rel="noreferrer noopener" aria-label="ob_start() (opens in a new tab)" href="https://www.php.net/manual/en/function.ob-start.php" target="_blank">ob_start()</a></code> and how we then get the resulting string with <code><a rel="noreferrer noopener" aria-label="ob_get_clean() (opens in a new tab)" href="https://www.php.net/manual/en/function.ob-get-clean.php" target="_blank">ob_get_clean()</a></code>. Notice also how we&#8217;ve swapped <code><a rel="noreferrer noopener" aria-label="esc_html() (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/esc_html/" target="_blank">esc_html()</a></code> with <code><a rel="noreferrer noopener" aria-label="esc_html_e() (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/esc_html_e/" target="_blank">esc_html_e()</a></code> and <code><a rel="noreferrer noopener" aria-label="esc_attr() (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/esc_attr/" target="_blank">esc_attr()</a></code> with <code><a rel="noreferrer noopener" aria-label="esc_attr_e() (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/esc_attr_e/" target="_blank">esc_attr_e()</a></code>. Similarly, we would swap <code><a rel="noreferrer noopener" aria-label="sprintf() (opens in a new tab)" href="https://www.php.net/manual/en/function.sprintf.php" target="_blank">sprintf()</a></code> with <code><a rel="noreferrer noopener" aria-label="printf (opens in a new tab)" href="https://www.php.net/manual/en/function.printf.php" target="_blank">printf</a>()</code>, <code><a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://developer.wordpress.org/reference/functions/checked/" target="_blank">checked( $value, true, false )</a></code> with <code>checked( $value, true )</code>, and so on.</p>



<p><strong>PRO TIP:</strong> If your code throws an exception, you can use <code><a rel="noreferrer noopener" aria-label="ob_end_clean() (opens in a new tab)" href="https://www.php.net/manual/en/function.ob-end-clean.php" target="_blank">ob_end_clean()</a></code> in your <code>catch</code> clause to cancel your buffer.</p>



<h2 class="wp-block-heading">&#8220;Why does it even matter&#8221;, you ask?</h2>



<p>Well, there&#8217;s a few advantages with the second form of our, err&#8230;, form!</p>



<ul class="wp-block-list"><li><strong>Readability.</strong> I find the second piece of code to be much more readable.</li><li><strong>Syntax coloring.</strong> Yes, some editors do perform HTML parsing and show visual queues related to the syntax of HTML inside strings. But not every editor does this, and the ones that do, cannot do this perfectly.</li><li><strong>No quote hell.</strong> No need to count opening and closing <code>'</code> characters, interpolated with <code>"</code> characters while printing HTML attributes. This business can quickly get confusing, and is a common source of errors.</li><li><strong>Show off</strong> your mad PHP output buffering skillz! Your average front-end developer will be astonished at your professional-looking code!</li></ul>



<p>Now, if only we were allowed to use shorthand PHP tags, our code could be even nicer. Sadly, <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#no-shorthand-php-tags" target="_blank">we can&#8217;t</a>.</p>



<p><code>?&gt;</code></p>
<p>The post <a href="https://www.alexgeorgiou.gr/how-to-html-in-wordpress/">💩 Please, WordPress theme and plugin developers, learn to write proper HTML already&#8230; smh</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/how-to-html-in-wordpress/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>💩 Your WordPress PHP code stinks! Here&#8217;s why.</title>
		<link>https://www.alexgeorgiou.gr/wordpress-php-code-quality/</link>
					<comments>https://www.alexgeorgiou.gr/wordpress-php-code-quality/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Mon, 22 Jul 2019 18:12:52 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[code quality]]></category>
		<category><![CDATA[code style]]></category>
		<category><![CDATA[envato]]></category>
		<category><![CDATA[grunt]]></category>
		<category><![CDATA[grunt-phpcs]]></category>
		<category><![CDATA[phan]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpcbf]]></category>
		<category><![CDATA[phpcs]]></category>
		<category><![CDATA[phpdoc]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[requirements]]></category>
		<category><![CDATA[themeforest]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wordpress.org]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=282</guid>

					<description><![CDATA[<p>Developing a WordPress theme or plugin? Learn how to use phan and phpcs to improve the quality of your WordPress PHP code.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/wordpress-php-code-quality/">💩 Your WordPress PHP code stinks! Here&#8217;s why.</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>In software development, as in all forms of engineering, we strive to produce results that satisfy a multitude of constraints, some more obvious than others. High <em>code quality</em> should be in your list of constraints when you write WordPress PHP code. And there are tools out there that can help you!</p>



<h3 class="wp-block-heading">First, some theory</h3>



<p>In a fantasy world where unicorns poop chocolate fudge and everything is awesome, it all goes down somewhat like this: You talk with the client or end user, and you gather up a list of things they want. You collect and number these in a <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://en.wikipedia.org/wiki/User_requirements_document" target="_blank">requirements document</a>, braking them up into <strong>Functional</strong> requirements, <strong>Non-functional</strong> requirements, and other <strong>Design constraints</strong>. Then, you design a solution, write your tests, and implement your code. Once all of the requirements in the document are met, you are <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.agilealliance.org/glossary/definition-of-done/" target="_blank">done</a>, and you get paid. Easy! Deviate from this simple methodology <strong>at your own peril.</strong> (Oh, and you also then need to maintain, fix and improve the code you&#8217;ve written.)</p>



<p>As a software engineer, you should know that in addition to what the client asks for, there are always <em>implicit</em> requirements. For example, your code must be <strong>readable</strong> and <strong>maintainable</strong>, and it must be <strong>reliable</strong> (read: not too buggy). All of these are aspects of <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://en.wikipedia.org/wiki/Software_quality" target="_blank">code quality</a>. A client or end user will never ask you for these, but you should have them in your list of non-functional requirements.</p>



<p>Professional developers write simple, clear code where a novice would write complex, intricate code to solve that same problem. Sure, a lot of this is just a matter of practice and experience.</p>



<p>Dev tools can help you with code quality whether you&#8217;re novice or pro. They help you discover issues that you don&#8217;t know about, and they help you discover issues that you do know about, faster!</p>



<p>If you are developing themes or plugins, here&#8217;s two tools that you definitely want to use as a professional WordPress developer:</p>



<h3 class="wp-block-heading">Improve WordPress PHP <a href="https://en.wikipedia.org/wiki/Code_smell" target="_blank" rel="noreferrer noopener" aria-label="code smell (opens in a new tab)">code smell</a> with CodeSniffer</h3>



<p>There are some <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://codex.wordpress.org/WordPress_Coding_Standards" target="_blank">styling guidelines</a> that all WordPress developers should follow. Especially if you are aspiring to upload your code to wordpress.org, or to the Envato Market (ThemeForest or CodeCanyon), then you definitely want to follow these guidelines. Generally, these get encoded into your muscle memory pretty quickly, but it&#8217;s always a great idea to have a tool like <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://github.com/squizlabs/PHP_CodeSniffer" target="_blank">PHP CodeSniffer</a> that double-checks your code style.</p>



<p>On my Ubuntu machine, I was able to install PHP CodeSniffer easily with:</p>



<pre class="wp-block-preformatted">sudo apt install php-codesniffer</pre>



<p>Then, it&#8217;s just a matter of loading the <a href="https://github.com/WordPress/WordPress-Coding-Standards" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">WordPress-specific set of rules</a>. Go to your home directory and clone the project:</p>



<pre class="wp-block-preformatted">git clone https://github.com/WordPress/WordPress-Coding-Standards ~/wpcs</pre>



<p>And tell CodeSniffer the location of these rules:</p>



<pre class="wp-block-preformatted">sudo phpcs --config-set installed_paths ~/wpcs</pre>



<p>Check that <a href="https://github.com/WordPress/WordPress-Coding-Standards#standards-subsets" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">the new rules</a> are added into CodeSniffer with:</p>



<pre class="wp-block-preformatted">phpcs -i</pre>



<p>Congratulations! You can now check your plugin for code style with a command such as:</p>



<pre class="wp-block-preformatted">phpcs --standard=Wordpress-Core /path/to/source/code/root/dir</pre>



<p>If, <a href="https://www.alexgeorgiou.gr/increasingly-verbose-gruntfile/">like me</a>, you&#8217;re using <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://gruntjs.com/" target="_blank">grunt</a> for your build process, then there&#8217;s a nifty Grung plugin, <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://github.com/SaschaGalley/grunt-phpcs" target="_blank">grunt-phpcs</a>. Just make sure to specify <code>WordPress-core</code> as the rule set. Here&#8217;s a <code>grunt</code> target that you might use:</p>



<pre class="wp-block-preformatted">phpcs: {
    plugin: {
        src: ['src/**/*.php']
    },
    options: {
        bin: '/usr/bin/phpcs',
        standard: 'WordPress-core'
    }
}</pre>



<p>Run it against your code and you will get a number of improvement suggestions. Some of these can be applied automatically with <code>PHPCBF</code> (the <strong>PHP Code Beautifier and Fixer</strong>), or you can go through the list manually and apply each suggestion as you see fit. Many of the suggestions will be related to code indentation, but you will also see a large number of other suggestions that are more critical.</p>



<h3 class="wp-block-heading">Improve WordPress PHP code correctness with phan</h3>



<p>PHP is a very lenient language. It will let you get away with murder. This is something that novice programmers often enjoy. For professionals it&#8217;s a nightmare, as it makes spotting errors harder. PHP has thus gained somewhat of a notoriety for being a bad language, and is the butt of some <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://www.reddit.com/r/ProgrammerHumor/comments/6k40cb/working_at_pornhub/" target="_blank">clever jokes</a>.</p>



<p>This isn&#8217;t something to worry about. It has happened to many respectable languages, including JavaScript. So nowadays we have <code>use strict</code>, which lets us only use <a rel="noreferrer noopener" aria-label="The Good Parts (opens in a new tab)" href="http://shop.oreilly.com/product/9780596517748.do" target="_blank">The Good Parts</a> of the language. You can do something similar with PHP.</p>



<p>My point is that <a href="https://en.wikipedia.org/wiki/Static_program_analysis">static code analysis</a> is not the hero you want, but it&#8217;s definitely the hero you deserve. Enter <code><a rel="noreferrer noopener" aria-label="phan (opens in a new tab)" href="https://github.com/phan/phan" target="_blank">phan</a></code>:</p>



<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="PHP in 2018 by the Creator of PHP" width="840" height="473" src="https://www.youtube.com/embed/rKXFgWP-2xQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div><figcaption><a href="https://en.wikipedia.org/wiki/Rasmus_Lerdorf">Rasmus Lerdorf</a>, the creator of PHP, discusses static code analysis with phan</figcaption></figure>



<p>First, install it. It&#8217;s straightforward to install <code>phan</code> with <code>composer</code>:</p>



<pre class="wp-block-preformatted">composer require phan/phan</pre>



<p>Now <code>phan</code> lives in your project&#8217;s <code>vendor/</code> dir.</p>



<p>Next, create a configuration under your project dir, in <code>.phan/config.php</code>. This will tell <code>phan</code> what settings you want to run it with. Start with the <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://github.com/phan/phan/wiki/Getting-Started#creating-a-config-file" target="_blank">example given here</a>, and set your source code directories.</p>



<p>You will also want to point to some third-party code, including the directory of your WordPress installation, since your code will invariably use WordPress functions and types.</p>



<p>You can also use this config file to exclude some rules, so that <code>phan</code> does not check for them. <a href="https://github.com/phan/phan/blob/master/.phan/plugins/README.md">Here&#8217;s the complete list of <code>phan</code> <em>plugins</em></a>.</p>



<p>When all is set, you can call <code>phan</code> on your code with:</p>



<pre class="wp-block-preformatted">vendor/bin/phan</pre>



<p>I don&#8217;t care how pro you are, you will definitely get a list of suggestions on how to improve your code.</p>



<h3 class="wp-block-heading">Conclusion</h3>



<p>Using <code>phpcs</code> and <code>phan</code> together, you will avoid a large number of errors that would otherwise likely go undetected. These include errors with translator comments over strings, <a rel="noreferrer noopener" aria-label=" (opens in a new tab)" href="https://phpdoc.org/" target="_blank">phpDoc</a> formatting errors, variable type errors, errors related to sentinel values such as <code>null</code>, and array indexing errors.</p>



<p>Always use these two tools together with <code>phpunit</code> when you write code. You will write more readable, maintainable, correct and robust code that you can feel confident about.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/wordpress-php-code-quality/">💩 Your WordPress PHP code stinks! Here&#8217;s why.</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/wordpress-php-code-quality/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>❏ How to render an SVG with a feDropShadow filter to PNG raster</title>
		<link>https://www.alexgeorgiou.gr/render-svg-fedropshadow-filter/</link>
					<comments>https://www.alexgeorgiou.gr/render-svg-fedropshadow-filter/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Thu, 30 Aug 2018 22:54:11 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[button]]></category>
		<category><![CDATA[convert]]></category>
		<category><![CDATA[drop shadow]]></category>
		<category><![CDATA[feDropShadow]]></category>
		<category><![CDATA[icon]]></category>
		<category><![CDATA[ImageMagick]]></category>
		<category><![CDATA[inkscape]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[raster]]></category>
		<category><![CDATA[SVG]]></category>
		<category><![CDATA[vector graphics]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=271</guid>

					<description><![CDATA[<p>Render an SVG that uses the feDropShadow filter to a raster file such as PNG, using a PHP script.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/render-svg-fedropshadow-filter/">❏ How to render an SVG with a feDropShadow filter to PNG raster</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In one of my most recent geeky escapades, I was attempting to automate generation of some icons / buttons. Turns out all is fun and games, until someone uses <code>feDropShadow</code>.</p>
<h2>There&#8217;s more than one ways to raster an SVG</h2>
<p>There&#8217;s tons of reasons why you wouldn&#8217;t want to generate a bunch of icons with a clumsy UI, such as Adobe Illustrator or Inkscape. You can set up a script that dumps your icons out as SVG, then add something that auto-converts to PNG. Think of the possibilities:</p>
<ul>
<li><strong>Parametrize your pipeline:</strong> Flip one parameter, run again, voila! A new batch of icons, with a different color or stroke width or font family, all freshly baked!</li>
<li><strong>Add a time dimension:</strong> Run multiple times with some variation, then join the results to&nbsp;<a href="https://askubuntu.com/questions/648244/how-to-create-a-gif-from-the-command-line" target="_blank" rel="noopener noreferrer">create animated GIFs</a>.</li>
<li><strong>Expand the range of glyphs:</strong> With a small change in your code, you can render any range of unicode glyphs. Think currency symbols, tool buttons, numbers, etc.</li>
<li><strong>Tile all the buttons into a sprite:</strong> Then, use the CSS <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background-position" target="_blank" rel="noopener noreferrer"><code>background-position</code></a> rule to display the right button at the right place. The browser will only do one HTTP request to download all the buttons.</li>
</ul>
<p>Why would you do all that, you say?</p>
<p>Well, for one, you could try to sell icon collections on places like <a href="https://www.vectorstock.com" target="_blank" rel="noopener noreferrer">vectorstock.com</a>. Once you have a pipeline ready, you can flood the market! Or so I theorize&#8230;</p>
<p>Also, code is beautiful!</p>
<h3>Way 1: Native PHP</h3>
<p>You could use the <a href="http://php.net/manual/en/book.imagick.php" target="_blank" rel="noopener noreferrer">PHP ImageMagick library</a> to generate your PNG file. In the following example, I will write out some SVG for the Bitcoin icon, using the <a href="https://www.fileformat.info/info/unicode/char/20bf/index.htm" target="_blank" rel="noopener noreferrer">Unicode character</a> and some <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform" target="_blank" rel="noopener noreferrer">rotation</a>.</p>
<pre>&lt;?php

ob_start();

$text = '&amp;#x20bf;';

?&gt;&lt;?xml version="1.0"?&gt;
&lt;svg
	xmlns="http://www.w3.org/2000/svg"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	viewBox="0 0 64 64"&gt;

    &lt;circle
		fill="orange"
		stroke="transparent"
		cx="32"
		cy="32"
		r="31"
		stroke-width="0"&gt;
	&lt;/circle&gt;


    &lt;text
		transform="rotate(10 32 32)"
		x="50%"
		y="50%"
		text-anchor="middle"
		fill="white"
		font-size="36pt"
		stroke="0"
		dy=".3em"&gt;
		
		&lt;?php echo $text; ?&gt;
	&lt;/text&gt;
&lt;/svg&gt;
&lt;?php

$svg = ob_get_clean();

// write out the SVG to file
file_put_contents( 'bitcoin-icon.svg', $svg );

// now use Imagick to render the button to raster
$im = new Imagick();
$im-&gt;setBackgroundColor( new ImagickPixel( 'transparent' ) );
$im-&gt;readImageBlob( $svg );
$im-&gt;setImageFormat( "png24" );
$im-&gt;writeImage( 'bitcoin-icon.png' );
$im-&gt;clear();
$im-&gt;destroy();</pre>
<p>Not too shabby! You can now use the full power of PHP templating to wrap this code into loops and generate all kinds of icons. Parametrise colors, sizes, stroke widths, etc.</p>
<p><div id="attachment_272" style="width: 71px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-272" class="wp-image-272 size-full" src="https://www.alexgeorgiou.gr/wp-content/uploads/2018/08/bitcoin-icon.png" alt="Bitcoin icon generated using some custom PHP" width="61" height="61"><p id="caption-attachment-272" class="wp-caption-text">bitcoin-icon.png</p></div></p>
<h3>Way 2: Convert</h3>
<p><a href="https://www.imagemagick.org/" target="_blank" rel="noopener noreferrer">ImageMagick</a> can be invoked on Linux systems with the <code>convert</code> command.</p>
<pre>convert bitcoin-icon.svg bitcoin-icon.png</pre>
<h3>Way 3: Inkscape CLI</h3>
<p>Inkscape can be used from the command line to convert an SVG to PNG. Here&#8217;s how:</p>
<pre>inkscape -z bitcoin-icon.svg -e bitcoin-icon.png</pre>
<p>Depending on various details of your SVG file, and on the current phase of the moon, this way might give you a better result compared to the other two.</p>
<h2>Keep your face to the PNG and you cannot see a shadow</h2>
<p>If you are a novice user of Scalable Vector Graphics, you might think that you can add a drop shadow with this well-known incantation:</p>
<pre>&lt;svg ... &lt;!-- header goes here as before --&gt;

	&lt;defs&gt;
		&lt;filter id="shadow"&gt;
			&lt;feDropShadow dx="4" dy="8" stdDeviation="4"/&gt;
		&lt;/filter&gt;
	&lt;/defs&gt;

	&lt;g filter="url(#shadow)"&gt;
		&lt;!-- rest of SVG shapes go here as before --&gt;
	&lt;/g&gt;
&lt;/svg&gt;</pre>
<p>You could, but only web browsers would render the output with a shadow. None of the three methods above render the shadow correctly. In fact, even the preview renderer in <a href="https://en.wikipedia.org/wiki/GNOME_Files" target="_blank" rel="noopener noreferrer">Nautilus</a> screws up when it sees this filter.</p>
<h2>When small scripts begin to cast big shadows</h2>
<p>What to do now? Simple. A quick look at the <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDropShadow" target="_blank" rel="noopener noreferrer">MDN docs</a> reveals that <code>feDropShadow</code> is a <em>filter primitive</em>, and it is equivalent to a bunch of simpler filters, <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feMerge" target="_blank" rel="noopener noreferrer">merged</a> together. Let&#8217;s try the whole thing again, this time spelling the shadow out a bit more verbosely:</p>
<p><script src="https://gist.github.com/alex-georgiou/fa311a92184859dd33f5055a93adbca2.js"></script></p>
<p>It seems that the <code>feDropShadow</code> filter is not yet supported in ImageMagick. At least not in the version I&#8217;m using. But the primitives it depends on, are!</p>
<p>&nbsp;</p>
<p><div id="attachment_273" style="width: 131px" class="wp-caption aligncenter"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-273" class="size-full wp-image-273" src="https://www.alexgeorgiou.gr/wp-content/uploads/2018/08/bitcoin-icon-shadow.png" alt="Bitcoin icon with shadow, generated using some custom PHP" width="121" height="121"><p id="caption-attachment-273" class="wp-caption-text">bitcoin-icon.png</p></div></p>
<p>The post <a href="https://www.alexgeorgiou.gr/render-svg-fedropshadow-filter/">❏ How to render an SVG with a feDropShadow filter to PNG raster</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/render-svg-fedropshadow-filter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
