Menu

Thursday, December 26, 2019

[Laravel - Blade Template] การใช้งาน Loops ประเภทต่างๆ
[Laravel - Blade Template] How to Use Each Loop Types

For Loop

@for ($i = 0; $i < 10; $i++)
    The current value is {{ $i }}
@endfor

ForEach Loop

@foreach ($users as $user)
    This is user {{ $user->name }}
@endforeach

ForElse Loop - ForEach with handling for empty inputs

@forelse ($users as $user)
    This is user {{ $user->name }}
@empty
    No users
@endforelse

[Laravel - Blade Template] การตรวจสอบเงื่อนไขใน Blade Template
[Laravel - Blade Template] How to Use Conditional Statement

If Statement

@if (count($record) > 0)

@elseif (count($record) < 0)

@else

@endif

Unless Statement

@unless (count($record)< 0)

@endunless

[Laravel - Blade Template] การตรวจสอบการเข้าใช้งานและการตรวจสอบสิทธิ์การใช้งาน
[Laravel - Blade Template] Authentication and Authorization

การตรวจสอบการเข้าใช้งาน 

มี 2 แบบดังนี้
  • ตรวจสอบว่า user ได้เข้าสู่ระบบแล้ว
  • @auth
    
    @else
    
    @endauth
    
  • ตรวจสอบว่า user ยังไม่ได้เข้าสู่ระบบแล้ว
  • @guest
    
    @else
    
    @endguest
    

[Laravel - Blade Template] การสร้าง Layout และการ Extend Layout
[Laravel - Blade Template] How to Create and Extend Layout

การสร้าง Layout

การสร้าง Layout เป็นการสร้างเว็บเพจด้วย HTML เช่นเดียวกับหน้าเว็บทั่วไป แต่แทนค่าส่วนต่างๆที่จะใช้โดย child view ด้วย directives ซึ่งมี directives ที่เกี่ยวกับ Layout ดังนี้
  • @section ใช้ประกาศ section ในส่วนของเนื้อหา
  • @show ใช้ประกาศ section และใช้แสดงเนื้อหาของ section นั้น
  • @yield ใช้แสดงเนื้อหาของ section ที่ระบุ
ตัวอย่าง เช่น
@section('sidebar')
    This is the master sidebar.
@show

<div class="container">
    @yield('content')
</div>

Wednesday, December 18, 2019

[Docker] การใช้ Docker สำหรับทำ Host เว็บไซต์หลายเว็บบน server เครื่องเดียว
[Docker] How to Use Docker to Host Multiple Websites in One Server

การใช้ Server เพียงเครื่องเดียวในการ host หลายเว็บไซต์ เราจำเป็นต้องใช้ Reverse Proxy

ในที่นี้เราจะใช้ NGINX Proxy ในการจัดการ Proxy ให้เรา โดยมีวิธีการติดตั้งดังนี้
  1. สร้าง docker network
  2. docker network create nginx-proxy
    
  3. สร้างไฟล์ docker-compose.yml โดยใช้ไฟล์ตั้งต้นจาก https://github.com/jwilder/nginx-proxy/blob/master/docker-compose.yml
  4. เพิ่ม code ข้างล่าง ใน docker-compose.yml ของ nginx-proxy
  5. networks:
      default:
        external:
          name: nginx-proxy
    
  6. รัน nginx-proxy ด้วยคำสั่งดังนี้
  7. docker-compose up -d
    

[Docker] การ Deploy Wordpress ด้วย Docker
[Docker] How to Deploy Wordpress with Docker

ขั้นตอนในการสร้าง docker-compose.yml สามารถอ่านได้ที่ Quickstart: Compose and WordPress

เมื่อสร้าง docker-compose.yml เสร็จแล้ว ให้แก้ไขไฟล์ดังนี้
  1. ให้แก้ volumes ใน service db ดังนี้ เพื่อให้เก็บ mysql data ใน folder เดียวกับ docker-compose.yml
  2. volumes:
        - ./db_data:/var/lib/mysql
    
  3. ให้เพิ่ม volumes ใน service wordpress ดังนี้ เพื่อให้เก็บข้อมูล web ใน folder เดียวกับ docker-compose.yml
  4. volumes:
        - ./html:/var/www/html    
    
ไฟล์ docker-compose.yml หลังจากแก้ไขแล้ว จะเป็นดังนี้
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - ./db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     volumes:
       - ./html:/var/www/html    
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       WORDPRESS_DB_NAME: wordpress
หลังจากนั้นให้ build project ตามเว็บข้างต้นได้เลย

หมายเหตุ เพื่อความปลอดภัย ควรเปลี่ยน user และ password ต่างๆในส่วนของ environment ให้ต่างไปจาก code ตัวอย่าง

Sunday, December 15, 2019

[System] การตั้งค่าการเข้าใช้งาน โดยใช้ SSH Key บน Linux Server
[System] How To Configure SSH Key-Based Authentication on a Linux Server

สมมติว่า เรามี id_rsa.pub เป็น Public Key เรามีวิธีตั้งค่าการเข้าใช้งานดังนี้
  1. คัดลองข้อมูล key ในไฟล์ id_rsa.pub 
  2. Remote เข้าเครื่อง Server ด้วย user ที่มีสิทธิ์ root
  3. เปิดไฟล์ ~/.ssh/authorized_keys
  4. นำข้อมูล key จากข้อ 1 ไปเพิ่มต่อจาก key ที่มีอยู่ แล้วทำการบันทึก

[Security] การสร้าง SSH Key ใหม่
[Security] How to Generate New SSH Key

  1. เปิด Git Bash หรือ PowerShell
  2. รันคำสั่งดังนี้
  3. ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  4. เมื่อขึ้น Enter a file in which to save the key สามารถกด Enter ได้เลย ถ้าต้องการบันทึกไฟล์ตาม path ที่แสดง
  5. เมื่อขึ้น Enter passphrase สามารถกด Enter ได้เลย ถ้าไม่ต้องการระบุ passphrase
ตัวอย่างผลการรันคำสั่งเป็นตามด้านล่าง
เมื่อรันคำสั่งสร้าง SSH Key จบแล้ว จะมีไฟล์เกิดขึ้นที่ตาม path ที่เรากำหนดในข้อ 3 ดังตัวอย่างข้างล่าง

Wednesday, December 11, 2019

[Laravel - Package] วิธีการใช้งาน Laravel Modules
[Laravel - Package] How to Use Laravel Modules

Modules

การสร้าง Module ใหม่

php artisan module:make module_name
ยกตัวอย่าง เช่น
php artisan module:make Projects

การตั้ง namespace ของ Class

namespace namespace_name\module_name\Http\Controllers;
ยกตัวอย่าง เช่น
namespace Modules\Projects\Http\Controllers;

[Laravel - Blade Template] การนำเข้า Template อื่นพร้อมกับกำหนด Parameter สำหรับ Template นั้น
[Laravel - Blade Template] How to Include Other Template with Parameters

โดยปกติแล้ว เวลาเราต้องการเพิ่ม template อื่นใน template หลักของเรา เราจะใช้โค้ดดังนี้
@include('menu.index')
Template ดังกล่าวถูกทำขึ้น เพื่อนำเข้าไปใช้ประโยชน์ในหลาย template หลัก เช่น template ของส่วนเมนูที่ต้องนำไปเพิ่มเข้าทุก template ที่ต้องการแสดงส่วนของเมนู

แต่ในบางครั้ง เราต้องการส่ง parameter เข้าไปยัง template ดังกล่าวด้วย เช่น การกำหนดว่า template หลักที่เพิ่ม template นั้นๆเข้ามาเป็น template เกี่ยวกับอะไร เพื่อแสดงเมนูในส่วนที่เกี่ยวข้องแตกต่างจากส่วนอื่น เป็นต้น เราสามารถใช้โค้ดดังนี้
@include('menu.index', ['group'=> 'users'])
จากตัวอย่าง เราส่ง parameter ชื่อ group เข้าไปยัง template menu.index ทำให้ใน template ดังกล่าว เราสามารถใช้ตัวแปร $group ได้

[Ubuntu] วิธีการเพิ่มผู้ใช้งานใหม่และกำหนดให้เข้าใช้งานผ่าน SSH บน Ubuntu
[Ubuntu] How to Add New User and Set to Login by SSH on Ubuntu

  1. เพิ่มผู้ใช้งานในระบบ
  2. adduser <username>
  3. แก้ไขไฟล์ config สำหรับ SSH
  4. vim /etc/ssh/sshd_config
  5. ตั้งค่าอนุญาตให้ Login ด้วย password ได้
  6. # Change to no to disable tunnelled clear text passwords
    PasswordAuthentication yes
  7. กำหนด User ที่อนุญาตให้ login ผ่าน SSH ได้ (จะกำหนดหรือไม่ก็ได้)
  8. AllowUsers <username>
    คำเตือน!!! กรณีที่ตั้งค่า AllowUsers และต้องการให้ root สามารถ login ได้จำเป็นต้องใส่ root ในส่วนของ username ด้วย
    AllowUsers root userA
  9. กำหนด User ที่ไม่อนุญาตให้ login ผ่าน SSH ได้ (จะกำหนดหรือไม่ก็ได้)
  10. DenyUsers <username>
  11. Restart SSH service
  12. service ssh reload
หมายเหตุ อ่าน config เพิ่มเติมของ SSH ได้ที่ FreeBSD Manual Pages - sshd_config

Friday, December 6, 2019

[Security] การเข้ารหัสและถอดรหัสไฟล์โดยใช้ Public และ Private Keys
[Security] File Encryption and Decryption by Using Public and Private Keys


สมมติว่า มีไฟล์ที่เกี่ยวข้องดังนี้
  • key.pem เป็นไฟล์ Private key
  • pub.pem เป็นไฟล์ Public key
  • data.txt เป็นไฟล์ข้อความที่ต้องการเข้ารหัส
หมายเหตุ กรณีที่ยังไม่มีไฟล์ key.pem และ pub.pem อ่านวิธีสร้างได้ที่ การสร้าง Private Key และ Public Key ด้วย OpenSSL

