<?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: Ken Ng</title>
    <description>The latest articles on DEV Community by Ken Ng (@kenng).</description>
    <link>https://dev.to/kenng</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%2F362114%2F6b1f7f40-62da-475e-a54f-a70274cae8b9.jpeg</url>
      <title>DEV Community: Ken Ng</title>
      <link>https://dev.to/kenng</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kenng"/>
    <language>en</language>
    <item>
      <title>The right way to fix PHP-FPM 'primary script unknown' issue</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Sat, 09 Nov 2024 03:16:31 +0000</pubDate>
      <link>https://dev.to/kenng/the-right-way-to-fix-php-fpm-primary-script-unknown-issue-32cn</link>
      <guid>https://dev.to/kenng/the-right-way-to-fix-php-fpm-primary-script-unknown-issue-32cn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Many online resources only outline potential causes and solutions for issues related to upgrading PHP versions, leaving users without a clear, step-by-step guide to resolve their problems. This tutorial aims to document the process of upgrading from PHP 8.2 to PHP 8.3 on Amazon Linux 2023 with Nginx, providing a comprehensive guide that can save developers from hours of frustration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Objective
&lt;/h3&gt;

&lt;p&gt;Objective: Upgrade from PHP 8.2 to PHP 8.3 &lt;/p&gt;

&lt;h3&gt;
  
  
  Server Specs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OS: Amazon Linux 2023  
Server: NGINX 1.26.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Problem Statement
&lt;/h2&gt;

&lt;p&gt;After upgrading PHP, you may encounter errors in the Nginx error log, such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2024/11/09 01:54:40 [error] 3394#3394: *33 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 127.0.0.1, server: abc.com, request: "GET /my-api HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/&lt;a href="http://www.sock:" rel="noopener noreferrer"&gt;www.sock:&lt;/a&gt;", host: "abc.com"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This error typically indicates issues with the FastCGI configuration or permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Potential Causes of the Issue
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Incorrectly Configured Nginx &lt;code&gt;fastcgi_param&lt;/code&gt; Directive
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;fastcgi_param&lt;/code&gt; directive in your Nginx configuration may not be set correctly. However, since the application was functioning properly before the upgrade, this is likely not the primary cause.&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="p"&gt;~&lt;/span&gt; &lt;span class="sr"&gt;\.php$&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;fastcgi_pass&lt;/span&gt;    &lt;span class="s"&gt;unix:/run/php-fpm/www.sock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;fastcgi_param&lt;/span&gt;   &lt;span class="s"&gt;SCRIPT_FILENAME&lt;/span&gt; &lt;span class="nv"&gt;$document_root$fastcgi_script_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;include&lt;/span&gt;         &lt;span class="n"&gt;/etc/nginx/fastcgi_params&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;h3&gt;
  
  
  Incorrect User Permissions
&lt;/h3&gt;

&lt;p&gt;Given that we just upgraded PHP and PHP-FPM, it's possible that the new PHP-FPM configuration is set to an incorrect user or group. This warrants further investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging Steps
&lt;/h2&gt;

&lt;p&gt;To effectively troubleshoot the issue, follow these steps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Locate the Correct &lt;code&gt;php-fpm.ini&lt;/code&gt; Using &lt;code&gt;systemctl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To find the &lt;code&gt;php-fpm.conf&lt;/code&gt;, use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl status php-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ec2-user ~/public_html  01:20:48$ systemctl status php-fpm
● php-fpm.service - The PHP FastCGI Process Manager
     Loaded: loaded (/usr/lib/systemd/system/php-fpm.service; disabled; preset: disabled)
     Active: active (running) since Sat 2024-11-09 00:44:23 UTC; 1h 5min ago
   Main PID: 3374 (php-fpm)
     Status: "Processes active: 0, idle: 7, Requests: 1, slow: 0, Traffic: 0.00req/sec"
      Tasks: 8 (limit: 4659)
     Memory: 12.3M
        CPU: 304ms
     CGroup: /system.slice/php-fpm.service
             ├─3374 "php-fpm: master process (/etc/php-fpm.conf)"
             ├─3377 "php-fpm: pool www"
             ├─3378 "php-fpm: pool www"
             ├─3379 "php-fpm: pool www"
             ├─3380 "php-fpm: pool www"
             └─3381 "php-fpm: pool www"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From this output, note that it is using &lt;code&gt;/etc/php-fpm.conf&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Check the PHP-FPM User Configuration
