<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jose De Gouveia</title>
    <description>The latest articles on DEV Community by Jose De Gouveia (@dhgouveia).</description>
    <link>https://dev.to/dhgouveia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F387355%2F17ecc593-f251-4aa2-8138-cc3e31187525.jpg</url>
      <title>DEV Community: Jose De Gouveia</title>
      <link>https://dev.to/dhgouveia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhgouveia"/>
    <language>en</language>
    <item>
      <title>How to serve a Vite + Vue3 page inside a sub-folder</title>
      <dc:creator>Jose De Gouveia</dc:creator>
      <pubDate>Tue, 17 Jan 2023 12:55:25 +0000</pubDate>
      <link>https://dev.to/dhgouveia/how-to-serve-a-vite-vue3-page-inside-a-sub-folder-5h8a</link>
      <guid>https://dev.to/dhgouveia/how-to-serve-a-vite-vue3-page-inside-a-sub-folder-5h8a</guid>
      <description>&lt;p&gt;Today I've spent a quite long amount of time trying to figure out how to just serve a Vue3 + Vite page inside a sub-folder, so i decided to make a very quick post to help any people in the same situation. &lt;/p&gt;

&lt;p&gt;So the URL was like &lt;code&gt;https://example.com/my-page/&lt;/code&gt;, and to make this happens, you need two changes&lt;/p&gt;

&lt;p&gt;The first one is on &lt;code&gt;vite.config.ts&lt;/code&gt; or &lt;code&gt;.js&lt;/code&gt;, and add the parameter &lt;code&gt;base: ''&lt;/code&gt;, when using &lt;code&gt;''&lt;/code&gt; will work with any sub-folder, since the &lt;code&gt;index.html&lt;/code&gt; assets URLs will start with &lt;code&gt;./&lt;/code&gt; and use the relative path&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="p"&gt;...,&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// or the path instead if you want '/my-page/'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second change, is inside your vue router , in my case &lt;code&gt;src/router/index.ts&lt;/code&gt; and add the parameter base in &lt;code&gt;createWebHistory(base?: string)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createWebHistory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/my-page/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could experiment with &lt;code&gt;location.pathname&lt;/code&gt; to make it agnostic of the folder name, but on my testing, it fail after navigating to another route&lt;/p&gt;

&lt;p&gt;Alternatively, you could modify your &lt;code&gt;index.html&lt;/code&gt; instead of the router and just add the base tag like this &lt;code&gt;&amp;lt;base href="https://example.com/my-page/"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that if you go to another route, ex: &lt;code&gt;https://example.com/my-page/my-route&lt;/code&gt; and refresh the page, it might show you the root page of &lt;code&gt;https://example.com/&lt;/code&gt;, this is something you will need to fix via your web server config such nginx, and doing that you might not need to do all these changes mentioned above, i recommend this setup just for showing a work in progress project, or one page landing, etc&lt;/p&gt;

&lt;p&gt;I hope this was helpful.&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://v3.vitejs.dev/config/shared-options.html#base" rel="noopener noreferrer"&gt;https://v3.vitejs.dev/config/shared-options.html#base&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://router.vuejs.org/api/#createwebhistory" rel="noopener noreferrer"&gt;https://router.vuejs.org/api/#createwebhistory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Write modern PHP without a framework</title>
      <dc:creator>Jose De Gouveia</dc:creator>
      <pubDate>Mon, 01 Jun 2020 16:00:49 +0000</pubDate>
      <link>https://dev.to/dhgouveia/write-modern-php-without-a-framework-5409</link>
      <guid>https://dev.to/dhgouveia/write-modern-php-without-a-framework-5409</guid>
      <description>&lt;p&gt;Since the introduction of &lt;a href="https://getcomposer.org/doc/00-intro.md" rel="noopener noreferrer"&gt;Composer&lt;/a&gt; package manager and the &lt;a href="https://php7.org/guidelines/" rel="noopener noreferrer"&gt;PHP standards&lt;/a&gt;, writing PHP became easier and more manageable, whereas in the past you were almost forced to use a framework to maintain your project in a professional matter, nowadays this is not necessary, and today I will show you how to glue together a small API project with basic routing, third party packages, and testing without a framework.&lt;/p&gt;