[Bash Script] วิธีการใช้ Environment Variables จากไฟล์ .env ใน Bash Script
[Bash Script] How to Use Environment Variables from .env File in Bash Script

สมมติว่า Bash script ที่เราจะกำลังเขียนใหม่อยู่ใน folder เดียวกับไฟล์ .env และไฟล์ .env มีข้อมูลดังนี้
DOMAIN="code2now.com"
เราสามารถเขียน script ของเรา เพื่อใช้งานข้อมูลในไฟล์ .env ดังนี้
# Set allexport option 
set -a
. ./.env
set +a

echo $DOMAIN
คำอธิบายเพิ่มเติม

set -a และ set +a เป็นการเปิดและปิด feature ที่ทำให้ตัวแปรที่ถูกประกาศระหว่าง 2 บรรทัดนี้ ถูก export เป็น environment variable

. ./.env เป็นการโหลด source จากไฟล์ .env

echo $DOMAIN เป็นตัวอย่างการใช้งาน environment variable จากไฟล์ .env

[Security] การสร้าง Private Key และ Public Key ด้วย OpenSSL
[Security] How to Create Private Key and Public Key with OpenSSL


สมมติว่า ได้ติดตั้ง OpenSSL ไว้ภายในเครื่องแล้ว และเราต้องการสร้าง Private key ชื่อ key.pem และ Public key ชื่อ pub.pem

วิธีการสร้าง Private key และ Public key เป็นดังนี้
  1. สร้าง Private key โดยรันคำสั่งดังนี้
  2. openssl genrsa -out key.pem 1024
    
  3. เรียกดูข้อมูล Private key ที่ถูกสร้างขึ้นด้วยคำสั่งดังนี้
  4. openssl rsa -in key.pem -text -noout
    
  5. สร้าง Public key จาก Private key ที่เพิ่งสร้าง โดยรันคำสั่งดังนี้
  6. openssl rsa -in key.pem -pubout -out pub.pem
    
  7. เรียกดูข้อมูล Public key ที่ถูกสร้างขึ้นด้วยคำสั่งดังนี้
  8. openssl rsa -in pub.pem -pubin -text -noout
    

[Security] การติดตั้ง OpenSSL บน Windows
[Security] OpenSSL Installation on Windows


OpenSSL เป็นเครื่องมือสำหรับ Transport Layer Security (TLS) และ Secure Sockets Layer (SSL) protocols

วิธีการติดตั้ง

  1. Download OpenSSL installer (Win64 OpenSSL v1.1.1d Light) จาก https://slproweb.com/products/Win32OpenSSL.html 
  2. ติดตั้งโปรแกรมที่ C:\Program Files\OpenSSL-Win64
  3. เพิ่มค่า Path ใน Environment variable ด้วย C:\Program Files\OpenSSL-Win64\bin

วิธีการทดสอบ

  1. เปิด Windows PowerShell
  2. รันคำสั่ง openssl

Tuesday, December 3, 2019

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Debugbar
[Laravel - Package] How to Install and Config Laravel Debugbar

Laravel Debugbar เป็น package ที่รวม PHP Debug Bar เข้ากับ Laravel เพื่อใช้แสดงข้อมูลจากส่วนต่างๆของ Application

วิธีการติดตั้ง

  1. สั่งติดตั้ง Laravel Modules package
  2. composer require barryvdh/laravel-debugbar --dev
  3. สร้างไฟล์ config ของ package ใน project
  4. php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"
    

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Modules
[Laravel - Package] How to Install and Config Laravel Modules

Laravel Modules เป็น package ที่สร้างขึ้น เพื่อจัดการ Laravel application ที่มีขนาดใหญ่ โดยการแบ่งเป็น module ย่อยๆ

วิธีการติดตั้ง

  1. สั่งติดตั้ง Laravel Modules package
  2. composer require nwidart/laravel-modules
  3. สร้างไฟล์ config ของ package ใน project
  4. php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider"

Friday, November 29, 2019

[Laravel - AWS] วิธีการเก็บ Cache Credentials สำหรับ AWS SDK ของ PHP
[Laravel - AWS] How to Cache Credentials for the AWS SDK for PHP

Credentials จะถูกเรียกใช้ทุกครั้งที่มีการส่ง request ไปยัง Amazon Web Services

มีหลายวิธีที่จะตั้งค่า Credentials นี้ สามารถอ่านได้ที่ Credentials for the AWS SDK for PHP Version 3

ถ้า Application ของเรารันบนเครื่อง Amazon EC2 วิธีการที่แนะนำ คือ การใช้ IAM role เพื่อดึง Credentials แบบชั่วคราวมาใช้งาน

สำหรับการใช้งาน IAM roles, metadata service จะถูกเรียกถูกครั้งที่เรียกใช้ Credentials

หมายเหตุ การเรียกใช้ metadata service คือ การส่ง request ไปที่ metadata server ใน เครื่อง EC2 ซึ่งอาจจะมี network latency ได้

Thursday, November 28, 2019

[Laravel - Model] การตั้งค่า Attribute ของ Model ให้เป็น Lower Case
[Laravel - Model] How to Set Model Attribute to Lower Case

บางครั้งเราจำเป็นต้องทำระบบที่เชื่อมต่อกับฐานข้อมูลเดิมที่มีอยู่แล้ว และฐานข้อมูลเหล่านั้นอาจจะมีชื่อ column เป็นตัวพิมพ์ใหญ่ทั้งหมด เวลาใช้งานแต่ละ column จะต้องพิมพ์ชื่อเป็นตัวพิมพ์ใหญ่ ทำให้ยากต่อการเขียนโค้ด

สำหรับ Laravel แล้ว เราสามารถตั้งค่าเพื่อให้เปลี่ยนชื่อ column พวกนี้เป็นตัวพิมพ์เล็ก เมื่อเราเรียกใช้งานได้

วิธีการตั้งค่า

  1. เข้าไปที่ config/database.php
  2. เพิ่มโค้ดข้างล่างในส่วนของ connections ที่ต้องการ
  3. 'options' => extension_loaded('pdo_mysql') ? array_filter([
        PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
        PDO::ATTR_CASE => PDO::CASE_LOWER,
    ]) : [
        PDO::ATTR_CASE => PDO::CASE_LOWER,
    ],
    

Wednesday, November 27, 2019

[Laravel - Model] การเข้ารหัสและถอดรหัสค่าของฟิลด์ใน Laravel Model
[Laravel - Model] Field Values Encryption and Decryption in Laravel Model

ในบางกรณี เราต้องการรักษาความลับของข้อมูล โดยอนุญาตให้เฉพาะผู้ที่เกี่ยวข้องเท่านั้นที่สามารถดูและแก้ไขได้ ระบบส่วนใหญ่จึงจำกัดสิทธิ์การใช้งานของแต่ละผู้ใช้งานภายใน application

อย่างไรก็ตาม ระบบดังกล่าวยังคงเก็บข้อมูลจริงลงฐานข้อมูลโดยไม่มีการเข้ารหัสใดๆ ทำให้ Database Admin ยังสามารถเข้าดูข้อมูลและแก้ไขได้

การเข้ารหัสข้อมูลก่อนเก็บลงฐานข้อมูล จึงเป็นการเพิ่มความปลอดภัยของข้อมูลอีกขั้นนึง

สำหรับ Laravel Model ที่มี function กลางสำหรับการดึงค่าข้อมูลและเก็บข้อมูลของ Fields ต่างๆ ทำให้การเข้ารหัสและถอดรหัสนั้นทำได้ง่ายขึ้นมาก เราเพียงเขียน Trait แล้วนำไปใส่ใน Model พร้อมกับกำหนด Fields ที่เราต้องการเข้ารหัสเท่านั้น

[Laravel - Package] ขั้นตอนการตั้งค่า Packagist เพื่อให้ติดตั้ง Laravel Package ผ่าน Composer ได้
[Laravel - Package] Packagist Setting Steps for Laravel Package Installation via Composer

สมมติว่า เรามี Laravel package อยู่บน Repository ใดๆ แล้วเราต้องการให้สามารถติดตั้ง package ดังกล่าวผ่าน composer ได้เลย โดยไม่ต้องตั้งค่าใดๆเพิ่ม เรามีวิธีการดังต่อไปนี้

เนื่องจาก Composer ใช้งาน Packagist repository เป็น default repository เท่านั้น (อ่านเพิ่มเติมได้ใน Composer Repositories) ขั้นตอนการตั้งค่าจึงเป็นดังนี้
  1. Login เข้า https://packagist.org/
  2. เข้าหน้าเมนู Submit
  3. ใส่ repository url กดปุ่ม Check
  4. กดปุ่ม Submit
  5. รอจน package ถูกอัพเดตเรียบร้อย
สำหรับการทดสอบ ทำได้โดยรัน command ดังนี้
composer require arzeroid/laravel-model-encryptable
ผลที่ได้จะเป็นดังนี้

[Laravel - Package] วิธีการตั้งค่า Composer เพื่อติดตั้ง Package จาก GitHub
[Laravel] How to Install Package from GitHub via Composer

สมมติว่า เรามี Laravel package ตัวนึงอยู่บน GitHub ของเราตามรูปตัวอย่างข้างล่าง


เมื่อเราต้องการนำ package นั้นมาใช้งานใน project ของเรา โดยปกติแล้ว เราจะรัน command ดังนี้
composer require arzeroid/laravel-model-encryptable

Monday, November 25, 2019

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Userstamps
[Laravel - Package] How to Install and Config Laravel Userstamps

Laravel-Userstamps เป็น package สำหรับจัดการฟิลด์ created_by และ updated_by (รวมถึง deleted_by กรณีที่เปิดใช้งาน Soft Delete) ของ Laravel model โดยใช้ข้อมูลของผู้ใช้งานในขณะนั้น โดยอัตโนมัติ เมื่อมีการสร้าง แก้ไข และลบ model

วิธีการติดตั้ง

  1. สั่งติดตั้ง Laravel-Userstamps package
  2. composer require wildside/userstamps

Friday, November 22, 2019

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Sluggable
[Laravel - Package] How to Install and Config Laravel Sluggable