&lt;/h3&gt;

&lt;p&gt;Open the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;less /etc/php-fpm.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is no &lt;code&gt;user&lt;/code&gt; setting configured, check for additional configurations in &lt;code&gt;/etc/php-fpm.d/*.conf&lt;/code&gt;. Navigate to this directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /etc/php-fpm.d/
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a backup of &lt;code&gt;www.conf&lt;/code&gt; before editing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp &lt;/span&gt;www.conf www.conf.bk
&lt;span class="nb"&gt;sudo &lt;/span&gt;vim www.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the file contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[www]
user = apache
group = apache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you’re using NGINX, update user and group to match your NGINX user configuration, typically nginx for both.&lt;/p&gt;

&lt;p&gt;After making changes, restart the PHP-FPM service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart php-fpm
systemctl status php-fpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything is configured correctly, your website should be accessible again. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Verify User Permissions
&lt;/h3&gt;

&lt;p&gt;If the user and group are correct but issues persist, verify that the user has access to the specified web directory. This is a common issue since users like &lt;code&gt;apache&lt;/code&gt; or &lt;code&gt;nginx&lt;/code&gt; often lack interactive login capabilities.&lt;/p&gt;

&lt;p&gt;To check permissions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Backup your &lt;code&gt;/etc/passwd&lt;/code&gt; file:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cp&lt;/span&gt; /etc/passwd /etc/passwd.bk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Edit &lt;code&gt;/etc/passwd&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   vim /etc/passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Change the shell for the user:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nginx:x:992:992:Nginx web server:/var/lib/nginx:/bin/bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now switch to the &lt;code&gt;nginx&lt;/code&gt; user and check directory access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - nginx
&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/web/directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Always Backup Before Upgrading
&lt;/h3&gt;

&lt;p&gt;Take a snapshot backup of your server before performing upgrades. This allows for quick restoration if issues arise during production changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Upgrades on a Staging Server
&lt;/h3&gt;

&lt;p&gt;Whenever possible, perform upgrades on a staging server before applying them in production environments to mitigate risks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This guide should help you troubleshoot and fix NGINX’s “Primary script unknown” error following a PHP upgrade, while covering best practices for secure and smooth upgrades.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Vuejs3 Template Refs inside v-for</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Sat, 06 May 2023 03:21:41 +0000</pubDate>
      <link>https://dev.to/kenng/vuejs3-template-refs-inside-v-for-1c05</link>
      <guid>https://dev.to/kenng/vuejs3-template-refs-inside-v-for-1c05</guid>
      <description>&lt;p&gt;Here's a short tutorial on using Vue.js3 template refs inside &lt;code&gt;v-for&lt;/code&gt; to call child component methods with the Composition API.&lt;/p&gt;

&lt;p&gt;Assuming you want to invoke the reset function of each child component, you can accomplish this as follows:&lt;/p&gt;

&lt;p&gt;App.vue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Comp&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Comp.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Comp1&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Comp1.vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compRefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onReset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;compRefs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;comp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;comp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onReset&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"n of [0, 1, 2]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;template&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"0 === n % 2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      loop &lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;: &lt;span class="nt"&gt;&amp;lt;Comp&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"compRefs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/Comp&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt; &lt;span class="na"&gt;v-if=&lt;/span&gt;&lt;span class="s"&gt;"1 === n % 2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      loop &lt;span class="si"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="si"&gt;}}&lt;/span&gt;:&lt;span class="nt"&gt;&amp;lt;Comp1&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"compRefs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/Comp1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"onReset"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Reset
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comp.vue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onReset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Reset is activated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onReset&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
   Child COM &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comp1.vue&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;onReset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Reset is activated&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onReset&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    Child COM1 &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that the function you want to invoke must be exposed and the template ref should be placed on the child component, rather than on the div where the v-for directive is specified. This is because we need to access the function of the child component.&lt;/p&gt;

&lt;p&gt;You can checkout the code on this &lt;a href="https://play.vuejs.org/#eNrdUk1rg0AQ/SsPoWxKUxNzDJq2hBxLIdeYQ6prs1R3F12lIP73jutHK6SE9li8ODNv3pt5s7XzpLVbldxZO34R5UIbFNyUehNKkWmVG9TIeYIGSa4yMIKysbRVme7z7qINWqZp2ZvUvR4QKVkYRJTZ86RA0ErMDsfbUAKhTEoZGaEklNxzmmZ2i7qtDHi3OqUldxOV707RedamEWxs2R1biKsJpb/olqJ1KDA80+nJcIoAPxYVqntiCUKHtBIclnN4c6yOoWMRhBk6CCgSwi0RBAEkbrAaQUCqlEZdy6ZZw7em0D6EHgYmqG/3H2gXk0ku6HjXdKyM95OOd1nIX9DO3d9raQw5/BilInonit63UayLbE8Hpfw3NmfuDPf+3cvpLp8Vb/3RGbtydIJ296YGZisQBU6ErWiQmCjpzC1BzBMh+e5Dq4LP6oEGDfFfeQXdytuzSGNsX57JYTvgA9ia4c7+r8EYGqs0mDjxtv16T+wb/y+mfLni/dmW5hMUyXSL"&gt;playground&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's all, Enjoy!&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuejs3</category>
    </item>
    <item>
      <title>Migrating from ASP.net to PHP Laravel</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Mon, 06 Mar 2023 12:13:34 +0000</pubDate>
      <link>https://dev.to/kenng/migrating-from-aspnet-to-php-laravel-filamentphp-4m0h</link>
      <guid>https://dev.to/kenng/migrating-from-aspnet-to-php-laravel-filamentphp-4m0h</guid>
      <description>&lt;p&gt;Recently, we had a project to migrate from ASP.NET to Laravel. During the process, we found that the information on the internet was scattered and disorganized. At times, we had to check the Laravel framework source code to truly understand what had gone wrong. Therefore, this post serves to record the issues we encountered during the migration and how we solved them.&lt;/p&gt;

&lt;p&gt;As we were only migrating the backend language while keeping the SQL Server database, we did not want to go too deep into ASP.NET. Consequently, there is a high chance that we may have misinterpreted the ASP.NET information presented below. Please let us know if we have.&lt;/p&gt;

&lt;p&gt;First off, there are differences in the SQL Server database schema compared to the conventional MySQL database used by Laravel.&lt;/p&gt;

&lt;p&gt;Take the user table as an example. The default &lt;code&gt;AspNetUsers&lt;/code&gt; table uses the column "Id" (than "id") as its primary key, which is stored as a 128-bit GUID string by default. To model the &lt;code&gt;AspNetUsers&lt;/code&gt; table, we had to set the primary key and cast its type to a string in the user model, like so:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Models\User.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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Authenticatable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;your-schema&amp;gt;.AspNetUsers"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$primaryKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Id'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$keyType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without specifying the &lt;code&gt;$primaryKey&lt;/code&gt;, you will encounter an error like the one below, as Laravel tries to inject the instance model using &lt;code&gt;id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Missing required parameter for [URI: products/{record}/edit] [Missing parameter: record].
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If without specifying the the &lt;code&gt;$keyType&lt;/code&gt; to string, you will encounter an error like the one below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQLSTATE[22018]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Conversion failed when converting the nvarchar value 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' to data type int. (Connection: sqlsrv, SQL: select top 1 * from [&amp;lt;your-schema&amp;gt;].[AspNetUsers] where [Id] = 5637154)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using SQL Server via a Docker image. To access the SQL Server, we have to set the &lt;code&gt;.env&lt;/code&gt; and &lt;code&gt;config/database.php&lt;/code&gt; files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DB_CONNECTION=sqlsrv
DB_HOST=127.0.0.1
DB_PORT=1433
DB_DATABASE=XXX
DB_USERNAME=XXX
DB_PASSWORD=XXX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;config/database.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="s1"&gt;'trust_server_certificate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DB_TRUST_SERVER_CERTIFICATE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'true'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test if the above settings are correct, you can try running tinker and pulling user data from the database. If that works, you are good to proceed with your next step.&lt;/p&gt;

&lt;p&gt;This is a rather short blog, but we hope that it is useful for anyone who is looking to migrate from ASP.NET to Laravel.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>aspdotnet</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>Dart Good Practice: separate Model, UI view and controller logic</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Fri, 10 Jun 2022 09:02:53 +0000</pubDate>
      <link>https://dev.to/kenng/dart-good-practice-separate-ui-view-and-controller-logic-1dpd</link>
      <guid>https://dev.to/kenng/dart-good-practice-separate-ui-view-and-controller-logic-1dpd</guid>
      <description>&lt;p&gt;MVC architecture is a design pattern to separate the application into three parts, namely: the model part, the view and the controller.&lt;/p&gt;

&lt;p&gt;In day to day code review, it is noticed that developers tend to directly use unprocessed model data into the UI view. Not only that this will create a lot of extra &lt;code&gt;if-else&lt;/code&gt; null checking logic in the final compiled code, it make the code looks very verbose. &lt;/p&gt;

&lt;p&gt;See the example with pseudocode below: &lt;/p&gt;

&lt;p&gt;Not Recommended:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;month&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good&lt;br&gt;
controller.dart&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;late&lt;/span&gt; &lt;span class="n"&gt;SaleModel&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;onFetch&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'https://abc.com/sales'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SaleModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// declare a named constructor which return SaleModel with blank string&lt;/span&gt;
    &lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SaleModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blank&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UI view&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_ctrl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Upgrading to PHP8.1 on CentOS 7.x</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Fri, 06 May 2022 11:11:49 +0000</pubDate>
      <link>https://dev.to/kenng/upgrading-to-amazon-linux-to-php81-1m52</link>
      <guid>https://dev.to/kenng/upgrading-to-amazon-linux-to-php81-1m52</guid>
      <description>&lt;p&gt;Laravel 9 which has been released recently dropped the support for PHP7.x, and now it can only run on PHP8.0-PHP8.1. &lt;/p&gt;

&lt;p&gt;PHP8.1 is shipped with a few nice features like &lt;code&gt;Enums&lt;/code&gt;, &lt;code&gt;readonly&lt;/code&gt; class property and etc. The introduction of the Enums finally allows you to type-hint permissible values accepted by a variable than resort to using docblock typehints, or third-party “fake enum” packages. &lt;/p&gt;

&lt;p&gt;Let's dive into how to upgrade our server to PHP8.1 from PHP8.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;https://rpms.remirepo.net/enterprise/remi-release-7.rpm
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;yum-utils

&lt;span class="nb"&gt;sudo &lt;/span&gt;yum-config-manager &lt;span class="nt"&gt;--disable&lt;/span&gt; &lt;span class="s1"&gt;'remi-php*'&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;yum-config-manager &lt;span class="nt"&gt;--enable&lt;/span&gt; remi-php81

&lt;span class="nb"&gt;sudo &lt;/span&gt;yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; php81-php php81-php-fpm php81-php-mysql php81-php-gd php81-php-curl php81-php-mbstring php81-php-xml php81-php-bcmath php81-php-sqlite3 php81-php-zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Two issues encountered during the upgrade
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Conflicts of library
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;file /usr/lib64/libzip.so.5 from install of libzip5-1.8.0-2.el7.remi.x86_64 conflicts with file from package libzip-1.3.2-1.amzn2.0.1.x86_64&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Solution: remove the existing package then run the installation of php81 again&lt;br&gt;
&lt;code&gt;$ yum remove libzip-1.3.2-1.amzn2.0.1.x86_64&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. php-fpm is not enabled and started properly
&lt;/h3&gt;

&lt;p&gt;Check using systemctl&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl list-unit-files | &lt;span class="nb"&gt;grep &lt;/span&gt;fpm
php81-php-fpm.service                         disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's enable and starts it, then check its status&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;php81-php-fpm.service
&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl start php81-php-fpm.service

&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl status php81-php-fpm.service
● php81-php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded &lt;span class="o"&gt;(&lt;/span&gt;/usr/lib/systemd/system/php81-php-fpm.service&lt;span class="p"&gt;;&lt;/span&gt; enabled&lt;span class="p"&gt;;&lt;/span&gt; vendor preset: disabled&lt;span class="o"&gt;)&lt;/span&gt;
   Active: active &lt;span class="o"&gt;(&lt;/span&gt;running&lt;span class="o"&gt;)&lt;/span&gt; since Fri 2022-05-06 18:21:15 +08&lt;span class="p"&gt;;&lt;/span&gt; 6min ago
 Main PID: 16011 &lt;span class="o"&gt;(&lt;/span&gt;php-fpm&lt;span class="o"&gt;)&lt;/span&gt;
   Status: &lt;span class="s2"&gt;"Processes active: 0, idle: 5, Requests: 0, slow: 0, Traffic: 0req/sec"&lt;/span&gt;
    Tasks: 6
   Memory: 8.9M
   CGroup: /system.slice/php81-php-fpm.service
           ├─16011 php-fpm: master process &lt;span class="o"&gt;(&lt;/span&gt;/etc/opt/remi/php81/php-fpm.conf&lt;span class="o"&gt;)&lt;/span&gt;
           ├─15897 php-fpm: pool www
           ├─15898 php-fpm: pool www
           ├─15899 php-fpm: pool www
           ├─15900 php-fpm: pool www
           └─15901 php-fpm: pool www
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another issue noticed is php-fpm does not read php-fpm config that we have setup in &lt;code&gt;/etc/php-fpm.d&lt;/code&gt;. From the output of &lt;code&gt;systemctl status&lt;/code&gt; command, we can see that configuration read is located at &lt;code&gt;/etc/opt/remi/php81/php-fpm.conf&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Edit this file to update the conf directory to be read&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;;include=/etc/opt/remi/php81/php-fpm.d/*.conf
include=/etc/php-fpm.d/*.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now restart the php-fpm service again&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl restart php81-php-fpm.service 
&lt;span class="nv"&gt;$ &lt;/span&gt;systemctl status php81-php-fpm.service 
● php81-php-fpm.service - The PHP FastCGI Process Manager
   Loaded: loaded &lt;span class="o"&gt;(&lt;/span&gt;/usr/lib/systemd/system/php81-php-fpm.service&lt;span class="p"&gt;;&lt;/span&gt; enabled&lt;span class="p"&gt;;&lt;/span&gt; vendor preset: disabled&lt;span class="o"&gt;)&lt;/span&gt;
   Active: active &lt;span class="o"&gt;(&lt;/span&gt;running&lt;span class="o"&gt;)&lt;/span&gt; since Fri 2022-05-06 18:30:07 +08&lt;span class="p"&gt;;&lt;/span&gt; 32min ago
 Main PID: 16296 &lt;span class="o"&gt;(&lt;/span&gt;php-fpm&lt;span class="o"&gt;)&lt;/span&gt;
   Status: &lt;span class="s2"&gt;"Processes active: 0, idle: 21, Requests: 30, slow: 0, Traffic: 0req/sec"&lt;/span&gt;
    Tasks: 22
   Memory: 118.6M
   CGroup: /system.slice/php81-php-fpm.service
           ├─16296 php-fpm: master process &lt;span class="o"&gt;(&lt;/span&gt;/etc/opt/remi/php81/php-fpm.conf&lt;span class="o"&gt;)&lt;/span&gt;
           ├─16297 php-fpm: pool app.xxx.com
           ├─16298 php-fpm: pool app.xxx.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of the www pool, we can see that it's now serving the pool for the website &lt;code&gt;app.xxx.com&lt;/code&gt; that we have set up in the pool configuration. &lt;/p&gt;

&lt;p&gt;That's all for it!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Small Things to note running dockerized Laravel testing with Github Actions</title>
      <dc:creator>Ken Ng</dc:creator>
      <pubDate>Wed, 21 Jul 2021 04:02:13 +0000</pubDate>
      <link>https://dev.to/kenng/small-things-to-note-running-dockerized-laravel-testing-with-github-actions-45pi</link>
      <guid>https://dev.to/kenng/small-things-to-note-running-dockerized-laravel-testing-with-github-actions-45pi</guid>
      <description>&lt;p&gt;It’s always good to test your app on code changes so that buggy code never goes to production. Github Actions is a sweet feature to use for continuous integration. For a free account, you have 2000 mins/month to use. Today, let’s setup dockerized Laravel unit testing using it.&lt;/p&gt;

&lt;p&gt;tldr;&lt;br&gt;
The final workflow at &lt;code&gt;.github/workflows/testing.yml&lt;/code&gt; look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Laravel testing&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;release&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;phpunit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-20.04&lt;/span&gt;
        &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;fail-fast&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

        &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kenngsimply/laravelapp:v1&lt;/span&gt;

        &lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;db-tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql:5.7&lt;/span&gt;
                &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR-ROOT-PASSWORD&amp;gt;&lt;/span&gt;
                    &lt;span class="na"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR-DB-USER&amp;gt;&lt;/span&gt;
                    &lt;span class="na"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR-DB-USER-PASSWOD&amp;gt;&lt;/span&gt;
                    &lt;span class="na"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;YOUR-DB-NAME&amp;gt;&lt;/span&gt;
                &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3306:3306&lt;/span&gt;
            &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:6-alpine&lt;/span&gt;
                &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;6379:6379&lt;/span&gt;

        &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
              &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install composer dependencies&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;composer install&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prepare Laravel Application&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;cp .env.testing .env&lt;/span&gt;
                &lt;span class="s"&gt;php artisan key:generate&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Migrate and seed&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;php artisan migrate --seed&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                &lt;span class="s"&gt;php artisan redis:init&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Testsuite&lt;/span&gt;
              &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;php artisan test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since phpunit will be using &lt;code&gt;.env.testing&lt;/code&gt; when it’s exists, we will copy it as &lt;code&gt;.env&lt;/code&gt; in the test environment&lt;/li&gt;
&lt;li&gt;Since we specify &lt;code&gt;container&lt;/code&gt;, the jobs will be running in the laravelapp docker container instead of in the runner machine. This simplifies the network access to service containers. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;services.&amp;lt;name&amp;gt;&lt;/code&gt; will become your docker container’s hostname. For our example, the MySQL database container hostname will be &lt;code&gt;db-tests&lt;/code&gt;. So in your &lt;code&gt;.env.testing&lt;/code&gt;, make sure to set the &lt;code&gt;DB_HOST=db-tests&lt;/code&gt;. Again this is because the jobs are running inside the docker. If it's running in the runner machine, then we would have to change it to &lt;code&gt;DB_HOST=localhost&lt;/code&gt;. Refers to this good tutorial on &lt;a href="https://docs.github.com/en/actions/guides/creating-redis-service-containers"&gt;service container&lt;/a&gt; for better understanding.&lt;/li&gt;
&lt;li&gt;If you having a connection issue with MySQL, you can try ping it using curl as one of the run step , Example &lt;code&gt;curl db-tests:3306 --ouput -&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We use &lt;code&gt;fetch-depth: 1&lt;/code&gt; so that we are not cloning the entire git history. In fact, this is the default behaviour of &lt;code&gt;actions/checkout@v2&lt;/code&gt;, we just make it explicit here. Refer to the &lt;a href="https://github.com/actions/checkout/blob/v2/action.yml"&gt;doc&lt;/a&gt; for all the inputs that are available.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fail-fast&lt;/code&gt; is by default set to true, we just make it explicit here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a sample of .env.testing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;APP_NAME="My Sample Laravel App"&lt;/span&gt;
&lt;span class="s"&gt;APP_ENV=testing&lt;/span&gt;
&lt;span class="s"&gt;APP_KEY=&lt;/span&gt;
&lt;span class="s"&gt;APP_DEBUG=true&lt;/span&gt;
&lt;span class="s"&gt;APP_URL=http://localhost&lt;/span&gt;

&lt;span class="s"&gt;LOG_CHANNEL=stack&lt;/span&gt;

&lt;span class="s"&gt;DB_CONNECTION=mysql&lt;/span&gt;
&lt;span class="s"&gt;DB_HOST=db-tests&lt;/span&gt;
&lt;span class="s"&gt;DB_PORT=3306&lt;/span&gt;
&lt;span class="s"&gt;DB_DATABASE=&lt;/span&gt;
&lt;span class="s"&gt;DB_USERNAME=&lt;/span&gt;
&lt;span class="s"&gt;DB_PASSWORD=&lt;/span&gt;

&lt;span class="s"&gt;REDIS_CLIENT=phpredis&lt;/span&gt;
&lt;span class="s"&gt;REDIS_HOST=redis&lt;/span&gt;
&lt;span class="s"&gt;REDIS_PORT=6379&lt;/span&gt;
&lt;span class="s"&gt;REDIS_DB=0&lt;/span&gt;
&lt;span class="s"&gt;REDIS_PREFIX='redis_test_'&lt;/span&gt;

&lt;span class="s"&gt;CACHE_DRIVER=database&lt;/span&gt;
&lt;span class="s"&gt;CACHE_PREFIX='cache_'&lt;/span&gt;   

&lt;span class="s"&gt;TELESCOPE_ENABLED=false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>github</category>
      <category>laravel</category>
      <category>testing</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
