Category Archive Tips & Tricks

windows: ลงโปรแกรมหลายเครื่อง

ถ้าต้องลงโปรแกรมเหมือน ๆ กันหลาย ๆ เครื่อง หรือตามไปอัพเดตโปรแกรมทุกเครื่องให้เป็นตัวล่าสุด จะดีมั๋ยถ้าจะลดเวลาที่ต้องใช้ลงไป ใช้สคริปท์ง่าย ๆ หมือนฝั่่ง Linux ที่ใช้ไฟล์เดียวก็ลงโปรแกรมที่ต้องใช้ได้ครบ

ก่อนอื่นโปรแกรมตัวนี้ชื่อ Chocolatey ไม่ต้องไปดาวน์โหลดมาก่อน วิธีติดตั้งมีทั้งแบบใช้คนเดียวและแบบองค์กรขนาดใหญ่ เพื่ออธิบายง่าย ๆ และที่ใช้ตอนนี้ไม่ได้มีเครื่องที่ต้องลงโปรแกรมมาก ขอใช้แบบลงส่วนตัวละกัน

  1. เปิด PowerShell ขึ้นมาโดนสิทธิ administrator copy
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString(‘https://community.chocolatey.org/install.ps1’))
    ไปวางแล้ว enter ก็ลงโปรแกรมติดตั้งเสร็จแล้ว
  2. ต่อไปคือสร้างลิสต์โปรแกรมที่จะติดตั้งลงเครื่องอื่น ๆ ขึ้นมาเพื่อความสดวกจะติดตัว Chocolatey Gui ( ทำแค่เครื่องของเราเครื่องเดียวก็พอ ) พิมพ์ choco install chocolateygui ใน PowerShell แลัว enter
    1. เปิดโปรแกรม Chocolatey GUI จากเมนูของ windows โดยสิทธิ administrator จะเห็นว่าซ้ายมือจะมีอยู่ 2 เมนูคือ
      • This PC คือรายชื่อโปรแกรมที่ติดตั้งในเครื่องเรา
      • chocolatey จะเป็นหน้าที่ไว้ค้นหาโปรแกรมที่จะติดตั้ง ต้องการจะติดตั้งโปรแกรมอะไรก็ค้นหาเอาจากหน้านี้ คลิกขวา install มันจะดาวน์โหลดโปรแกรมและติดตั้งให้เอง
    2. เมื่อลง program ที่ต้องการครบแล้วไปที่ This PC มุมขวาบนจะมีปุ่ม Export ให้เซฟไฟล์ไว้ใน flash drive จะเป็นไฟล์ Chocolatey.config
  3. ไปที่เครื่องที่จะติดตั้งโปรแกรมเพิ่มเปิด PowerShell ขึ้นมาโดนสิทธิ administrator และลง Chocolatey เหมือนขั้นตอนที่ 1
  4. ติดตั้งโปรแกรมในลิสต์โดยใช้ choco install <path-to-exported-file> เช่น choco install “E:\Chocolatey.config” โปรแกรมจะถูกติดตั้งเพิ่มตามที่มีอยู่ในลิสต์ที่ได้ทำไว้
  5. เวลาผ่านไปโปรแกรมที่ลงไว้เริ่มเก่าแล้วก็สั่งอัพเดตโดยใช้ choco upgrade all -y ถ้าจะ upgrade บางโปรแกรมหรือจะยกเว้นบางโปรแกรมก็ทำตามคู่มือ https://docs.chocolatey.org/en-us/choco/commands/upgrade

ถ้าไม่เข้าใจลองดูวิธีได้จากคู่มือ https://docs.chocolatey.org/en-us/chocolatey-gui/user-interface/main-window/actions/export ตัวสคริปต์ที่มันใช้เป็นไฟล์ง่าย ๆ อย่างที่ผมใช้คือ

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="avastfreeantivirus" version="21.6.6446.0" />
  <package id="chocolatey-core.extension" version="1.3.5.1" />
  <package id="chocolatey-dotnetfx.extension" version="1.0.1" />
  <package id="chocolatey-visualstudio.extension" version="1.9.0" />
  <package id="chocolatey-windowsupdate.extension" version="1.0.4" />
  <package id="chocolatey" version="0.10.15" />
  <package id="chocolateygui" version="0.18.1" />
  <package id="dotnetfx" version="4.8.0.20190930" />
  <package id="filezilla" version="3.55.1" />
  <package id="Firefox" version="91.0" />
  <package id="gimp" version="2.10.24.3" />
  <package id="GoogleChrome" version="92.0.4515.131" />
  <package id="googledrive" version="2.34.5075.1619" />
  <package id="greenshot" version="1.2.10.6" />
  <package id="keepass.install" version="2.48.1" />
  <package id="microsoft-teams" version="1.4.00.19572" />
  <package id="microsoft-windows-terminal" version="1.9.1942.0" />
  <package id="notepadplusplus.install" version="8.1.2" />
  <package id="postman" version="8.9.1" />
  <package id="sourcetree" version="3.4.1" />
  <package id="visualstudio-installer" version="2.0.1" />
  <package id="vlc" version="3.0.16" />
  <package id="winmerge" version="2.16.12" />
</packages>

จะลองแก้เองเพื่อที่จะใช้กับ user หลาย ๆ กลุ่มก็ได้ครับ กลุ่มนี้เพิ่มบรรทัดนี้ อีกกลุ่มลงอีกโปรแกรมก็แค่ copy ไปอีกไฟล์ แล้วเพิ่มลดรายชื่อโปรแกรมเอา

สร้าง USB Boot ง่ายๆ กับ ventoy

นอกจากลง windows ผ่าน usb ที่ microsoft จะทำตัวติดตั้งให้โหลดจากเว็บตัวเองแล้วลง usb ไม่ต้องใช้ cd dvd เหมือนสมัยก่อนแล้ว แต่ถ้าจะลง windows หลาย version หรือจะลง linux จะลงตัวสแกนไวรัส ปกติมันก็ใช้ flash drive ตัวละอัน รกกว่า dvd หลายอีก

หลังจากลองมาหลายตัวอย่าง Rufus, YUMI จนได้เจอกับตัวที่ถูกใจ ใช้ง่ายมากๆ คือ ventoy ที่ตอบโจทย์มากๆ คือ ลงได้หลาย os หลาย iso โดยใช้แค่ usb อันเดียว เพิ่มลด iso แค่ลบ วาง ไม่ต้องทำอะไรพิเศษ จะทำใน windows ก็ได้ windows พังก็ใช้ linux ทำก็ได้

  1. โหลดตัวติดตั้งได้จากเว็บ https://www.ventoy.net/en/download.html โดยมีให้เลือก windows / linux / live cd
  2. โหลด windows 10, xp, 7 ตัวที่ชอบ, linux, Hiren’s BootCD PE, ตัวแสกนไวรัส อะไรก็แล้วแต่ไปพลางๆ ขอแค่เป็นไฟล์ iso เป็นอันใช้ได้
  3. หา usb flash drive sd card หรือ harddisk ที่ชะตาขาดเพราะว่ามันจะต้องโดนลบข้อมูลข้างในทั้งหมด เลือกเอาที่มันจุหน่อย ตอนนี้ตัว 32GB ไม่กี่ร้อยละ จะได้ลงได้หลายๆ ตัว เสียบเข้าเครื่องรอเอาไว้
  4. แตก zip ไฟล์ออกมาทั้ง folder
  5. ดับเบิลคลิกตรง Ventoy2Disk จะเห็นโปรแกรมหน้าตาบ้านๆ ไม่มีอะไรเลยจริงๆ เพราะมันใช้ง่ายมาก
  6. เลือก device ( usb ) อันโชคร้ายของเรา ( เลือกให้ถูกนะเพราะมันจะโดนลบเกลี้ยง ) ถ้าไม่เห็นคลิกวงเขียวๆ ด้านหลัง
  7. กด Install แค่นี้ละ
  8. หลายคนคงจะงงแล้วที่โหลด windows เอาไว้ละ เปิดดูใน File Explorer จะเห็น drive ใหม่ชื่อ Ventoy เพิ่มขึ้นมาให้เอา iso ที่โหลดเอาไว้ทั้งหมด วางไว้ในนี้เป็นอันเสร็จ

ทดสอบโดยการตั้งให้เครื่องของเรา boot จาก usb อันที่ทำไว้ จะเห็นชื่อไฟล์ iso ที่เราโหลดมา เลือกตัวที่ต้องการจะใช้ติดตั้งได้เหมือน usb แยกเฉพาะตัวเลย

ความดีงามของ Ventoy คือเวลา windows ออกเวอร์ชั่นใหม่ขึ้นมา ก็แค่โหลด iso ตัวใหม่มาวางใน dirve เดิม ถ้ามันเก่าแล้วหรือพื้นที่ไม่พอแล้วก็แค่ลบอันที่ไม่ใช้ออก ไม่ต้องทำอะไรเป็นพิเศษ ไม่ต้องใช้ Ventoy มาทำอะไรด้วยซ้ำไป

Pangram แพนแกรม ไทย

ถ้าทำงาน design หรือเกี่ยวของกับงาน design อย่างการรับทำเว็บต่างๆ อาจจะคุ้นๆ กับประโยค The quick brown fox jumps over a lazy dog อยู่บ่อยๆ เวลา designer ไม่รู้ว่าจะเอาอะไรใส่ลงไปในกล่องข้อความดี หรือไม่มีเวลามานั่่งคิด มันต้องเผางานออกมาแล้ว ประโยคพวกนี้เรียกว่า “pangram” เจ้า “แพนแกรม” คือ ประโยคที่่มี ตัวพยัญชนะ สระ วรรณยุกต์ ครบพอที่จะใช้ในการดูว่าฟอนต์ต่างๆ เวลาเอาไปใช้ มันจะสวยงามแค่ไหนกันนะ

ภาษาไทยก็มีใช้เหมือนกัน ความเทพคือ ภาษาไทยนั้นมีตัวพยัญชนะ 44 ตัว สระ 21 รูป 32 เสียงวรรณยุกต์อีก 4 ตัว แค่จะคิดออกมาว่ามันมีอะไรบ้างยังยากเลย ขนาดจบบรรณารักษศาสตร์และสารนิเทศศาสตร์ (Library and information science: LIS) มานะเนี่ย พูดแล้วก็อาย จนปี 2530 สมาคมคอมพิวเตอร์แห่งประเทศไทย ในพระบรมราชูปถัมภ์ ได้คิดประโยค จริงๆ ต้องเรียกบทกลอน

เป็นมนุษย์สุดประเสริฐเลิศคุณค่า   กว่าบรรดาฝูงสัตว์เดรัจฉาน
จงฝ่าฟันพัฒนาวิชาการ   อย่าล้างผลาญฤๅเข่นฆ่าบีฑาใคร
ไม่ถือโทษโกรธแช่งซัดฮึดฮัดด่า   หัดอภัยเหมือนกีฬาอัชฌาสัย
ปฏิบัติประพฤติกฎกำหนดใจ   พูดจาให้จ๊ะๆ จ๋า น่าฟังเอยฯ

ออกมาให้ใช้กัน แต่งกันยังไงเนี่ยแก่งมากเลย เอาประโยคบ้านๆ บ้างดีกว่า
นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ

อ่านเพิ่มเติม แพนแกรม

git: private repository โดยใช้ synology server

เดี่ยวนี้ถ้าต้องการจะใช้ git repository ก็แค่สมัครสมาชิกเว็บอย่าง github แค่กรอกข้อมูลใน Join GitHub ไม่นานก็ได้พื้นที่สำหรับ backup ข้อมูลได้แล้ว ติดแค่ว่าถ้าเป็น project ภายในหรือเป็นเรื่องเกี่ยวกับธุรกิจการจะเปิดให้คนอื่นใครก็ได้เข้ามาดู source code คงจะไม่ดีแน่ ทำให้ต้องจ่ายค่าบริการเพื่ิอสร้างเป็น private repository หรืออีกทางเลือกคือ สร้าง git server ไว้ใช้เอง

ผมมีตัว nas ของ synology อยู่แล้วเลยใช้มันเป็นที่สำรองข้อมูลซะเลย จะได้ไม่ต้องสร้าง linux มาทำเป็น server อีกตัว

  1. login เข้า synology Control Panel โดยใช้ user ที่มีสิทธิ administrator
  2. ลง git package โดยวิธี Install or Buy Packages
  3. set user permission ให้ใช้ group git ได้โดยวิธี Manage Groups
  4. เปิดให้ใช้ ssh ได้โดยวิธีตาม Terminal
  5. SSH login synology nas ได้โดยวิธี How to login to DSM with root permission via SSH/Telnet
  6. สร้าง folder ไว้เก็บข้อมูล git ทั้งหมดและเซ็ทสิทธิไว้
    # Create the directory
    mkdir /volume1/git

    # folder owner and permission
    chown -R admin:administrators git
    chmod -R 772 git

  7. เตรียมการสำเร็จแล้ว เราสามารถสร้าง repository ขึ้นมาใหม่ได้โดย
    cd /volume1/git
    git init --bare --shared [my-project].git

    โดยแทนที่

    [my-project]

    โดยชื่อ git project

    ในขั้นตอนนี้ folder [my-project].git จะถูกสร้างขึ้นมาใหม่ใน /volume1/git/ และจะเห็นข้อความประมาณ Initialized empty shared Git repository in /volume1/git/snippets.git/ ก็เป็นอันเสร็จกับทางฝั่ง git server แล้ว

  8. จากนั้นก็ clone git ในเครื่อง client (ฝั่ง local) ได้โดยใช้คำสั่ง
    git clone ssh://[git-user]@[syn-ip-addr]/volume1/git/[my-project].gitโดย
    [git-user]
    user ที่เซ็ตไว้
    [syn-ip-addr]
    ip ของตัว nas synology
    [my-project]
    path และชือ repository

    เช่น
    git clone ssh://ph[email protected]/volume1/git/chromeExtensions/pittBookmarks.git

อาจจะดูยุ่งยากแต่ repository ต่อไปแค่ทำ 2 ขั้นตอนสุดท้าย ก็สามารถทำงานอย่างเป็นส่วนตัวได้แล้ว

หาเครื่องที่เปิดอยู่ในบ้าน / ที่ทำงาน

แทนที่จะไล่หาว่าเครื่องไหนมันเปิดอยู่บ้างที่ละเครื่องสามารถใช้ command ping เครือข่ายทั้งยวงได้โดยใช้คำสั่ง

FOR /L %i IN (1,1,254) DO ping -n 1 192.168.1.%i | FIND /i "Reply">>c:\ipaddresses.txt

ผลที่ได้จะถูกเขียนลงในไฟล์ c:\ipaddresses.txt

...
Reply from 192.168.1.1: Destination host unreachable.
Reply from 192.168.1.1: Destination host unreachable.
Reply from 192.168.1.1: Destination host unreachable.
...
Reply from 192.168.1.61: bytes=32 time=2ms TTL=64
Reply from 192.168.1.62: bytes=32 time=5ms TTL=64
Reply from 192.168.1.63: bytes=32 time<1ms TTL=128
Reply from 192.168.1.64: bytes=32 time<1ms TTL=128
...
Reply from 192.168.1.1: Destination host unreachable.
...

อธิบายคือไล่ ping เครื่องตั้งแต่ ip 192.168.1.1 ถึง 192.168.1.254 ถ้าเครื่องไหนตอบกลับมา (เปิดอยู่) แล้วเขียนไว้ในไฟล์ c:\ipaddresses.txt ถ้าเปิดดูก็จะเห็นตัวหนังสือประมาณ bytes=32 time=2ms TTL=64 ส่วนที่หาไม่เจอ ไม่ตอบกลับมา ก็จะได้ข้อความซ้ำๆ มาจาก router อย่าง Reply from 192.168.1.1: Destination host unreachable.

ดีกว่าไล่ดูทีละเครื่องเยอะเลย
Cr: Ping all addresses in network, windows

ทำ checkbox / radio สวยๆ

สิ่งที่ css framework อย่าง bootstrapt ไม่ยอมทำซักทีคือ ทำให้ checkbox หรือ radio ออกมาเหมือนๆกันทุก browser ทำให้การออกแบบฟอร์มทำได้ไม่สวยงามเท่าที่ควร

แก้ได้โดยใช้ fronteed/icheck มาวางภาพทับ checkbox หรือ radio ไว้ และทำการจับ event แทนตัว input จริงๆ

ตัวอย่าง

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>jQuery iCheck</title>
<link href="vendor/twbs/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="vendor/fronteed/icheck/skins/square/green.css" rel="stylesheet" type="text/css">
</head>
<body>
<?php
if(count($_POST)) {
   echo '<pre>', print_r($_POST, true), '</pre>';
}
?>
<div class="container">
  <form action="jQuery.icheck.php" id="formA" method="post">
    <fieldset class="form-group row">
      <legend class="col-form-legend col-sm-2">Checkbox</legend>
      <div class="col-sm-10">
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" checked id="chk1" name="checkbox1" type="checkbox" value="checkbox1">
            Check me out </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="chk2" name="checkbox2" type="checkbox" value="checkbox2">
            Check me </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="chk3" name="checkbox3" type="checkbox" value="checkbox3" disabled>
            Check is disabled </label>
        </div>
      </div>
    </fieldset>
    <fieldset class="form-group row">
      <legend class="col-form-legend col-sm-2">Radios</legend>
      <div class="col-sm-10">
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" checked id="gridRadios1" name="radio" type="radio" value="option1">
            Check me out </label>
        </div>
        <div class="form-check">
          <label class="form-check-label">
            <input class="form-check-input" id="gridRadios2" name="radio" type="radio" value="option2">
            Check me </label>
        </div>
        <div class="form-check disabled">
          <label class="form-check-label">
            <input class="form-check-input" disabled id="gridRadios3" name="radio" type="radio" value="option3">
            Check is disabled </label>
        </div>
      </div>
    </fieldset>
    <div class="form-group row">
      <label class="col-sm-2"></label>
      <div class="col-sm-10 text-right">
        <button class="btn btn-lg btn-primary" type="submit">Save</button>
      </div>
    </div>
  </form>
  <hr>
  <button class="btn btn-lg btn-info" id="ajaxBtn" type="button">AJAX Value</button>
</div>
<script src="vendor/components/jquery/jquery.min.js"></script>
<script src="vendor/fronteed/icheck/icheck.min.js"></script>
<script>
$(function () {

  /* style */
  $('input').iCheck({
     "checkboxClass": "icheckbox_square-green",
     "radioClass": "iradio_square-green",
  });

  /* event */
  $('input').on('ifChanged', function(event) {
    console.log(event);

    alert('checked = ' + event.target.checked);
    alert('id = ' + event.target.id);
    alert('name = ' + event.target.name);
    alert('type = ' + event.target.type);
    alert('value = ' + event.target.value);
  });

  /* value */
  $('#ajaxBtn').click(function() {
     var formData = $('#formA').serializeArray();
     var message = '';

     $.each(formData, function (index, item) {
  	  message +='\n' +  index + ' ' +  item.name + ' = '+item.value;
     });

     alert(message);

  });

});
</script>
</body>
</html>

สามารถเปลี่ยนรูปแบบอื่นได้โดยดู style ได้จาก iCheck v1.0.1 @FRONTEED จากนั้นเปลี่ยน css ไฟล์ และ checkboxClass หรือ radioClass ไม่ก็ทำภาพพื้นหลังใหม่และเขียน css ของตัวเองก็ได้

ลง windows / linux ผ่าน usb

notebook สมัยนี้หลายๆเครื่องไม่มี drive dvd / cd ติดมาแล้ว ขณะเดียวกัน flash drive มันถูกมากแค่อันละ 200 ก็พอที่จะใช้ลง windows xp, windows 7, windws 8, windows 10, linux แถม linux อีกตัวก็ยังได้เลย

เพิ่ม os / boot cd ได้โดย

  1. เตรียมไฟล์ iso ของ os ที่ต้องการจะติดตั้ง ถ้ายังไม่มีก็ download มาจาก
    windows 10
    ดาวน์โหลด Windows 10
    kali linux
    Kali Linux Downloads
    Linux Mint
    Download Linux Mint 18 Sarah
    Hiren’s BootCD
    Hiren’s BootCD 15.2
    MiniTool® Partition Wizard 9
    MiniTool Partition Wizard Free Edition
  2. ระหว่างรอ download ไป download MultiBootUSB จาก http://multibootusb.org/ หรือ mbusb/multibootusb
  3. เปิดโปรแกรม MultiBootUSB ขึ้นมา
  4. Step 1 เลือก drive จากด้านขวามือ
  5. Step 2 Browse ISO เลือกไฟล์ Browser ที่ต้องการ
  6. Step 3 คลิก Create
  7. ถ้ามี alert ประมาณ Sorry. xxx is not supported at the moment Please email this issue to [email protected]
  8. จะมี folder ถูกสร้างขึ้นมาใน flash drive เช่น F:\multibootusb\kali-linux-2016.2-amd64F:\multibootusb\kali-linux-2016.2-amd64

ถ้าต้องการเพิ่มตัวติดตั้งหรือลบออกไปก็สามารถนำ flash drive มาเสียบกับคอมพิวเตอร์เครื่องไหนก็ได้ ไม่ต้องเป็นเครื่องเดิมในครั้งแรก จะเห็นรายชื่อ ด้านซ้ายมือ สามารถเลือกและคลิก Uninstall Distro เพื่อลบออกไป หรือถ้าต้องการเพิ่มเข้าไปใหม่ ก็ download มาแลัวเริ่ม Step 1 อีกครั้ง

แก้ / เพิ่ม windows environment variables registry

ปกติจะสามารถแก้ environment variables ได้โดยวิธี How to set the path and environment variables in Windows แต่เพราะว่าเครื่องที่ใช้โดนกำหนดไม่ให้แก้ environment variables ไว้โดย ad จะขอให้ทาง infa แก้ให้ก็ไม่ทัน งานจะต้องส่งภายในวันนี้แต่ทาง admin คนที่เซ็ต ad ได้ดันลา ลองคลิกดูหลายๆจุดก็โดน lock ไว้ โชคดีที่ลองใช้ regedit ดู ก็เห็นว่ามันไม่ได้ lock ไว้ (รั่วนะเนี่ย)

เพราะงั่นเลยแก้มันตรงๆ ใน registry เลยละกัน โดย environment variables จะมี 2 จุดคือ

  • User Variables อยู่ที่ HKEY_CURRENT_USER\Environment
  • System Variables จะอยู่ที่ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

ตั้งตัวแปรใหม่ โดย new > string value หรือจะแก้ของเดิมที่มีโดยใช้ ; คั่นก็ได้

เสร็จแล้วให้ restart windows หรือแค่ restart windows explorer ก็ได้ เท่านี้ก็จะ set environment variables ได้แล้ว

อ่านเพิ่มเติม

แก้เน็ตค้างกับเราเตอร์ 3 เสา

เพราะว่าที่บ้านใช้เน็ตแบบ 24/7 จริงๆ ถึงจะอยู่แค่คนเดียว มีแค่ nas กับมือถือที่ต่อเน็ตอยู่ตลอดเวลา กับ tv ที่ไว้ดูหนังออนไลน์เวลาพัก แต่เราเตอร์ได้มาจากทรูมันค้างตลอดศก วัน สองวันต้องมากด restart มันทีหนึ่ง งานไม่ได้หนักแต่มันเสียอารมณ์มากเลย ยิ่งถ้ากำลังดูหนังจาก youtube ในทีวีอยู่ เคยไปขอตัวใหม่มาใช้ ไม่นานก็เป็นอีก

เดินๆ งานคอมอยู่เห็นขายเยอะเลย หลายรุ่น ตัวเจ็บๆ ก็เยอะ asus ก็น่าสนหลายตัวแต่แพง ซื้อไม่ลง เดินดูเรื่อยๆ เห็น D-link dir809 Wireless AC750 Dual Band Router แปะอยู่ตัวโตๆ 900 เอง แถมดูโหงวเฮ้งมี 3 เสา ไกล้ๆ เขียน dual band 2.4 GHz. กับ 5 GHz. ไม่ใช่ repeater ความโลภเข้ามาทันที ถามดูประกันตลอดอายุ ก็จัดซิครับ

พอมาถึงบ้านจักการ config เข้าไปที่ http://192.168.0.1 user admin pass ไม่ต้องใส่ เข้าไปแก้ ตามที่ router ตัวเก่าก็แล้ว ใช้ไม่ได้ โทรถามทรูขอ pass ใหม่ ก็ใช้ไม่ได้ โทรไปโทรมา เค้าเช็คจากชื่อรุ่นว่ามันไม่มี modem adsl ในตัว T-T พลาดละ มิน่าถึงถูกตัวอื่น 3000 ถึงหมื่นต้นๆทั้งนั้น

โดยสรุปคือ ต้องใช้ router ตัวเดิมต่อเน็ต แล้วต่อสายแลนเข้าตัวนี้จ่ายเน็ตแทน อนาถยิ่งนัก

  1. ต่อสานแลนจาก router เดิมที่ใช้ออกเน็ต
  2. config โดนเปิดเน็ตเข้าไปที่ http://192.168.0.1 user กรอกadmin pass ไม่ต้องใส่
  3. กด easy setup ใส่ ชื่อ wifi ใหม่ในช่อง Wireless Network Name (SSID) และใส่ password wifi ในช่อง Wireless Password ทั้งสองตัวแต่ Wireless Network Name (SSID) ต้องใช้คนละชื่อกัน
  4. เปลี่ยน password ตัวเร้าเตอร์ใหม่ กันมือเลวมาขโมยเล่น ใน tools ใต้ ADMINISTRATOR ใส่ password เข้าไปใหม่
  5. เข้าไปปิด การจ่าย wifi ของเราเตอร์ตัวเดิม งานมันจะได้ไม่หนัก ไม่น้อยใจฆ่าตัวตายบ่อยๆ
  6. จากที่ใช้มาเดือนกว่าๆ สัญญานนิ่งมาก ไกล ไม่ค้างเลย เพิ่งมาค้างตอนมีคนมาช่วยใช้อีก 3 คนแต่สั่ง restart ครั้งเดียวก็ไม่เป็นอีก จากราคาที่จ่ายไปก็ถือว่าคุ้มอยู่

บั๊คที่แท้มันคืออะไรตับไตใส้พุง

มี user ถามมาว่า bug คืออะไร ทำไม่มี bug ก็เลยลองเขียนตัวอย่างให้ดู ยกตัวอย่างบัคที่เกิดจาการกรอกข้อมูลผิดไปจากที่ระบบออกแบบและคาดหวังไว้ ก็มีคำถามกลับมาประมาณว่าทำไม่ไม่ตรวจให้หมดละ เลยลองทำตัวอย่างออกมา

<?php

$strings = [
    '!@#$%^&*()_-+="{}[]\+:<>,./?',
    'Apple Inc.',
    'email.gmail.com',
    'email.job.co.th',
    '[email protected]',
    '[email protected]',
    'https://pitt.plusmagi.com/about/',
    'https://pitt.plusmagi.com/เชื่อมต่อ-php-กับ-sql-server-sqlsrv/',
    'james bond 007',
    'johnny english พยัคฆ์ร้าย 00ก๊าก',
    'pitt@小米科技.cn',
    'sale 20%',
    'Xiaomi Inc. (小米科技)',
    'Xiaomi Inc.',
    'พิชญ์ พันธุ์สนิท pitt phunsanit',
    'พิชญ์ พันธุ์สนิท',
    'พิชญ์@gmail.com',
    'หนึ่งในพระราชดำริ ช่อง 9',
    'หนึ่งในพระราชดำริ ช่อง ๙',
    'ไทย นี่มันไทยจริงๆ',
];

function validateAlphanumeric($string)
{
    if (preg_match('/[^A-Za-z0-9]/', $string)) {
        return true;
    } else {
        return false;
    }
}

function validateAlphanumericEnglish($string)
{
    if (preg_match('/^[a-zA-Z0-9\s]+$/', $string)) {
        return true;
    } else {
        return false;
    }
}

function validateAlphanumericThai($string)
{
    if (preg_match('/[^A-Za-z0-9-ก-๙]/', $string)) {
        return true;
    } else {
        return false;
    }
}

function validateAlphanumericThaiOnly($string)
{
    /* อักษรภาษาไทย และ space */
    if (preg_match('/^[ก-ฮ\s]+$/', $string)) {
        return true;
    } else {
        return false;
    }
}

function validateEmail($string)
{
    if (filter_var($string, FILTER_VALIDATE_EMAIL)) {
        return true;
    } else {
        return false;
    }
}

function validateFilterURL($string)
{
    if (filter_var($string, FILTER_VALIDATE_URL)) {
        return true;
    } else {
        return false;
    }
}

function validatePregURL($string)
{
    if (preg_match('/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $string)) {
        return true;
    } else {
        return false;
    }
}

echo '<!doctype html>
<html>
   <head>
      <meta charset="utf-8">
      <title>PHP String Validation By Ptii Phunsanit</title>
      <meta name="author" content="Pitt Phunsanit">
      <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css">
   </head>
   <body>
      <table class="table table-striped">
      <caption>
         PHP String Validation
      </caption>
      <thead>
         <tr>
            <th>Test</th>
            <th>String</th>
            <th colspan="4">Alphabet</th>
            <th>Email</th>
            <th colspan="2">URL</th>
         </tr>
         <tr>
            <th></th>
            <th></th>
            <th>Alphanumeric</th>
            <th>Alphanumeric English</th>
            <th>Alphanumeric Thai</th>
            <th>Alphanumeric Thai Only</th>
            <th>Email</th>
            <th>Filter URL</th>
            <th>Preg URL</th>
         </tr>
      </thead>
      <tbody>';
foreach ($strings as $no => $string) {
    echo '<tr>',
    '<th>', ($no + 1), '</th>',
    '<th>', $string, '</th>',
    '<td>', (int) validateAlphanumeric($string), '</td>',
    '<td>', (int) validateAlphanumericEnglish($string), '</td>',
    '<td>', (int) validateAlphanumericThai($string), '</td>',
    '<td>', (int) validateAlphanumericThaiOnly($string), '</td>',
    '<td>', (int) validateEmail($string), '</td>',
    '<td>', (int) validateFilterURL($string), '</td>',
    '<td>', (int) validatePregURL($string), '</td>',
        '</tr>';
}
echo '</tbody></table></body></html>';

ผลที่ได้ ดูเต็มๆ เว็บนี้ยังมี bug เลย แต่ไม่คุ้มที่จะแก้
1 คือผ่านการทดสอบ 0 คือ ไม่ผ่านการทดสอบ

PHP String Validation
Test String Alphabet Email URL
Alphanumeric Alphanumeric English Alphanumeric Thai Alphanumeric Thai Only Email Filter URL Preg URL
1 !@#$%^&*()_-+=”{}[]\+:<>,./? 1 0 1 0 0 0 0
2 Apple Inc. 1 0 1 0 0 0 0
3 email.gmail.com 1 0 1 0 0 0 0
4 email.job.co.th 1 0 1 0 0 0 0
5 [email protected] 1 0 1 0 1 0 0
6 [email protected] 1 0 1 0 1 0 0
7 https://pitt.plusmagi.com/about/ 1 0 1 0 0 1 1
8 https://pitt.plusmagi.com/เชื่อมต่อ-php-กับ-sql-server-sqlsrv/ 1 0 1 0 0 0 1
9 james bond 007 1 1 1 0 0 0 0
10 johnny english พยัคฆ์ร้าย 00ก๊าก 1 0 1 0 0 0 0
11 pitt@小米科技.cn 1 0 1 0 0 0 0
12 sale 20% 1 0 1 0 0 0 0
13 Xiaomi Inc. (小米科技) 1 0 1 0 0 0 0
14 Xiaomi Inc. 1 0 1 0 0 0 0
15 พิชญ์ พันธุ์สนิท pitt phunsanit 1 0 1 0 0 0 0
16 พิชญ์ พันธุ์สนิท 1 0 1 1 0 0 0
17 พิชญ์@gmail.com 1 0 1 0 0 0 0
18 หนึ่งในพระราชดำริ ช่อง 9 1 0 1 0 0 0 0
19 หนึ่งในพระราชดำริ ช่อง ๙ 1 0 1 1 0 0 0
20 ไทย นี่มันไทยจริงๆ 1 0 1 1 0 0 0

เริ่มจากชุดแรก Alphanumeric ใช้ preg_match(‘/[^A-Za-z0-9]/’, $string เหมือนจะดูดี ตามคู่มือคือเทียบโดยตัวอักษร a ถึง z และตัวเลข 0 ถึง 9 แต่ขอโทษชุดสตริงค์ แปลกๆ ?!@#$%^&*()_-+=”{}[]\+:<>,./ มันยังผ่าน จนด้วยคำพูดจริงๆ ใส่อะไรก็ผ่าน

ชุดที่ 2 Alphanumeric English ใช้ preg_match(‘/^[a-zA-Z0-9\s]+$/’, $string) ผลคือ ที่มีอักษรไทยอยู่ตกหมด และ james bond 007 ผ่าน แต่ Apple Inc. กับตัวอื่นๆ ตกไปง่ายๆแค่ใส่ . สรุปถ้าเขียนเป็นประโยคมาก็จบชีวิต

ชุดที่ 3 Alphanumeric Thai ใช้ preg_match(‘/[^A-Za-z0-9-ก-๙]/’, $string) รั่วทุกตัวอักษรอีกชุก ถึงจะใส่ ก-๙ มาอักษรจีนก็ยังรอดอยู่ดี

ชุดที่ 4 Alphanumeric Thai Only ใช้ preg_match(‘/^[ก-ฮ\s]+$/’, $string) มันไทยมากจริง อย่าได้ใส่เลขอารบิกมาเชียว บางคนก็ไม่รู้นะครับว่าเลขไทยนะมันพิมพ์ยังไง

ชุดที่ 5 Email ใช้ filter_var($string, FILTER_VALIDATE_EMAIL) ตรวจว่าเป็นอีเมล์จริงๆ รึเปล่า ผ่าน email.gmail.com และ พิชญ์@gmail.com ก็หลอกมันไม่ได้

ชุดที่ 6 ติดใจคำสั่ง filter_var ในข้อที่แล้วใช้ filter_var($string, FILTER_VALIDATE_URL) ผลคือ เกือบจะดีแล้ว ตรวจ url ได้จริงๆ ยกเว้น https://pitt.plusmagi.com/เชื่อมต่อ-php-กับ-sql-server-sqlsrv/ link ของบล๊อคของผมเองยังไม่ผ่าน ปวดตับ แม้แต่ function สำเร็จรูปก็ไม่ได้ดีเสมอตามที่คิดว่า “ใช้กันมากเป็นมาตราฐานมันต้องดีกว่าเขียนเองซิ” function filter_var ของ PHP มันออกมาตั้งแต่ 2 November 2006 ก็แค่ไม่กี่ปีเองมั๊ง ปีนี้ ค.ศ. อะไรแล้ว แต่มันก็ยังไม่รับภาษาอื่นนอกจากภาษาอังกฤษอยู่เหมือนเดิม ไม่ใช่ไม่มีคนแจ้งไปที่คนเขียนภาษา php นะ ตามนี้ แต่พี่แกก็ยังไม่แก้แค่นั้นเอง

ชุดที่ 7 ใช้ preg_match(‘/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i’, $string) ยาวยืดอย่าพิมพ์ผิดเชียว ผมก็ก๊อบเค้ามา แต่ตรวจ url ได้ถูกต้อง

ที่ทำตัวอย่างให้ดูสรุปคือ ในการเขียนโปรแกรมไม่มีอะไรที่ทำงานได้ดี 100% เต็ม ทำอย่างหนึ่งจะมีการแลกเปลี่ยนที่เท่าเทียม (รึเปล่า) ตามมาด้วยเสมอ อย่างตรวจ link แบบชุดที่ 6 จริงๆ มันตรวจว่าเป็นลิงค์เว็บจริงๆ มาได้หลายปีแล้ว แต่เว็บหลังๆ เน้นทำ SEO กับท้องถิ่นตามภาษาและประเทศมากขึ้นแทนที่จะใช้ภาษาอังกฤษอย่างเดียว ตอนนี้เลยต้องมาเขียนตัวตรวจสอบกันแบบยาวๆ และปวดตับมากกกก

การที่กว่าจะได้งานที่สมบูรณ์ที่สุดไกล้ความสมบูรณ์แบบถึงต้องใช้พลังและความร่วมมือจากทุกๆคน และมีค่าใช้จ่ายและเวลาที่สูงมาก ผลคือ การลดค่าใช้จ่ายอย่าง

  • บอกมานิดเดียว น้องไปคิดต่อเอาเองนะ พี่มางานอื่น (พี่ครับ ผมต้องเขียน business plan ต้องมาคิดให้ว่าบริษัทพี่นี่ มันขายอะไร ต้องทำยัง บริการอะไรบ้าง และมันทำงานยังไง สุดท้ายก็ออกมาขาดๆ เกินๆ)
  • ไม่จ้าง tester ครับ programmer เขียนเสร็จก็ต้องมาลองเอง เพราะว่าออกแบบและเขียนเองมากะมือ มันเลยจำติดอยู่ในสมองว่า ตรงนี้ต้องกรอกอะไร ตอนทดสอบ ก็เผลอทำแบบเดิม ทำมาให้กรอกตัวเลข ต้อนทดสอบก็ใส่ 1555, 5544, 444, 85 มัวๆไป ตอนให้ user ทำลองใช้ มีคนใส่โง่ๆ “100 บาท” เกิดอะไรขึ้น
    1. โปรแกรมก็เอา 100 บาท ไปใส่ในสูตร
      จำนวนบาท คูณจำนวน ก็ออกมาเป็น
      100บาท x 5 = ?
      แล้วก็บอกกลับมาว่า พ่องมึง คูณได้เหรอวะ แต่มันบอกมาแบบที่มีแต่โปรแกรมเมอร์ที่เข้าใจ แลัวฆ่าตัวตายไปต่อหน้าต่อตา
    2. บัญชีก็บอกว่า นี่ทำเสร็จแล้วเหรอ เทสแล้วแน่นะ
    3. คนเขียนเห็นก็อยากจะบอกว่า ข้างหลังใส่ label บาทให้ละ จะกรอกไปทำซากอะไร
    4. ทีนี้เกินอะไรขึ้นต่อไปในการประชุม
      • project manager ก็บอกว่านิดหนึ่งพี่ แก้ไม่ถึง 5 นาทีก็เสร็จแล้วครับ
      • programmer คิด มึงเคยถามกูยัง ทำไงต่อ ทำนานปะ แก้แล้วตรงไหนจะพังมั่ย แล้วอย่างอื่นมันจะทันป่าว
      • บัญชีของลูกค้าก็คิด ขี้เกียจเทสแน่ๆ เมื่อไหร่จะได้ใช้
      • เซลล์ก็คิด ทำไม่ไม่เอาใบส่งสินค้าที่เขียนกับมือ เข้าเครื่องถ่ายเอกสาร แล้วได้รายงานออกมาเลย ไม่เสียเวลา เอาไปขายให้ที่ไหนมีแต่คนอยากซื้อ ทำไม่ไม่ยอมทำ จะได้ขายง่ายๆ ซักที % จะได้เยอะๆ อุสาห์คิดให้ดีๆ ไม่เข้าใจ
      • ลูกค้า ก็คิด รู้งี้ยอมจ่ายอีกนิดจ้างอีกเจ้า ยอมไม่ไปเที่ยวเมืองนอกก็ได้ จะได้ทำอย่างอื่นซะที
    5. จ้างมาแพง ต้องรีบๆทำงาน ให้ได้ function ผลคือไม่ได้ test งานจริงๆ หรือให้มันใช้งานได้ง่าย อย่างงานที่เคยเจอต้องมีคนมา เอารูปถ่ายสินค้ามาตัดให้พอดีกับขนาดที่ใช้ในเว็บ ทั้งๆที่ ก็ถ่ายโดยกล้องเดิม ขนาดเดิม และมุมกล้องเดิมทุกวัน ทุกชิ้น ถ้ายอมให้เวลาเขียนโปรแกรมเพิ่มอีกนิด ก็แค่วางของที่เดิม กดถ่ายรูปแล้วโยนให้โปรแกรมมันตัดรูป เปลี่ยนขนาด แล้วเอาให้ลูกค้าดูเอง ประหยัดเวลาในชีวิตออกไปได้เยอะเลยแท้ๆ แต่พี่รีบ พี่ไม่อยากจ่ายเงินเพิ่ม

มันก็เหมือนคำพูดที่ว่า ของดีไม่แพง นั้นละครับ ยอมจ่ายได้แค่ไหน คนขายก็ประมาณ ต่อกันอย่างนี้ ขอฟรีเลยมั๋ยพี่ ที่สำคัญคือ จะหาจุดสมดุลย์ได้ที่ไหน ถึงจะพอใจกันทั้งสองฝ่าย