Eloquent-Sluggable เป็น package เสริมสำหรับสร้าง Slug ภายใน Laravel Model โดยจะสร้าง Slug ใส่ฟิลด์ที่ระบุให้โดยอัตโนมัติ เมื่อมีการบันทึกข้อมูล

วิธีการติดตั้ง

  1. สั่งติดตั้ง Eloquent-Sluggable package
  2. composer require cviebrock/eloquent-sluggable
  3. สร้างไฟล์ config ของ package ใน project
  4. php artisan vendor:publish --provider="Cviebrock\EloquentSluggable\ServiceProvider"
    

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Activity Log
[Laravel - Package] How to Install and Config Laravel Activity Log

laravel-activitylog เป็น package สำหรับใช้จัดเก็บ log การใช้งานของ user ยิ่งไปกว่านั้น package นี้สามารถเก็บ log จาก model event ได้โดยอัตโนมัติ

วิธีการติดตั้ง

  1. สั่งติดตั้ง laravel-activitylog package
  2. composer require spatie/laravel-activitylog
  3. สร้างไฟล์ migration ของ package ใน project
  4. php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="migrations"
    
  5. รัน migrate เพื่อสร้างตารางในฐานข้อมูล
  6. php artisan migrate
    
  7. สร้างไฟล์ config ของ package ใน project
  8. php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="config"
    

Thursday, November 21, 2019

[Laravel - Package] วิธีการติดตั้งและตั้งค่า Laravel Permission
[Laravel - Package] How to Install and Config Laravel Permission

laravel-permission เป็น package สำหรับจัดการ roles และ permissions ของ user ใน database

วิธีการติดตั้ง

  1. สั่งติดตั้ง laravel-permission package
  2. composer require spatie/laravel-permission
  3. สร้างไฟล์ migration ของ package ใน project
  4. php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="migrations"
    
  5. รัน migrate เพื่อสร้างตารางในฐานข้อมูล
  6. php artisan migrate
    
  7. สร้างไฟล์ config ของ package ใน project
  8. php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" --tag="config"
    

Wednesday, November 20, 2019

[Laravel - Package] การสร้าง PHPDOC สำหรับ Laravel Model
[Laravel - Package] How to Generate PHP Document for Laravel Model

เราสามารถสร้าง PHPDOC ของ Laravel Model ได้ง่ายๆ ดังนี้
  1. ติดตั้ง Package Laravel IDE Helper เข้าไปใน Project โดยรันคำสั่งต่อไปนี้
    composer require --dev barryvdh/laravel-ide-helper
    
  2. รันคำสั่งต่อไปนี้ เพื่อสร้าง PHPDOC ของ Laravel Model 
    php artisan ide-helper:models -R
    

Monday, November 18, 2019

[VSCODE] วิธีการย่อโค้ดในไฟล์โดยอัตโนมัติใน Visual Studio Code
[VSCODE] How to Automatically Fold Code Files in Visual Studio Code

หลายๆครั้งที่เราเขียนโค้ด โดยที่ในหนึ่งไฟล์จำเป็นต้องมี Function จำนวนมาก เมื่อเราต้องการแก้ไขหรือเรียกใช้ฟังก์ชั่นใดฟังก์ชั่นหนึ่ง เราจำเป็นต้องเลื่อนหน้าจอขึ้นลงหลายครั้ง เพื่อหาโค้ดตำแหน่งที่เราต้องการ

การย่อฟังก์ชั่นเป็นวิธีนึงที่จะช่วยลดเวลาในเลื่อนหาโค้ดได้ แต่เนื่องจากมี Function จำนวนมาก การย่อฟังก์ชั่นทีละฟังก์ชั่นนั้นใช้เวลามาก

ดังนั้นเราจะใช้วิธีการย่อฟังก์ชั่นโดยอัตโนมัติ โดยใช้ extension ชื่อ Auto Fold ซึ่ง extension ตัวนี้จะย่อ Function และส่วนต่างๆของโค้ดให้เราโดยอัตโนมัติ เมื่อเราเปิดไฟล์

Tuesday, November 12, 2019

[PHP] วิธีการสร้าง Slug จากข้อความที่กำหนด
[PHP] How to Slugify a String

Slug เป็น Identifier ประเภทหนึ่งที่ใช้อ้างอิงถึงข้อมูลเช่นเดียวกับ id ใน database แตกต่างกันตรงที่ Slug เป็น identifier ที่คนสามารถอ่านเข้าใจ

โค้ดสำหรับสร้าง Slug จากข้อความที่กำหนดเป็นดังนี้
public static function slugify($str, $delimiter = '-')
{
    // Replace none alphanumeric with delimiter
    $str = preg_replace('/[^A-Za-z0-9]+/', $delimiter, $str);

    // Replace duplicated delimiter
    $str = preg_replace("/$delimiter+/", $delimiter, $str);

    // Trim delimiter
    $str = trim($str, $delimiter);

    // Convert to lower case
    $str = strtolower($str);

    return $str;
}

Tuesday, November 5, 2019

[Docker] วิธีการแก้ไขข้อผิดพลาด "SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version"
[Docker] How to Fix "SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version"

หลังจากที่รันคำสั่งของ laradock ดังต่อไปนี้ผ่าน Docker Toolbox on Windows
docker-compose up -d nginx workspace mysql phpmyadmin 
จะได้ข้อผิดพลาดตามด้านล่างนี้
ERROR: SSL error: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661)
วิธีแก้ไข คือ ให้รันคำสั่งตามข้างนี้ก่อน แล้วจึงรันคำสั่งข้างต้นอีกที
export COMPOSE_TLS_VERSION=TLSv1_2
กรณีที่ต้องการตั้งค่าถาวรให้เพิ่มคำสั่งข้างบนในไฟล์ ~/.bash_proflle

Tuesday, October 29, 2019

[Batch Script] วิธีการ Disable การเปลี่ยนภาพพื้นหลังหน้าจอ
[Batch Script] How to Disable Changing Desktop Background

กรณีที่เราต้องการตั้งค่าการเปลี่ยนภาพพื้นหลังหน้าจอผ่าน Batch Script เราจำเป็นต้องเปลี่ยนค่าของ Registry แทนการตั้งค่าผ่าน UI

ขั้นแรก เราต้องหาให้ได้ว่า Registry ตัวใดที่ควบคุมการตั้งค่าการเปลี่ยนภาพพื้นหลัง ซึ่งสามารถหาได้จากลิ้งค์ข้างล่างนี้
How to stop people from changing your Windows 10 desktop wallpaper

ขั้นต่อไป เราต้องเขียน Batch Script ที่มีคำสั่งตามด้านล่างนี้ เพื่อเพิ่ม Key และ Value ของ Registry ข้างต้น
REG ADD HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop /f /v NoChangingWallPaper /t REG_DWORD /d 1
สามารถอ่านเพิ่มเติมได้ที่ Batch Script - Adding to the Registry

กรณีที่เราต้องการลบการตั้งค่าข้างต้น เราสามารถรันคำสั่งตามด้านล่างนี้ใน PowerShell
REG DELETE HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop /f /v NoChangingWallPaper
สามารถอ่านเพิ่มเติมได้ที่ Batch Script - Deleting from the Registry

Monday, October 14, 2019

[Windows] ข้อควรระวัง: การตั้งค่า Environment Variables สำหรับ User ที่ถูกสร้างใหม่
[Windows] Warning: Setting Environment Variables for New User

กรณีนี้เริ่มจากเราสร้าง User ใหม่ ชื่อ Arzeroid โดยไม่ได้ใช้ User lenovo เดิมที่มีสิทธิ์เป็น Administrator ที่มากับเครื่องในตอนแรก

หลังจากนั้นทำการติดตั้ง Docker Toolbox ใน Arzeroid ผลปรากฏว่า ไม่สามารถรัน Docker Toolbox ได้ โดยได้ข้อผิดพลาดว่า หาไฟล์ vboxmanage.exe ไม่เจอ

เมื่อทำการตรวจสอบ พบว่า ในหน้าจอของ Environment Variables ของ Arzeroid มีส่วนของ User variables เป็นของ lenovo และ Docker Toolbox ก็มาสร้าง Environment Variable ไว้ในส่วนนี้ ดังภาพด้านล่าง


เมื่อตรวจสอบ User ที่กำลังใช้งานอยู่ผ่าน Windows PowerShell ก็ได้เป็น Arzeroid ตามภาพด้านล่าง


เราจึงย้าย User variables ที่ถูกสร้างขณะติดตั้ง Docker Toolbox มาใส่ใน System variables ผลที่ได้คือ สามารถรัน Docker Toolbox ได้ตามปกติ

[Security] การสร้าง Public Key และ Private Key ด้วย OpenSSL
[Security] How to Generate Public and Private Keys with OpenSSL

สำหรับการสร้าง RSA key หรือ Private Key สามารถใช้คำสั่งดังนี้
openssl genrsa -out key.pem 1024
openssl rsa -in key.pem -text -noout
Private Key ที่ได้จะอยู่ในไฟล์ชื่อ key.pem

สำหรับการสร้าง Public Key สามารถใช้คำสั่งดังนี้
openssl rsa -in key.pem -pubout -out pub.pem
openssl rsa -in pub.pem -pubin -text -noout
Public Key ที่ได้จะอยู่ในไฟล์ชื่อ pub.pem

Friday, October 11, 2019

[Batch Script] วิธีการใช้วันที่และเวลาสำหรับชื่อไฟล์ในไฟล์ Batch
[Batch Script] How to Use Date and Time for Filename in Batch File

สำหรับค่าของวันที่จะอยู่ในตัวแปรชื่อ date ซึ่งเราสามารถเรียกใช้ตามตัวอย่างดังนี้
echo Date format = %date%
echo dd = %date:~4,2%
echo mm = %date:~7,2%
echo yyyy = %date:~10,4%
สำหรับค่าของเวลาจะอยู่ในตัวแปรชื่อ time ซึ่งเราสามารถเรียกใช้ตามตัวอย่างดังนี้
echo Time format = %time%
echo hh = %time:~0,2%
echo mm = %time:~3,2%
echo ss = %time:~6,2%
จากทั้ง 2 ตัวอย่างข้างต้นเป็นการใช้ substring ในการดึงค่าส่วนที่เราต้องการ ซึ่งจะมีรูปแบบการใช้งานดังนี้
%variable_name:~start_position,length%
โดยที่
  • variable_name เป็นชื่อตัวแปรที่เก็บข้อความที่ต้องการตัด
  • start_position เป็นตำแหน่งเริ่มต้นของข้อความที่ต้องการตัด
  • length เป็นความยาวของข้อความที่ต้องการตัด