&lt;p&gt;There are few reasons why you don't want to use a framework, you are creating a library, a small app/API, have more control and so forth, depending on your cases you might want to use a framework don't get me wrong.&lt;/p&gt;

&lt;p&gt;Our goal is to create a simple Blog Api, each post will have an &lt;strong&gt;id, title, and body&lt;/strong&gt;, you will able to list, create and view a post, we won't use any database, a simple JSON file that will act as DB should be enough, all request/responses will be in JSON format&lt;/p&gt;

&lt;p&gt;As you see, there are some fields and features missing, like slug, summary, published date, author, tags, categories and so forth, or ability to delete/update, I decided to not implement those and I'll briefly explain some classes and code without getting into too much detail to make this article shorter, if you need extra explanation of any step please leave it in the comments and I will do my best to help you there.&lt;/p&gt;

&lt;p&gt;All code is available in &lt;a href="https://gitlab.com/dhgouveia/medium-blog-api" rel="noopener noreferrer"&gt;https://gitlab.com/dhgouveia/medium-blog-api&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP 7.0 or greater&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;li&gt;Basic knowledge of PHP, classes, composer, MVC pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Composer
&lt;/h2&gt;

&lt;p&gt;The first thing we need to do is create our &lt;code&gt;composer.json&lt;/code&gt; needed to add 3rd party packages and manage our project with the autoloading feature, this will make importing classes easier.&lt;/p&gt;