กรณีที่เราต้องการตั้งชื่อไฟล์ โดยมีวันที่และเวลาในรูปแบบ yyyymmdd_hhmmss อยู่ในชื่อไฟล์ด้วย เราสามารถใช้คำสั่งดังนี้
set filename=test_%date:~10,4%%date:~7,2%%date:~4,2%_%time:~0,2%%time:~3,2%%time:~6,2%.7z
echo %filename%
หมายเหตุ ตำแหน่งเริ่มต้นของ substring แต่ละชุดจะแตกต่างกันไป โดยขึ้นอยู่กับการตั้งค่า Date and time formats ของแต่ละเครื่อง

Thursday, October 3, 2019

[Ubuntu] วิธีการหาชื่อ Operating System และ Version ของ Linux ผ่านทาง Terminal
[Ubuntu] How to Find Name and Version of Operating System in Linux Terminal

เราสามารถใช้คำสั่งต่อไปนี้ในการหาชื่อ Operating System และ Version ใน Linux
cat /etc/os-release
lsb_release -a
hostnamectl

[NodeJS] การติดตั้ง NodeJS และ NPM บน Alpine Linux
[NodeJS] How to Install NodeJS and NPM on Alpine Linux

Alpine Linux เป็นระบบปฏิบัติการที่นิยมใช้บน Docker เนื่องจากมีการติดตั้งเฉพาะ package ที่จำเป็น ทำให้ใช้พื้นที่ในการติดตั้งน้อยกว่า Linux เวอร์ชั่นอื่นๆ

NodeJS ไม่ได้เป็น package ที่จำเป็นสำหรับระบบปฏิบัติการ จึงไม่ถูกติดตั้งมาด้วย

นอกเหนือจากนั้น NodeJS บน Alpine Linux จะไม่ติดตั้ง NPM ให้ด้วย ดังนั้นคุณจำเป็นต้องติดตั้ง nodejs-npm เพิ่มด้วย

จากข้างต้น ทำให้ได้คำสั่งที่ใช้ติดตั้ง ดังนี้
apk add --update nodejs nodejs-npm

[Laravel - Model] วิธีการ Query Pivot Table ของ Laravel Model
[Laravel - Model] How to Query Pivot Table of Laravel Model

การ select ข้อมูลโดยเอาข้อมูลจาก Pivot Table ด้วย
$this->devices()->withPivot()->get();
การอ้างอิงถึง column ใน Pivot Table จะใช้ pivot_ นำหน้าชื่อ column ที่ต้องการ ตามตัวอย่างข้างล่าง
$user->devices()->orderBy('pivot_updated_at', 'desc')->paginate();
การ update ข้อมูลใน Pivot Table โดยอ้างอิงจาก relation
$this->devices()->updateExistingPivot($deviceId, [
    'status' => 'active',
    'updated_at' => Carbon::now(),
]);
การรัน statement ที่ Pivot Table โดยตรง ซึ่งต้องใส่เงื่อนไขใน where เอง 
$this->devices()->newPivotStatement()
    ->where('user_id', $userId)
    ->whereIn('device_id', $deviceIds)
    ->update(['status' => 'inactive']);
หมายเหตุ การรัน statement ที่ Pivot Table โดยตรง สามารถเปลี่ยนจาก update เป็น delete เพื่อลบข้อมูล หรือเป็น get เพื่อดึงข้อมูลมาแสดง

Monday, September 30, 2019

[Laravel - Model] วิธีเปลี่ยน User Model สำหรับการ Authentication เมื่อสร้าง User Model เอง
[Laravel - Model] How to Change User Model for Authentication when Create User Model Manually

หลังจากที่เราสร้าง User model ใหม่หรือมีการย้าย path ของ User model เดิมไปไว้ยังที่ใหม่ เราต้องแก้ไขค่าของ model ในไฟล์ config/auth.php ด้วย

เมื่อเปิดไฟล์ config/auth.php เราจะเจอบรรทัดที่กำหนดค่าเริ่มต้นของ model เป็น App\User::class ตามรูปข้างล่าง ให้ทำการแก้ไขบรรทัดดังกล่าวเป็น Class ของ User ที่ต้องการ


เพียงเท่านี้ User model ของเราก็จะถูกเรียกใช้โดย Laravel โดยอัตโนมัติ

Thursday, September 26, 2019

[Excel] ประเภทการอ้างอิงถึง Cell ใน Excel
[Excel] Type of Cell Reference in Excel

การอ้างอิงถึง Cell หรือ Cell Reference ถูกใช้เมื่อต้องการอ้างอิงถึง Cell อื่นๆ จาก Cell ที่เราใส่สูตรคำนวณ โดย Cell ดังกล่าวจะขึ้นต้นด้วย = (Equal Sign)

การอ้างอิงถึง Cell สามารถแบ่งเป็นประเภทได้ดังนี้
  1. ประเภทการอ้างอิงถึง Cell แบ่งตามจำนวน Cell ที่อ้างอิง
    • การอ้างอิงถึง Cell เดียว สามารถใช้ชื่อ column ตามด้วยเลขแถวได้เลย เช่น A1
    • การอ้างอิงถึง Cell แบบเป็นช่วง จะใช้การอ้างอิงถึง Cell เดียว 2 อันคั่นด้วย : (colon) เช่น A1:A30

  2. ประเภทการอ้างอิงถึง Cell แบ่งตามที่อยู่ของ Cell ที่อ้างอิง
    • การอ้างอิงถึง Cell ที่อยู่ใน Worksheet เดียวกัน สามารถใช้ชื่อ column ตามด้วยเลขแถวได้เลย เช่น A1
    • การอ้างอิงถึง Cell ที่อยู่คนละ Worksheet ต้องใส่ชื่อ Sheet นำหน้าตามด้วย ! (Exclamation Mark) แล้วจึงตามด้วยการอ้างอิงถึง Cell ที่อยู่ใน Worksheet เดียวกัน เช่น Sheet2!A1
    • การอ้างอิงถึง Cell ที่อยู่คนละ Workbook ต้องใส่ชื่อไฟล์ใน [] (Square Brackets) แล้วจึงตามด้วยการอ้างอิงถึง Cell ที่อยู่คนละ Worksheet เช่น [Book1.xlsx]Sheet1!A1
    หมายเหตุ ในกรณีที่ชื่อ Sheet หรือชื่อไฟล์มีช่องว่าง ต้องใส่ ' (Single Quote) ครอบเอาไว้ เช่น 'Target sheet'!A1 หรือ '[Target file.xlsx]Sheet1'!A1

  3. ประเภทการอ้างอิงถึง Cell แบ่งตามรูปแบบการอ้างอิงของ Cell
    • การอ้างอิงถึง Cell แบบ Relative สามารถใช้ชื่อ column ตามด้วยเลขแถวได้เลย เช่น A1
    • การอ้างอิงถึง Cell แบบ Absolute ต้องใช้ $ (Dollar Sign) นำหน้าชื่อ column และหมายเลขแถว เช่น $A$1
    • การอ้างอิงถึง Cell แบบ Mixed เป็นการผสมการอ้างอิงแบบ Relative และ Absolute เช่น A$1 หรือ $A1
หมายเหตุ การอ้างอิงถึง Cell ทั้งสามประเภท สามารถนำมาใช้ผสมกันได้ เช่น Sheet1!A$1:A$5

Tuesday, September 17, 2019

[Laravel - Model] สรุป syntax ต่างๆของ where หรือ orWhere ที่ใช้ในการ Query
[Laravel - Model] Syntax of where or orWhere that is used in Query

สมมติว่า User เป็น model ของ Laravel ซึ่งมีตารางที่คู่กัน คือ users

หากเราต้องการเรียกดูข้อมูล user ที่มี name เป็น 'test'

สำหรับ SQL ก็คือ
select * from users where name = 'test';
สำหรับ Laravel สามารถใช้ syntax ได้ตามข้างล่างนี้
  1. User::where('name', 'test')->get(); 
  2. User::where('name', '=', 'test')->get();
  3. User::where(['name' => 'test'])->get();
  4. User::where([['name', '=', 'test']])->get();
  5. User::where(function($q){ 
        $q->where('name', 'test');
    })->get();
ทั้ง 5 รูปแบบข้างต้น จะถูกแปลงเป็น SQL ตามข้างต้นในการ Query ข้อมูลจาก database

หมายเหตุ รูปแบบที่ 5 เป็นการส่ง parameter แบบ Closure สำหรับการ Query ที่ซับซ้อน ซึ่งภายใน Closure นี้สามารถใช้ where ได้ตาม syntax ข้างบนเช่นกัน

[Laravel - Laradock] ข้อควรระวัง: การใช้ Laradock สำหรับการรันหลายโปรเจค จะทำให้ data folder ของแต่ละโปรเจคทับกัน ถ้าตั้งค่า env ไม่ถูกต้อง
[Laravel - Laradock] Warning: Using Laradock for Many Projects will Use the Same Data Folder if Set env Incorrect

เวลาที่เรา build และ run container ของ Laradock จะมีการสร้าง folder สำหรับเก็บข้อมูลของ Laradock ที่ path ~/.laradock/data ซึ่งเป็นค่าตั้งต้นใน env-example

Folder นี้จะเก็บข้อมูล data ของ mysql, redis และอื่นๆที่จำเป็นไว้

ถ้าหากเราใช้ Laradock ในการรันโปรเจคมากกว่า 1 โปรเจค โดยไม่แก้ไข path ดังกล่าว จะทำให้ทุกโปรเจคใช้งาน data folder ที่ path เดียวกัน

แน่นอน!!! มันจะเกิดข้อผิดพลาดขึ้นแน่นอน...

สมมติว่า โปรเจคนั้นๆใช้ mysql container ของ Laradock เป็น database

สิ่งที่ต้องเจอแน่ๆเลย คือ ข้อมูลหาย!!! เพราะ data ของโปรเจคนึงไปทับของอีกโปรเจคนึง

วิธีการป้องกัน คือ แก้ไขไฟล์ .env ใน Laradock ดังนี้
# Choose storage path on your machine. For all storage systems

DATA_PATH_HOST=~/.laradock/{project_name}
โดยที่ {project_name} เป็นชื่อของโปรเจคที่จะรันโดย Laradock

Monday, September 9, 2019

[Laravel - Exception] วิธีการแสดง Validation Errors บนหน้าเว็บ
[Laravel - Exception] How to Display Validation Errors on Web Page

เนื่องจากใช้ฟังก์ชั่น validate ตาม code ข้างล่าง
public function update()
    $this->validate($this->request, [
        'ids' => 'required|array',
        'ids.*' => 'required|integer',
    ]);
    return 'test';
}
ทำให้เวลาที่ Validate request ไม่ผ่าน มันจะ throw ValidationException โดยอัตโนมัติ ซึ่งวิธีการ Handle มี 3 วิธีดังนี้
  1. ใช้ try...catch ครอบ code ส่วน validation เพื่อ handle ValidationException ที่เกิดขึ้นในแต่ละ function ของ controller
  2. เพิ่มการ handle ใน Handler class เพื่อเป็น handle กลางสำหรับ ValidationException ที่ไม่ถูก handle จากข้อแรก
  3. ข้ามข้อ 1 และ 2 แล้วนำ ValidationException มาแสดงผลบนหน้าเว็บ เนื่องจากเวลาเกิด ValidationException ระบบจะ redirect กลับไปหน้าก่อนหน้าพร้อมกับตัวแปรชื่อ $errors
สำหรับวิธีการแสดง Validation Error บนหน้าเว็บ ให้ใส่ code ด้านล่างนี้ในส่วนของ Blade template
@foreach ($errors->all() as $error)
    <div>{{$error}}</div>
@endforeach
หมายเหตุ  ตัวแปร $errors ข้างต้นไม่สามารถตรวจสอบได้ โดยการ inspect ดู Network ของ browser และการเรียกดูจาก request ใน controller

Tuesday, September 3, 2019

[Python] วิธีการเขียนไฟล์ Excel ใน Python
[Python] How to Write Excel File in Python

การเขียนไฟล์ Excel จำเป็นต้องใช้ package xlsxwriter ซึ่งสามารถติดตั้งโดยรันคำสั่งต่อไปนี้
pip install xlsxwriter
ตัวอย่างการใช้งาน เช่น
import xlsxwriter

### สั่งสร้างไฟล์ Excel
workbook = xlsxwriter.Workbook('filepath')

### สร้าง Sheet ที่ต้องการใช้งาน โดยใช้ชื่อ default ที่เป็น Sheet1, Sheet2, ...
worksheet = workbook.add_worksheet()

### สร้าง Sheet ที่ต้องการใช้งาน โดยระบุชื่อ Sheet
worksheet2 = workbook.add_worksheet('sheetname')

### เขียนข้อมูลลง Sheet
row = 0
col = 0
for i in range(20):
    worksheet.write(row, col, i)
    col += 1

### ปิดไฟล์ Excel เมื่อเขียนเสร็จ
workbook.close()

[Python] วิธีการอ่านไฟล์ Excel ใน Python
[Python] How to Read Excel File in Python

การอ่านไฟล์ Excel จำเป็นต้องใช้ package xlrd ซึ่งสามารถติดตั้งโดยรันคำสั่งต่อไปนี้
pip install xlrd
ตัวอย่างการใช้งาน เช่น
import xlrd

### สั่งเปิดไฟล์ Excel
workbook = xlrd.open_workbook('filepath')

### เลือก Sheet ที่ต้องการใช้งานจากชื่อของ Sheet
worksheet = workbook.sheet_by_name('sheetname')

### เลือก Sheet ที่ต้องการใช้งานจากตำแหน่งของ Sheet
worksheet2 = workbook.sheet_by_index(0)

### แสดงจำนวนแถวทั้งหมด
print(worksheet.nrows)

### แสดงจำนวนคอลัมน์ทั้งหมด
print(worksheet.ncols)

### แสดงค่าข้อมูลแถวที่ระบุ
print(worksheet.row_values(1))

### แสดงค่าข้อมูล cell ที่ระบุ
print(worksheet.cell_value(0, 0))

Monday, September 2, 2019

[GIT] วิธีการเปลี่ยน Remote URL ของ GIT Repository
[GIT] How to Change Remote URL of GIT Repository

การเปลี่ยน Remote URL ของ GIT Repository จำเป็นต้องใช้ 2 คำสั่งดังนี้
  • คำสั่งสำหรับตรวจสอบ GIT remote URL ปัจจุบัน
    git remote -v
  • คำสั่งสำหรับตั้งค่า Remote URL ของ GIT Repository ใหม่
    git remote set-url <current_remote_name> <new_git_remote_url>
โดยที่ new_git_remote_url จะมีรูปแบบ URL ดังนี้
  • URL สำหรับ HTTPS
    https://github.com/USERNAME/REPOSITORY.git
  • URL สำหรับ SSH
    git@github.com:USERNAME/REPOSITORY.git

Friday, August 30, 2019

[Blogger] การทำ code snippet สำหรับ Blogger ที่เป็น HTTPS
[Blogger] How to Make Code Snippet for Blogger (HTTPS version)

  1. เข้าไปที่ Theme 
  2. กดปุ่ม Edit HTML ภายใต้ Live on Blog
  3. Copy script ด้านล่างไปใส่ไว้ในส่วนของ head ของ theme
  4. <link href='https://agorbatchev.typepad.com/pub/sh/3_0_83/styles/shCore.css' rel='stylesheet' type='text/css'/>
    <link href='https://agorbatchev.typepad.com/pub/sh/3_0_83/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
     
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shCore.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushBash.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushCpp.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushCSharp.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushCss.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushJava.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushJScript.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushPlain.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushPhp.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushPython.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushRuby.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushSql.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushVb.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushXml.js' type='text/javascript'/>
    <script src='https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/shBrushPerl.js' type='text/javascript'/>
    <script language='javascript'>
        SyntaxHighlighter.config.bloggerMode = true;
        SyntaxHighlighter.config.clipboardSwf = &#39;https://agorbatchev.typepad.com/pub/sh/3_0_83/scripts/clipboard.swf&#39;;
        SyntaxHighlighter.all();
    </script>
    
  5. กดปุ่ม Save theme
  6. ใส่ code ตามด้านล่างในส่วนของ HTML ของ Post
  7. <pre class="brush: html">
        <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
        <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
    </pre>
    
หมายเหตุ: เราไม่จำเป็นต้องใส่ brush ทุกอันในข้อ 3 สามารถเลือกเฉพาะอันที่ใช้เท่านั้นได้ สำหรับ brush เพิ่มเติม สามารถดูได้จาก http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/

Thursday, August 29, 2019

[Laravel - Exception] ระวังข้อผิดพลาด "Prepared statement contains too many placeholders" หากมีการ Bulk Insert ข้อมูลจำนวนมาก
[Laravel - Exception] Warning: "Prepared statement contains too many placeholders" Exception if Bulk Insert Large Data

การทำ bulk insert หรือการ insert ข้อมูลทีละเยอะๆ สามารถช่วยลดจำนวนการยิง query หลายๆรอบได้ ซึ่งส่งผลให้เวลาในการทำงานลดลงอย่างเห็นได้ชัด โดยเฉพาะอย่างยิ่ง เมื่อ Database อยู่คนละเครื่อง Server

แต่... อย่าเพิ่งคิดนะครับว่า เราจะยิงข้อมูลเป็นก้อนใหญ่ๆไปเลยทีเดียวได้

เพราะว่ามันก็มี limit ในเรื่องของ placeholder อยู่เหมือนกัน ซึ่งถ้าหากเราส่งข้อมูลก้อนใหญ่เกินไปก็จะได้ error นี้กลับมา
PDOException: SQLSTATE[HY000]: General error: 1390 Prepared statement contains too many placeholders in /var/www/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
แล้ว placeholder มาจากไหน?

Thursday, August 15, 2019

[Laravel - Config] วิธีการเพิ่มหรือแก้ไขค่าตัวแปรในไฟล์ .env ในขณะ Runtime
[Laravel - Config] How to Add or Modify Variable Value in .env File at Runtime

ไฟล์ .env เป็นไฟล์สำหรับเก็บค่า environment variables ต่างๆของ Application

โดยปกติแล้ว เราสามารถใส่ชื่อตัวแปรและค่าของตัวแปรนั้นๆเข้าไปในไฟล์ .env ได้เลย

แต่ในบางกรณี เราไม่สามารถกำหนดค่าของตัวแปรนั้นได้ เช่น ค่าที่ต้อง encrypt ผ่าน Application หรือค่าของตัวแปรนั้นสามารถหาได้ในขณะ Runtime เท่านั้น เช่น IP address ของ Host server เป็นต้น

[Docker - AWS] วิธีการหา IP address ของ Host ที่เป็น EC2 จากภายใน Docker Container
[Docker - AWS] How to Find IP Address of EC2 Host from Inside of Docker Container

สำหรับ Docker ที่รันใน AWS นั้น ข้อมูล Instance meta-data ของ Host ยังคงสามารถเรียกใช้ได้จากภายใน Container

ดังนั้นเราไม่จำเป็นต้องหาวิธีส่งค่า Host IP address เข้าไปใน Docker Container ให้ยุ่งยาก เราสามารถเรียกใช้ local-ipv4 หรือ public-ipv4 จาก Instance meta-data ได้เลย โดยใช้คำสั่งดังนี้
curl http://169.254.169.254/latest/meta-data/{category}
โดยที่ {category} เป็น local-ipv4 หรือ public-ipv4