&lt;p&gt;Create a folder and type &lt;code&gt;composer init&lt;/code&gt; in your terminal and fill the information, it will create the &lt;code&gt;composer.json&lt;/code&gt; file for us, then create our basic folder structure with some empty files called &lt;code&gt;index.php&lt;/code&gt;, &lt;code&gt;config.php&lt;/code&gt; and an empty folder called &lt;code&gt;App&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F131%2F1%2AJPhVAm5DkfciT_KMwa4Olg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F131%2F1%2AJPhVAm5DkfciT_KMwa4Olg.png" alt="Folder Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's add the first package by using the command line &lt;code&gt;composer require monolog/monolog:1.25.1&lt;/code&gt;, it creates a &lt;code&gt;vendor&lt;/code&gt; folder with the package we just added and a file called &lt;code&gt;autoload.php&lt;/code&gt;, this file will contain all the path to the classes we add from 3rd parties and ours, &lt;code&gt;monolog&lt;/code&gt; is a package to create logs files that will be used later on&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;index.php&lt;/code&gt; and fill it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;modify the &lt;code&gt;composer.json&lt;/code&gt; by adding the &lt;code&gt;autoload&lt;/code&gt; entry after the &lt;code&gt;type&lt;/code&gt; entry&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"type": "project",
"autoload": {
  "psr-4": {
    "App\\": "App/"
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;then type &lt;code&gt;composer dump-autoload&lt;/code&gt; to update the &lt;code&gt;autoload&lt;/code&gt; entries, the &lt;code&gt;autoload&lt;/code&gt; entry will register all our classes to be used anywhere in our app, &lt;code&gt;psr-4&lt;/code&gt; is a more flexible autoloading standard specification than &lt;code&gt;psr-0&lt;/code&gt;, you don't need to regenerate the autoloader when you add classes or have folders that match your namespaces structure for example.&lt;/p&gt;

&lt;p&gt;By now, the app is already setup to work with composer, you can run &lt;code&gt;php index.php&lt;/code&gt; in the terminal, if no error is shown it means is working, this shouldn't output anything&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding our first class
&lt;/h2&gt;

&lt;p&gt;Let's make a Config helper to use across the project, we are going to have 2 files, &lt;code&gt;config.php&lt;/code&gt; at the root of the project, with some settings for the app, here is where you put your API Key, Cache setting, etc, and you should have a different one base on your environment (test, stage, prod), and the other file will be &lt;code&gt;App/Lib/Config.php&lt;/code&gt; to read those variables&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;config.php&lt;/code&gt; and fill it with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'LOG_PATH'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'./logs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;create a new file inside &lt;code&gt;App/Lib/&lt;/code&gt; called it &lt;code&gt;Config.php&lt;/code&gt; and paste this code&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Lib/Config.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This code reads the Array from &lt;code&gt;config.php&lt;/code&gt; and check if the key exists in the array, if so return the value otherwise return the default value given&lt;/p&gt;

&lt;p&gt;Let's check if working by editing the &lt;code&gt;index.php&lt;/code&gt; adding these lines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// New lines&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Lib\Config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'LOG_PATH'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[LOG_PATH]: &lt;/span&gt;&lt;span class="nv"&gt;$LOG_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;now run &lt;code&gt;php index.php&lt;/code&gt; and should output the path of the logs specified on &lt;code&gt;config.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It seems not much but at this point, you should be getting an idea how the rest of the code will work, we'll add some classes into &lt;code&gt;App&lt;/code&gt; folder and thanks to the autoloading will be accessible anywhere in the app.&lt;/p&gt;

&lt;p&gt;So if you manage to follow along until here, congrats! grab some coffee and let's continue.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Logging
&lt;/h2&gt;

&lt;p&gt;Earlier we added the &lt;code&gt;monolog&lt;/code&gt; package to our dependencies, this package contains a series of classes and helper to manage logs. Logging is an essential part of any app since it will be the first thing you'll check when anything goes wrong and packages like &lt;strong&gt;&lt;a href="https://github.com/Seldaek/monolog" rel="noopener noreferrer"&gt;monolog&lt;/a&gt;&lt;/strong&gt; make this job easier and even the possibility to send those via email, slack, telegram, you name it!, for this app, I want to create three simple log files &lt;code&gt;errors.log&lt;/code&gt;, &lt;code&gt;requests.log&lt;/code&gt; and &lt;code&gt;app.log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;errors&lt;/strong&gt; and &lt;strong&gt;requests&lt;/strong&gt; logs will be active all the time and &lt;strong&gt;app&lt;/strong&gt; logs will be used on demand for us to display desire information, &lt;code&gt;errors.log&lt;/code&gt; will contain any error that happens in the app, &lt;code&gt;requests.log&lt;/code&gt; will log any HTTP request made to the app&lt;/p&gt;

&lt;p&gt;create &lt;code&gt;App/Lib/Logger.php&lt;/code&gt; and paste the code below, this will be a wrapper that will manage our different logs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Lib/Logger.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;now we have two main functions &lt;code&gt;Logger::enableSystemLogs()&lt;/code&gt; this will enable our error/request logs, and then we have &lt;code&gt;Logger::getInstance()&lt;/code&gt; that by default will be our &lt;code&gt;App&lt;/code&gt; log, let's try it, modify our &lt;code&gt;index.php&lt;/code&gt; once again with these new lines&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Lib\Config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'LOG_PATH'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[LOG_PATH]: &lt;/span&gt;&lt;span class="nv"&gt;$LOG_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//New Lines&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Lib\Logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;enableSystemLogs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getInstance&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nv"&gt;$logger&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Hello World'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;type &lt;code&gt;php -S localhost:8000&lt;/code&gt; it'll run a built-in web server that is present in PHP since 5.4, navigate to &lt;code&gt;http://localhost:8000&lt;/code&gt;, you should see the &lt;strong&gt;"LOG_PATH"&lt;/strong&gt;, but if you check your &lt;code&gt;logs&lt;/code&gt; folder you will see two files, showing the requested content and another one with "Hello World" text, take a time to tweak the &lt;code&gt;request&lt;/code&gt; if you need to show specific info or remove it, this was meant to show different types of logging&lt;/p&gt;

&lt;p&gt;finally lets clean a little bit our &lt;code&gt;index.php&lt;/code&gt; and create a new file called &lt;code&gt;App/Lib/App.php&lt;/code&gt; , let's use this as a bootstrap to our app&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Lib/App.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;and update the &lt;code&gt;index.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt; &lt;span class="k"&gt;require&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Lib\App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;looks much nicer right?&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Routing
&lt;/h2&gt;

&lt;p&gt;In any modern app, routing takes a huge part of it, this will call a specific code based on the path in the URL we choose, for example &lt;code&gt;/&lt;/code&gt; could show the homepage, &lt;code&gt;/post/1&lt;/code&gt; could show the post information with id 1, for this we will implement three classes &lt;code&gt;Router.php&lt;/code&gt; , &lt;code&gt;Request.php&lt;/code&gt; and &lt;code&gt;Response.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;Router.php&lt;/code&gt; will be very basic, it will verify the request method and match the path we are giving using regex, if match, it will execute a callback function given by us with two parameters &lt;code&gt;Request&lt;/code&gt; and &lt;code&gt;Response&lt;/code&gt;, &lt;code&gt;Request.php&lt;/code&gt; will have some functions to get the data that was sent in the request, for example, the Post data such as title, body to create it, and &lt;code&gt;Response.php&lt;/code&gt; will have some functions to output as JSON with specific HTTP status.&lt;/p&gt;

&lt;p&gt;create &lt;code&gt;App/Lib/Router.php&lt;/code&gt;, &lt;code&gt;App/Lib/Request.php&lt;/code&gt;, &lt;code&gt;App/Lib/Response.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Lib/Router.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;App/Lib/Request.php&lt;/code&gt;&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
&lt;code&gt;App/Lib/Response.php&lt;/code&gt;&lt;br&gt;&lt;/p&gt;

&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;update your &lt;code&gt;index.php&lt;/code&gt; with the code below,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;type &lt;code&gt;php -S localhost:8000&lt;/code&gt; to test it and navigate to &lt;code&gt;http://localhost:8000/&lt;/code&gt; and you should see 'Hello World' and &lt;code&gt;http://localhost:8000/post/1&lt;/code&gt;, you should see a JSON response with status 'ok' and the id you gave inside 'Post'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"post"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;if you are using Apache you might need to add this &lt;code&gt;.htaccess&lt;/code&gt; file to the root of your project&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="nc"&gt;RewriteEngine&lt;/span&gt; &lt;span class="ss"&gt;On&lt;/span&gt;
&lt;span class="nc"&gt;RewriteBase&lt;/span&gt; /
&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-d
&lt;span class="nc"&gt;RewriteCond&lt;/span&gt; %{REQUEST_FILENAME} !-f
&lt;span class="nc"&gt;RewriteRule&lt;/span&gt; ^(.+)$ index.php [QSA,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;in the case of Nginx&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="n"&gt;/index.php&lt;/span&gt;&lt;span class="nv"&gt;$is_args$args&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Great! our app now have routing! is time to take a break again, go and grab some lunch! , You want to continue? ok as a bonus let's add a really simple Controller, this might be useful in the future if you want to use a template engine like &lt;a href="https://twig.symfony.com/doc/2.x/intro.html" rel="noopener noreferrer"&gt;Twig&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;create &lt;code&gt;App/Controller/Home.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Controller/Home.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;and modify the &lt;code&gt;Router::get('/',..)&lt;/code&gt; in the &lt;code&gt;index.php&lt;/code&gt; with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Controller\Home&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;indexAction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Implementing our Blog API
&lt;/h2&gt;

&lt;p&gt;Finally!, we are almost over!, in these steps, we are finally implementing our Blog API, thanks to our Router, the next steps will be easy,&lt;/p&gt;

&lt;p&gt;We will have three endpoints&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET &lt;code&gt;/post&lt;/code&gt;, list all the available post&lt;/li&gt;
&lt;li&gt;POST &lt;code&gt;/post&lt;/code&gt;, Create a new Post&lt;/li&gt;
&lt;li&gt;GET &lt;code&gt;/post/{id}&lt;/code&gt;, show and specific post&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First, we need our Posts model to handle these operations and then be called from our router&lt;/p&gt;

&lt;p&gt;create &lt;code&gt;App/Model/Posts.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;App/Model/Posts.php&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;create a &lt;code&gt;db.json&lt;/code&gt; file in the root of the project and paste this so we can have a content already to test&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My Post 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My First Content"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;modify our &lt;code&gt;config.php&lt;/code&gt; to add the &lt;code&gt;DB_PATH&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'LOG_PATH'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'./logs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'DB_PATH'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/db.json'&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;with this we already have our &lt;strong&gt;"DB"&lt;/strong&gt; setup, now we need to use it with our router, let's modify our &lt;code&gt;index.php&lt;/code&gt; to add the routes and DB call respectively&lt;/p&gt;

&lt;p&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;in this step, we added &lt;code&gt;Posts::load()&lt;/code&gt; to load our &lt;strong&gt;"DB"&lt;/strong&gt; from the &lt;code&gt;db.json&lt;/code&gt; file and created three routes GET &lt;code&gt;/post&lt;/code&gt; to list, POST &lt;code&gt;/post&lt;/code&gt; to create and GET &lt;code&gt;/post/([0–9]*)&lt;/code&gt; to get a specific post , you could move the &lt;code&gt;Posts::load()&lt;/code&gt; inside our &lt;code&gt;App::run&lt;/code&gt; method to make it cleaner.&lt;/p&gt;

&lt;p&gt;Great! let's test it!, you could use &lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;postman&lt;/a&gt;, curl, to simulate the POST request&lt;/p&gt;

&lt;p&gt;List all posts &lt;code&gt;curl -X GET http://localhost:8000/post&lt;/code&gt; should output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"My Post 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"My First Content"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;List one post &lt;code&gt;curl -X GET http://localhost:8000/post/1&lt;/code&gt; should output:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"My Post 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"My First Content"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Create a post&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
 http://localhost:8000/post &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"title": "Hello World", "body": "My Content"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally! is finished! we have our Blog Api working! if you manage to follow along until here and you didn't get bored, Congrats once again!, but before we wrap up, let's add some testing and I promise we'll finish&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding Testing
&lt;/h2&gt;

&lt;p&gt;Ok, we got this far, so let's implement some testing, for this step, I will test only our &lt;code&gt;Router.php&lt;/code&gt; with simple cases and the code styling based on &lt;code&gt;psr-2&lt;/code&gt; coding style standard, but you should take the time to test as much you can in your app, my intention is just to show you how to add this into our app and CI&lt;/p&gt;

&lt;p&gt;we need to add some package into our project, type&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; squizlabs/php_codesniffer
composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; peridot-php/peridot
composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; peridot-php/leo
composer require &lt;span class="nt"&gt;--dev&lt;/span&gt; eloquent/phony-peridot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;run in the terminal &lt;code&gt;./vendor/bin/phpcs - standard=psr2 App/&lt;/code&gt; to check if any code syntax is wrong, this will be part of our test script, but try to run it now, in case you have only white-spaces errors, you could use &lt;code&gt;./vendor/bin/phpcbf - standard=psr2 App/&lt;/code&gt; to fix it automatically.&lt;/p&gt;

&lt;p&gt;for unit testing, we are going to use my personal choice peridot but you could use any you feel comfortable, besides peridot, we have two plugins leo provides expect functionality and phony-peridot provides stubs functionality that is very handy to check if a function was called&lt;/p&gt;

&lt;p&gt;create &lt;code&gt;Test/Router.spec.php&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Test/Router.spec.php&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;modify the &lt;code&gt;composer.json&lt;/code&gt; and add this section below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="s2"&gt;"./vendor/bin/phpcs --standard=psr2 App/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="s2"&gt;"./vendor/bin/peridot Test/"&lt;/span&gt;&lt;span class="w"&gt;
   &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now to run the test, you could just type &lt;code&gt;./vendor/bin/peridot Test/&lt;/code&gt; or &lt;code&gt;composer run-script test&lt;/code&gt; or even shorter with &lt;code&gt;composer test&lt;/code&gt; all of them would do the same if everything went right you see this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1080%2F1%2AL40BYPlZPz8wlJy8JGQ-hw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmiro.medium.com%2Fmax%2F1080%2F1%2AL40BYPlZPz8wlJy8JGQ-hw.png" alt="Unit Test"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;This was a very simple project and a lot of things was left out to keep the article shorter as possible, but you could use it as a base and extended it by adding a better router, an ORM, template engine and so forth, take time and check &lt;a href="https://packagist.org/explore/popular" rel="noopener noreferrer"&gt;https://packagist.org/explore/popular&lt;/a&gt; or &lt;a href="https://thephpleague.com/#packages" rel="noopener noreferrer"&gt;https://thephpleague.com/#packages&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All code is available in &lt;a href="https://gitlab.com/dhgouveia/medium-blog-api" rel="noopener noreferrer"&gt;https://gitlab.com/dhgouveia/medium-blog-api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice to read:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.php-fig.org/" rel="noopener noreferrer"&gt;https://www.php-fig.org/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://php7.org/guidelines" rel="noopener noreferrer"&gt;https://php7.org/guidelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://phptherightway.com" rel="noopener noreferrer"&gt;https://phptherightway.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>api</category>
    </item>
  </channel>
</rss>