นอกจาก local-ipv4 และ public-ipv4 แล้ว ยังมี categories อื่นๆที่ยังสามารถเรียกใช้ได้อีก อ่านข้อมูลเพิ่มเติมได้ที่ EC2 Instance Metadata

Thursday, August 8, 2019

[Laravel - Scheduler] การใช้ Environment Variable ของระบบปฏิบัติการใน Laravel Scheduler
[Laravel - Scheduler] How to Use Environment Variable of Operating System in Laravel Scheduler

Laravel scheduler ใช้ Crontab ในการรันคำสั่งต่างๆตามเวลาที่กำหนดบน Linux

เมื่อเราต้องการใช้งาน Laravel scheduler เราเพียงเพิ่มการตั้งค่าตามด้านล่างนี้ใน Cron ของ server
* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
สำหรับการใช้ Environment Variable ของระบบปฏิบัติการ เราจำเป็นต้องสร้าง shell script ขึ้นมาตัวนึง เพื่อ export ตัวแปรที่เราต้องการใช้ก่อน

Wednesday, August 7, 2019

[Laravel - Model] เรื่องที่ควรรู้เกี่ยวกับ Attributes ใน Laravel Model
[Laravel - Model] What to Know about Attributes in Laravel Model

นอกจาก Laravel Model จะมี Attributes ที่ชื่อตามชื่อ Column ของ Table ใน Database แล้ว Laravel Model ยังมีตัวแปรและ Function สำหรับการจัดการ Attributes พวกนี้อีกด้วย โดยมีรายละเอียดดังนี้

ตัวแปรสำหรับการจัดการ Attributes ใน Laravel Model ประกอบด้วย
  • $fillable - เป็นตัวแปรที่กำหนดว่า Attributes ใดสามารถแก้ไขค่าได้บ้าง
  • $cast - เป็นตัวแปรที่กำหนดว่า Attributes ใดต้องเปลี่ยนประเภทตัวแปรบ้าง ซึ่งประเภทตัวแปร ประกอบด้วย integer, real, float, double, decimal:<digits>, string, boolean, object, array, collection, date, datetime และ timestamp
  • $dates - เป็นตัวแปรที่กำหนดว่า Attributes ใดต้องถูกเปลี่ยนประเภทเป็น datetime บ้าง ซึ่ง attribute ดังกล่าวจะถูก cast เป็น Carbon instance
  • $hidden - เป็นตัวแปรที่กำหนดว่า Attributes ใดต้องถูกตัดออก เมื่อมีการแปลง Model ไปเป็น JSON
  • $appends - เป็นตัวแปรที่กำหนดว่า Attributes ใดต้องถูกเพิ่มเข้าไป เมื่อมีการแปลง Model ไปเป็น JSON

Monday, August 5, 2019

[Laravel - Model] ข้อควรระวังของการใช้ฟังก์ชั่น where และ orWhere ของ Laravel Model
[Laravel - Model] Warning: Using where and orWhere functions of Laravel Model

สมมติว่า
  • OrganizationChildren เป็น Laravel model ที่ผูกกับตาราง organization_children ในฐานข้อมูล
  • OrganizationChildren ประกอบด้วยฟิลด์ parent_organization_id และ child_organization_id 
  • $org1->id และ $org2->id เป็นค่า id ของ Organization โดยมีค่าเป็น 1 และ 2 ตามลำดับ

ถ้าเราต้องการ query ข้อมูล โดยใช้ SQL ดังนี้
select * 
from `organization_children` 
where (`parent_organization_id` = 1 and `child_organization_id` = 2) or 
(`parent_organization_id` = 2 and `child_organization_id` = 1)

[Laravel - Package] วิธีการเปลี่ยนข้อมูลที่ใช้สำหรับ Subject Claim ของ JWT ใน Laravel Model
[Laravel - Package] How to Change Data for Subject Claim of JWT in Laravel Model

JSON Web Token (JWT) ถูกใช้ใน stateless web application

jwt-auth เป็น JWT package ที่นิยมใช้สำหรับ Laravel framework

package นี้จะใช้ ID ของผู้ใช้งานเป็น sub claim (subject claim) โดยอัตโนมัติ

เนื่องจาก payload ของ JWT สามารถ decode ที่ใดก็ได้ โดยไม่จำเป็นต้องใช้ key ใดๆ การใช้ ID ของผู้ใช้งาน จึงทำให้เกิดปัญหาทางด้านความปลอดภัย

คุณสามารถเปลี่ยนฟิลด์ ID ของผู้ใช้งานเป็นฟิลด์อื่นด้วยวิธีตามด้านล่างนี้ เพื่อหลีกเลี่ยงปัญาด้านความปลอดภัย

Saturday, August 3, 2019

[PHP] วิธีการพิมพ์ข้อความออกทาง STDOUT หรือ STDERR หรือ SYSLOG
[PHP] How to Print Out Message to STDOUT or STDERR or SYSLOG

ในบางครั้งคุณมีความจำเป็นต้องพิมพ์ข้อความออกทาง system log หรือ I/O streams อื่นๆ เช่น standard output, standard error

สมมติว่า $str เป็นข้อความที่คุณต้องการ print

คุณสามารถใช้ method ข้างล่างสำหรับการพิมพ์ข้อความออก system log
syslog(LOG_INFO, $str);
อ่านข้อมูลเพิ่มเติมที่ https://www.php.net/manual/en/function.syslog.php

คุณสามารถใช้ method ข้างล่างสำหรับการพิมพ์ข้อความออก I/O streams อื่นๆ
$out = fopen('php://stdout', 'w'); //output handler
fputs($out, $str); //writing output operation
fclose($out); //closing handler
โดยที่ php://stdout สามารถแทนด้วย php://stderr หรือ php://output
อ่านข้อมูลเพิ่มเติมที่ https://www.php.net/manual/en/wrappers.php.php

Monday, July 8, 2019

[Docker] วิธีการ Bash หรือ Shell เข้าไปภายใน Docker Container ด้วยผู้ใช้งานที่กำหนด
[Docker] How to Bash or Shell into Docker Container with Specific User

คุณสามารถ shell เข้าไปใน docker container ได้ โดยใช้คำสั่งดังนี้
docker exec -it --user <username> <container_id> bash
โดยที่
  • username เป็น username ของผู้ใช้งานภายใน Docker container
  • container_id เป็น ID ของ Docker container นั้นๆ
โดยปกติแล้ว คุณไม่จำเป็นต้องใส่ user option ก็ได้ แต่คุณจะ shell เข้าไปเป็น root user ซึ่งคำสั่งที่ใช้จะเป็นดังนี้
docker exec -it <container_id> bash
ในบางครั้ง Docker container อาจจะไม่มี bash คุณต้องเปลี่ยนไปใช้คำสั่งดังนี้แทน
docker exec -it <container_id> /bin/sh

Monday, July 1, 2019

[PHP] วิธีการเปิดใช้ environment variables ใน PHP FPM
[PHP] How to Enable Environment Variables in PHP FPM

PHP FPM จะถูก clear environment variables ออก เนื่องจากเหตุผลทางด้านความปลอดภัย

แต่ในบางครั้งเรามีความจำเป็นต้องใช้ตัวแปรพวกนี้ เช่น environment variables ที่ถูกส่งผ่านเข้ามาจากการสร้าง Docker image เพื่อเก็บข้อมูล log หรือสถิติต่างๆ

สำหรับการอนุญาตให้ environment variables ถูกส่งต่อไปยัง PHP FPM ให้แก้ไขไฟล์ /etc/php/7.2/fpm/pool.d/www.conf โดยเอา comment บรรทัดข้างล่างนี้ออก
;clear_env = no
จะได้ผลลัพธ์ดังภาพข้างล่าง

หลังจากนั้นให้ restart service php7.2-fpm ด้วยคำสั่งดังนี้
service php7.2-fpm restart

Friday, June 28, 2019

[Docker] วิธีการใช้ Git Tag เป็น Version ของ Code ใน Docker Image
[Docker] How to Use Git Tag as Version of Code in Docker Image

ในกรณีที่เราต้องการใช้ GIT Tag เพื่อแสดงเป็น Version บนหน้าเว็บ มีวิธีทำดังนี้

ขั้นแรก แก้ไข Dockerfile โดยเพิ่มบรรทัดตามด้านล่างนี้
ARG GIT_TAG=12345
ARG MAIN_FILE
RUN sed -i -e "s/version:\"0\.0\.0\"/version:\"${GIT_TAG}\"/" public/$MAIN_FILE
  • บรรทัดแรก เป็นการประกาศว่า เราจะรับตัวแปรชื่อ GIT_TAG ที่จะถูกส่งเข้ามาทาง build argument ตอนสั่ง docker build ซึ่งถ้าไม่มีค่าอะไรส่งเข้ามาเลย ให้ตั้งค่าตั้งต้นเป็น 12345
  • บรรทัดที่สอง เป็นการประกาศว่า เราจะรับตัวแปรชื่อ MAIN_FILE ที่จะถูกส่งเข้ามาทาง build argument
  • บรรทัดที่สุดท้าย เป็นการรันคำสั่งเพื่อ replace ค่า 0.0.0 ในไฟล์ MAIN_FILE ด้วยค่าของ GIT_TAG

[Bash Script] วิธีการประกาศและใช้ตัวแปรใน Bash Script
[Bash Script] How to Declare and Use Variable in Bash Script

สำหรับการประกาศตัวแปรพร้อม assign ค่า ให้ใช้รูปแบบดังนี้
VARIABLE_NAME=VALUE
หมายเหตุ: ไม่มีช่องว่างข้างหน้าและข้างหลังเครื่องหมายเท่ากับ (=)

สำหรับการเรียกใช้ค่าตัวแปร ให้ใช้รูปแบบดังนี้
echo $VARIABLE_NAME;
หมายเหตุ: มี $ นำหน้าชื่อตัวแปร

สำหรับการ assign ค่าที่ได้จากการรันคำสั่งอื่นๆ ให้ใช้รูปแบบดังนี้
VARIABLE_NAME=$(COMMAND)
หมายเหตุ:  คำสั่งที่รันอยู่ภายใน $(...) ตัวอย่างเช่น
VERSION=1.0.0
MAIN_FILE=$(grep -o 'main.[0-9a-z]*.js' public/index.html)
sed -i -e "s/version:\"0\.0\.0\"/version:\"$VERSION\"/" public/$MAIN_FILE

Monday, June 24, 2019

[Docker] วิธีการส่งผ่านค่า Build Argument และตั้งค่าเป็น Environment Variable
[Docker] How to Pass Build Argument and Set as Environment Variable

สมมติว่า var_name เป็น argument ที่เราต้องการส่งเข้าไป เพื่อตั้งค่าเป็น Environment Variable

ใน Dockerfile ให้เพิ่มบรรทัดดังนี้
ARG var_name
ENV env_var_name=$var_name
บรรทัดแรกเป็นการรับค่า var_name ที่เป็น build argument
บรรทัดที่ 2 เป็นการตั้งค่า Environment Variable โดยให้ชื่อว่า env_var_name และมีค่าตาม var_name

หลังจากแก้ไข Dockerfile แล้ว เรามีวิธีการส่งค่า build argument หลายแบบดังนี้

แบบที่ 1 ส่งชื่อตัวแปรพร้อมค่าของตัวแปรที่เรากำหนดเอง
docker build --build-arg var_name=VALUE [--build-arg var_name2=VALUE2 ...] (...)

แบบที่ 2 ส่งชื่อตัวแปรพร้อมค่าของตัวแปรจาก environment variable ปัจจุบัน
docker build --build-arg var_name=${VARIABLE_NAME} (...)
โดยที่ VARIABLE_NAME เป็นชื่อของ environment variable

แบบที่ 3 ส่งชื่อตัวแปรที่เป็นชื่อเดียวกันกับ environment variable ซึ่งค่าของตัวแปรนี้จะถูกตั้งตามค่า environment variable ที่ชื่อเดียวกันโดยอัตโนมัติ
docker build --build-arg var_name (...)

[Bash Script] วิธีการหาส่วนของข้อความที่อยู่ภายในไฟล์ข้อความ โดยใช้ Regular Expression
[Bash Script] How to Find Substring within Text File by Using Regular Expression

คุณสามารถใช้คำสั่ง grep ตามด้านล่างนี้
grep -o 'Regex pattern' filename
ตัวอย่างเช่น
grep -o 'main.[0-9a-z]*.js' public/index.html
ในกรณีนี้ index.html เป็นไฟล์ที่ถูกสร้างโดย AngularJS และมีชื่อไฟล์ main.{hash}.js อยู่ภายในไฟล์

เราไม่สามารถรู้ค่า hash ของชื่อไฟล์นี้ได้ แต่เรารู้รูปแบบข้อความของชื่อไฟล์นี้

ดังนั้นเราสามารถใช้ Regular Expression ในการหาชื่อไฟล์นี้จาก index.js ได้

Thursday, June 13, 2019

[Laravel - Carbon] ข้อควรระวัง: การใช้ Carbon::today()->toDateString() เพื่อเปรียบเทียบกับ Date String
[Laravel - Carbon] Warning: Using Carbon::today()->toDateString() for Comparing with Date String

Carbon เป็น PHP API extension สำหรับ DateTime

Carbon::today() เป็นฟังก์ชั่นที่ใช้สร้าง Carbon object ที่มีวันที่เป็นวันปัจจุบัน อย่างไรก็ตามในส่วนของเวลาจะเป็น 00:00:00 

จากภาพด้านล่างเป็นผลลัพธ์การเปรียบเทียบระหว่าง Carbon::today() กับวันที่ในรูปแบบข้อความ โดยใช้การเปรียบเทียบข้อความปกติ


ดังนั้นถ้าต้องการเปรียบเทียบเพียงวันที่เท่านั้น ให้เปลี่ยนไปใช้ Carbon::today()->toDateString() แทน

ผลลัพธ์การเปรียบเทียบจะเป็นดังภาพด้านล่าง

Thursday, May 30, 2019

[Database - SQL] วิธีคำนวณระยะทางระหว่างพิกัด (Latitude, Longitude) 2 พิกัด
[Database - SQL] How to Calculate Distance between 2 Points of (Latitude, Longitude)

เนื่องจากผิวโลกมีความโค้ง จึงต้องใช้ haversine formula ในการคำนวณระยะทางที่สั้นที่สุดระหว่างพิกัดสองพิกัดบนผิวโลก

สมมติว่า ตาราง location ประกอบด้วยคอลัมน์ lat และ lon ที่เก็บค่า Latitude และ Longitude ตามลำดับของแต่ละพิกัด และพิกัดที่สนใจอยู่ที่ตำแหน่ง ([lat0], [lon0])

เราสามารถค้นหาพิกัดที่อยู่ใกล้เคียงกับพิกัดที่เราสนใจ ภายในรัศมี 1 กิโลเมตร โดยใช้ SQL ดังต่อไปนี้

SELECT *, 6373  * 2 * ATAN2(
    SQRT(
        POW(SIN((lat - [lat0]) * PI() / 180 / 2), 2) +
        COS(ABS([lat0]) * PI() / 180) *
        COS(ABS(lat) * PI() / 180) *
        POW(SIN((lon - [lon0]) * PI() / 180 / 2), 2)
    ),
    SQRT(1-(
        POW(SIN((lat - [lat0]) * PI() / 180 / 2), 2) +
        COS(ABS([lat0]) * PI() / 180) *
        COS(ABS(lat) * PI() / 180) *
        POW(SIN((lon - [lon0]) * PI() / 180 / 2), 2))
    )
) as dist
FROM `location`
HAVING  dist < 1 
ORDER BY dist

โดยที่
  •     6373 เป็นรัศมีของโลก มีหน่วยเป็นกิโลเมตร
  •     lat เป็นค่า Latitude ของ record ในตาราง location
  •     lon เป็นค่า Longitude ของ record ในตาราง location
  •     [lat0] เป็นค่า Latitude ของพิกัดที่เราสนใจ
  •     [lon0] เป็นค่า Longitude ของพิกัดที่เราสนใจ
  •     dist เป็นระยะทางระหว่างพิกัดที่เราสนใจกับพิกัดของ record ในตาราง location มีหน่วยเป็นกิโลเมตร

Monday, May 27, 2019

[Laravel - Exception] ข้อควรระวัง: โปรดระวังการใช้ Exception class ใน catch เมื่อใช้ try...catch
[Laravel - Exception] Warning: Using Wrong Exception Class in catch when Using try...catch

try...catch ถูกใช้ในการ handle exception

อย่างไรก็ตาม มีบางกรณีที่ทำให้ exception ไม่ถูก handle ในส่วนของ catch และถูก throw ออกไปโดยไม่มีการ handle ใดๆ

ผมจะใช้โค้ดตัวอย่างเพื่อแสดงว่า โค้ดส่วนใดที่คุณต้องระวังเป็นพิเศษ

โค้ดทั้งสองตัวอย่างเป็น Laravel commands ที่สามารถเรียกใช้งาน โดยรันคำสั่งใน console ดังนี้
php artisan test-exception

Friday, May 17, 2019

[Laravel - AWS] วิธีการตั้งค่า timeout สำหรับ InstanceProfileProvider ของ AWS PHP SDK
[Laravel - AWS] How to Set Timeout for InstanceProfileProvider of AWS PHP SDK

InstanceProfileProvider เป็น credential provider ที่ใช้ credentials จาก EC2 metadata server

สำหรับข้อมูลของ EC2 metadata server อ่านได้ที่ https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

ใน InstanceProfileProvider class ของ aws-php-sdk library เราจะพบ constructor ตามภาพด้านล่าง


เราจะพบตัวแปร $config['timeout'] แต่เราจะตั้งค่ามันยังไง!!!

Thursday, May 16, 2019

[ELK - Logstash] วิธีการ parse ข้อความ Log ที่มีหลายรูปแบบ โดยใช้ GROK
[ELK - Logstash] How to Parse Multiple Log Message by Using GROK

สำหรับการ parse ข้อความโดย GROK คุณต้องเพิ่ม grok filter ตามตัวอย่างด้านล่าง (อ้างอิงจาก https://www.elastic.co/guide/en/logstash/2.1/plugins-filters-grok.html#plugins-filters-grok-match)

สำหรับรายละเอียดของ GROK patterns อ่านได้ที่ https://github.com/elastic/logstash/blob/v1.4.0/patterns/grok-patterns

คุณสามารถทดสอบ pattern ที่คุณสร้างขึ้นกับข้อความจริง ได้ที่ https://grokdebug.herokuapp.com/

Tuesday, April 30, 2019

[Laravel - Laradock] การแก้ปัญหา "Fatal error loading the DB: Invalid argument" ของ Redis ใน Laradock
[Laravel - Laradock] How to Fix "Fatal error loading the DB: Invalid argument" of Redis in Laradock

เมื่อสั่ง docker-compose up -d redis ใน Laradock จะไม่สามารถ start ได้ และเมื่อดู log จะพบ error ดังรูปข้างล่าง
วิธีแก้ไข คือ ลบ folder redis ที่ path C:\Users\{user}\.laradock\data\redis แล้วสั่งรัน docker-compose up -d redis ใหม่อีกครั้ง ({user} แทนด้วย username ของ user ที่จะรันคำสั่ง)

Tuesday, April 23, 2019

[ELK - Filebeat] การติดตั้งและตั้งค่า Filebeat บน Ubuntu เพื่อเก็บ log ใน Logstash
[ELK - Filebeat] How to Install and Configure Filebeat on Ubuntu for Storing Log in Logstash

การติดตั้ง Filebeat สามารถทำได้โดยรันคำสั่งดังนี้
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.6.2-amd64.deb
dpkg -i filebeat-6.6.2-amd64.deb
Path ของ Filebeat ที่ควรรู้มีดังนี้
config path/etc/filebeat
log path /var/log/filebeat

กรณีใช้ Filebeat ยิง log ไปที่ Logstash จำเป็นจะต้อง load template ไปที่ elasticsearch แบบ manual โดยใช้คำสั่งดังนี้
filebeat setup --template -E output.logstash.enabled=false -E 'output.elasticsearch.hosts=["localhost:9200"]'

[Database - SQL] วิธีการ Query หา Record ที่มีค่ามากที่สุดหรือน้อยที่สุด
[Database - SQL] How to Query a Record that Has Maximum or Minimum Value

สมมติว่า user_login เป็นตารางในฐานข้อมูลที่มีคอลัมน์ login_at สำหรับเก็บวันเวลาที่ผู้ใช้งาน login เข้าใช้งานระบบ

ในกรณีที่เราต้องการหา record ของการ login เข้าใช้งานล่าสุดของผู้ใช้งานทุกคน (login_at มีค่ามากที่สุด) เราสามารถใช้คำสั่ง SQL ตามด้านล่างนี้ได้เลย
SELECT * 
FROM user_login 
WHERE EXISTS (
    SELECT 1
    FROM user_login AS ul
    GROUP BY user_id
    HAVING user_id = users_login.user_id AND
        MAX(login_at) = user_login.login_at
)
ในทางตรงกันข้าม ถ้าเราต้องการหา record ของการ login เข้าใช้งานครั้งแรกสุดของผู้ใช้งานทุกคน (login_at มีค่าน้อยที่สุด) เราสามารถใช้คำสั่ง SQL ตามด้านล่างนี้ได้เลย
SELECT * 
FROM user_login 
WHERE EXISTS (
    SELECT 1
    FROM user_login AS ul
    GROUP BY user_id
    HAVING user_id = users_login.user_id AND
        MIN(login_at) = user_login.login_at
)

Wednesday, April 17, 2019

[Ubuntu] วิธีการเพิ่มหรือแก้ไขผู้ใช้งานบน Ubuntu
[Ubuntu] How to Add and Modify User on Ubuntu

คำสั่งสำหรับเพิ่ม account ผู้ใช้งานใหม่
adduser <username>
คำสั่งสำหรับเพิ่มผู้ใช้งานของคุณเข้ากลุ่ม sudo เพื่ออนุญาตให้ผู้ใช้งานคนนั้นรันคำสั่งด้วย administrative privileges ได้ โดยใส่ sudo นำหน้า
usermod -aG sudo <username>
คำสั่งสำหรับสลับเป็นผู้ใช้งานอื่นชั่วคราว ในขณะที่ผู้ใช้งานเป็น root
su - <username>
คำสั่งสำหรับเปลี่ยนรหัสผ่านผู้ใช้งานของคุณ
passwd <username>
คำสั่งสำหรับตรวจสอบผู้ใช้งานปัจจุบัน
whoami

Thursday, April 11, 2019

[Blogger] การทำ Code Snippet สำหรับ Blogger ที่เป็น HTTP
[Blogger] How to Make Code Snippet for Blogger (HTTP Version)

  1. เข้าไปที่ Theme 
  2. กดปุ่ม Edit HTML ภายใต้ Live on Blog
  3. Copy script ด้านล่างไปใส่ไว้ในส่วนของ head ของ theme
  4. <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
    <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
    
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
    <script language='javascript'>
        SyntaxHighlighter.config.bloggerMode = true;
        SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
        SyntaxHighlighter.all();
    </script>
    
  5. กดปุ่ม Save theme
  6. ใส่ code ตามด้านล่างในส่วนของ HTML ของ Post
  7. <pre class="brush: html">
        <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
        <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
    </pre>
    
หมายเหตุ: เราไม่จำเป็นต้องใส่ brush ทุกอันในข้อ 3 สามารถเลือกเฉพาะอันที่ใช้เท่านั้นได้ สำหรับ brush เพิ่มเติม สามารถดูได้จาก http://alexgorbatchev.com/SyntaxHighlighter/manual/brushes/

Thursday, April 4, 2019

[Laravel - Exception] วิธีการแก้ไข exception หลังจากพลาดรันคำสั่ง php artisan config:cache
[Laravel - Exception] How to Fix Exception after Running php artisan config:cache Command

คำอธิบายของคำสั่ง config:cache คือ สร้าง cache file สำหรับการโหลดค่า config ที่เร็วขึ้น (คุณสามารถรันคำสั่ง php artisan ใน console เพื่อดูคำอธิบายของแต่ละคำสั่งได้)

อย่างไรก็ตาม ผลกระทบจากการรัน  php artisan config:cache อาจจะประกอบด้วย
  1. Website/APIs ของคุณจะตอบกลับด้วย error code 500 Internal Server Error เสมอ โดยไม่มี log ใดๆใน laravel.log
  2. ทุกคำสั่งที่รันด้วย php artisan จะ throw exception ตามภาพด้านล่าง
  3. ทุกคำสั่งที่รันด้วย composer จะรันได้ตามปกติ

วิธีแก้ไข exception นี้ คือ การลบ cache file ที่ถูกสร้างขึ้นมา ซึ่งสำหรับ Laravel 5.6 cache file ดังกล่าวจะอยู่ที่ bootstrap/cache/config.php

Sunday, March 31, 2019

[AWS] การติดตั้ง ELK อย่างง่ายบน AWS
[AWS] How to Install ELK on AWS

ELK stack เป็น platform สำหรับการจัดการ log ซึ่งประกอบไปด้วย 3 ส่วน คือ
  1. Elasticsearch (deep search and data analytics)
  2. Logstash (centralized logging and parsing)
  3. Kibana (powerful data visualizations)

การติดตั้งเริ่มต้นโดยเข้าไปที่ ELK Certified by Bitnami แล้วทำการ subscribe และทำตามขั้นตอนไปจนจบ ก็จะได้ Instance ที่มี ELK stack มาใช้งาน

Friday, March 29, 2019

[Docker] การติดตั้ง Docker และ Docker Compose บน Ubuntu
[Docker] How to Install Docker and Docker Compose on Ubuntu

ถ้าหากเครื่อง server ยังไม่ได้ติดตั้ง curl ให้ติดตั้ง curl ก่อน โดยใช้คำสั่งดังนี้
sudo apt-get install curl
หลังจากนั้นให้ติดตั้ง Docker โดยใช้คำสั่งดังนี้
sudo curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
สำหรับการทดสอบ เมื่อติดตั้ง Docker สำเร็จแล้ว ให้รันคำสั่งดังนี้
docker run hello-world
จะได้ผลลัพธ์ดังรูป


หลังจากนั้นให้ติดตั้ง Docker Compose โดยใช้คำสั่งดังนี้ 
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
สำหรับการทดสอบ เมื่อติดตั้ง Docker Compose สำเร็จแล้ว ให้รันคำสั่งดังนี้
docker-compose -v
จะได้ผลลัพธ์ดังรูป


Tuesday, February 5, 2019

[Server - Ubuntu] การสร้างหรือต่ออายุ Let's Encrypt Certificate สำหรับ Website
[Server - Ubuntu] How to Create or Renew Let's Encrypt Certificate for Website

สมมติว่า ได้ลง certbot ไว้ในเครื่อง server เรียบร้อยแล้ว
  1. รันคำสั่ง sudo certbot certonly -d {domain_name}
  2. เลือก option ที่ 2 เพื่อใช้วิธีการระบุ path ของ public folder ของเว็บแทนการสร้าง standalone web server ขึ้นมา
  3. ใส่ path ของ public folder แล้วกด enter 
ไฟล์ certificates ที่ถูกสร้างใหม่ จะอยู่ใน folder /etc/letsencrypt/live/{domain_name} ซึ่งเราสามารถนำไฟล์นี้ไปแทนที่ไฟล์ certificates เดิมที่กำลังจะหมดอายุได้เลย

[Laravel - Command] วิธีการเรียกใช้ command ที่ถูกต้อง จากอีก command นึงใน Laravel
[Laravel - Command] How to Call Laravel Command from Other Commands

บางครั้งเราต้องการสร้าง command เพื่อเรียกใช้ชุด command ที่ได้สร้างไว้ก่อนหน้าแล้ว

สมมติว่า มี 2 commands คือ command A และ B แล้วเราสร้าง command C มาอีกตัว เพื่อเรียกใช้ 2 commands นี้

ถ้าหากเป็นการเรียกรัน command จาก controller ปกติ ก็จะใช้คำสั่งดังนี้
Artisan::call('A');
Artisan::call('ฺB');

แต่สำหรับการเรียกรัน command จากอีก command นึง ห้ามใช้ Artisan::call โดยเด็ดขาด เนื่องจากถ้าหากเกิด exception ขึ้น มันจะไม่ throw exception ออกมายัง command C ทำให้ command C สามารถรันต่อจนเสร็จได้ ถึงแม้จะเกิด exception ใน command A หรือ B ซึ่งเราจะไม่สามารถรู้ได้เลยว่า มันทำงานเสร็จแล้วจริงๆหรือมันเกิด exception ขึ้น ถ้าเราไม่ดูจาก error logs

ในความเป็นจริงแล้ว เราควรจะรู้ว่า command ใดเกิด exception ขึ้น และไม่มีความจำเป็นที่ต้องรัน command อื่นๆต่อไป ในกรณีที่ exception ได้เกิดขึ้นแล้ว ดังนั้นให้ใช้ $this->call แทนดังนี้
$this->call('A');
$this->call('ฺB');

อ่านเพิ่มเติม: https://laravel.com/docs/5.7/artisan#calling-commands-from-other-commands

Tuesday, January 15, 2019

[Laravel - Model] การแปลง Query Builder ไปเป็น SQL Query String
[Laravel - Model] How to Convert Query Builder to SQL Query String

สาเหตุที่ต้องแปลง Query Builder ไปเป็น SQL Query String ก็มีหลายสาเหตุด้วยกัน เช่น การ debug query ที่เกิด error ขึ้น เป็นต้น ซึ่งสามารถใช้โค้ดได้ตามด้านล่างนี้
$sql= str_replace(array('?'), array('\'%s\''), $query->toSql());
$sql = vsprintf($sql, $query->getBindings());
เมื่อ $query คือ Query Builder และ $sql คือ Query String ที่ได้จากการแปลง