Menu

Showing posts with label PHP. Show all posts
Showing posts with label PHP. Show all posts

Monday, August 16, 2021

[PHP - Laravel] วิธีการสร้าง Class Diagram ที่มี Caller Graph จาก Source Code ที่เป็น Laravel
[PHP - Laravel] How to Generate Class Diagram with Caller Graph from Laravel Source Code

เราจะใช้ Doxygen ร่วมกับ Graphviz ในการสร้าง Class diagram ที่มี Caller Graph 

Doxygen เป็นเครื่องมือที่ใช้สร้างเอกสารจาก source code ที่มีอยู่ ภาษาโปรแกรมที่ support เช่น PHP, Java, Python เป็นต้น

Graphviz เป็น open source software ที่ใช้สร้างและแสดงผลกราฟรูปแบบต่างๆ

Doxygen จะเรียกใช้ dot ของ Graphviz สำหรับสร้างเอกสารในส่วนของ caller graph

การติดตั้ง Doxygen และ Graphviz

  1. ดาวน์โหลด Doxygen จาก https://www.doxygen.nl/download.html และติดตั้งตามปกติ
  2. ดาวน์โหลด Graphviz จาก https://graphviz.org/download/ และติดตั้งตามปกติ
  3. เพิ่ม C:\Program Files\Graphviz\bin เข้าไปที่ System path

Monday, June 14, 2021

[Laravel - Composer] วิธีการตั้งค่า Authentication token ของ Github ใน Composer
[Laravel - Composer] How to Set Github Authentication Token in Composer

หลังจากรัน composer install เพื่อติดตั้ง package ที่จำเป็นต้องใช้งาน แล้วได้ข้อความตามข้างล่างนี้

Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+MACHINE-NAME+2021-02-17+0532
to retrieve a token. It will be stored in "C:/Users/puthipong/AppData/Roaming/Composer/auth.json" for future use by Composer.
Token (hidden): GitHub API limit (0 calls/hr) is exhausted, could not fetch https://api.github.com/repos/test/l5-repository/contents/composer.json?ref=ce164fa72b884b4af488ff2749a171346f229c66. Create a GitHub OAuth token to go over the API rate limit. You can also wait until ? for the rate limit to reset.

สิ่งที่เราต้องทำมีดังนี้
  1. เข้าไปที่ URL ตามข้อความข้างต้น
    https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+MACHINE-NAME+2021-02-17+0532
  2. กดสร้าง token 
  3. รันคำสั่งข้างล่างนี้
    composer config --global github-oauth.github.com <token>
หมายเหตุ สำหรับข้อมูลเพิ่มเติม อ่านได้ที่ https://getcomposer.org/doc/articles/authentication-for-private-packages.md#github-oauth

Wednesday, February 17, 2021

[Laravel - Composer] วิธีการใช้ Custom Package พร้อมกับการกำหนด Version ของ Package นั้นในไฟล์ composer.json
[Laravel - Package] How to Use Your Custom Package with Package Version in Composer File

ไฟล์ composer.json เป็นแหล่งรวมรายการ package ที่ต้องใช้ใน Laravel project

บางครั้งเราอาจจะต้อง fork package บางตัวมาจาก repository อื่น เพื่อนำมาปรับใช้กับ project ของเรา

หลังจากที่เราปรับแก้ package แล้ว เรามีวิธีตั้งค่าไฟล์ composer เพื่อเรียกใช้ package จาก branch บน repository ของเราดังนี้
  1. เพิ่มชื่อ package ของเราในส่วน require หรือ require-dev ดังนี้
    "require": {
        ...
        "{package_name}": "dev-{branch_name}",
        ...
    }
    เช่น
    "require": {
        ...
        "monolog/monolog": "dev-fix-concurrent-mkdir",
        ...
    }
  2. เพิ่ม repository ของเราในส่วน repositories ดังนี้
    "repositories": {
        ...
        {
          "type": "vcs",
          "url": "{my_repository_url}"
        },
        ...
    }
    เช่น
    "repositories": {
        ...
        {
          "type": "vcs",
          "url": "https://github.com/my_repo/monolog.git"
        },
        ...
    }

Monday, January 25, 2021

[PHP - Composer] วิธีการรัน Composer แบบไม่จำกัดหน่วยความจำและไม่ต้องแก้ไขไฟล์ php.ini
[PHP - Composer] How to Run Composer with Unlimited Memory and Do Not Update PHP INI File

เมื่อเรารัน composer install หรือ composer require เราอาจจะเจอกับ error ข้างล่างนี้ ทำให้เราไม่สามารถติดตั้ง package ที่เราต้องการได้

Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

อีกทั้งการแก้ไขขนาด memory ในไฟล์ php.ini ก็ดูเกินความจำเป็นไป

วิธีการรัน composer โดยไม่จำกัดขนาด memory สามารถรันได้ด้วยคำสั่งดังนี้

COMPOSER_MEMORY_LIMIT=-1 composer require {package_name}

สำหรับข้อมูลเพิ่มเติม อ่านได้ที่ Memory limit errors

Monday, April 20, 2020

[PHP - Laravel] วิธีการตรวจสอบว่า Private key ที่ผู้ใช้งานใส่เข้ามาตรงกับ Public key ที่ตั้งค่าไว้หรือไม่
[PHP - Laravel] How to Verify Private Key with Existing Public Key

สืบเนื่องจากโพสต์ [Laravel - Model] การเข้ารหัสและถอดรหัสค่าของฟิลด์ใน Laravel Model โดยใช้ SSH Keys ที่ใช้ SSH keys ในการเข้ารหัสข้อมูล โดยที่เราตั้งค่า public key ไว้ในไฟล์ .env แต่เราให้ผู้ใช้งานเป็นผู้กรอก private key เอง แล้วเราจะรู้ได้อย่างไรว่า private key ที่ถูกกรอกเข้ามานั้น เป็นคู่ของ public key ที่เราตั้งค่าไว้จริงๆ

เรามีวิธีตรวจสอบ 2 วิธีดังนี้
  • การตรวจสอบด้วยการ sign และ verify signature
  • การตรวจสอบด้วยการ encrypt และ decrypt ข้อความ

การตรวจสอบด้วยการ sign และ verify signature

ขั้นตอนการตรวจสอบเป็นดังนี้
  1. เลือกข้อความมา 1 ข้อความ ข้อความอะไรก็ได้
  2. sign ข้อความนั้นด้วย private key ที่ผู้ใช้กรอกเข้ามา เพื่อสร้าง signature
  3. verify ข้อความนั้นกับ signature ที่เพิ่ง sign ด้วย public key ในระบบ
  4. ถ้า verify ไม่ผ่านจะเกิด exception ดังนี้

Wednesday, April 8, 2020

[Laravel] ขั้นตอนการตั้งค่า XAMPP สำหรับรันโปรเจค Laravel
[Laravel] How to Set XAMPP to Run Laravel Project

สมมติว่า 
  • เรามี folder ชื่อ laravel ที่เป็น folder ของ project ที่เป็น Laravel
  • เราติดตั้ง XAMPP ไว้ที่ C:\xampp
  • เราต้องการเรียกหน้าเว็บของเราผ่าน domain ชื่อ laravel.dev
เราจะมีขั้นตอนดังต่อไปนี้

Wednesday, April 1, 2020

[PHP - Laravel] Closure คืออะไร
[PHP - Laravel] What is Closure?

Closure เป็น anonymous function ที่นิยมใช้เป็น callback method อีกทั้งยังสามารถใช้เป็น parameter ของ function ได้อีกด้วย

ตัวอย่างการใช้งาน

สมมติว่า เรามี function ชื่อ handle โดยที่ function นี้รับ parameter เป็น Closure ดังต่อไปนี้
function handle(Closure $closure) {
    $closure();
}
เวลาเราเรียกใช้งาน handle เราสามารถใส่ function ของเราเข้าไปเป็น parameter แบบนี้ได้เลย
handle(function(){
    echo __METHOD__;
});
นอกจากนั้น เราสามารถประกาศ function ของเราเก็บไว้ในตัวแปรก่อน แล้วค่อยส่งตัวแปรนั้นเป็น parameter แบบนี้ก็ได้
$myFunction = function(){
    echo __METHOD__;
});
handle($myFunction);

Thursday, March 19, 2020

[PHP - Laravel] Trait คืออะไร?
[PHP - Laravel] What is Trait?

ปัญหานึงของการเขียนโปรแกรมด้วยภาษา PHP คือ class 1 class สามารถ inherit จาก class อื่นได้เพียง class เดียวเท่านั้น (single inheritance) ทำให้ไม่สามารถ inherit method ที่ต้องการใช้จาก class อื่นๆ เพื่อลดความซ้ำซ้อนของโค้ดได้

Traits เป็นกลไกสำหรับการใช้ code ซ้ำในภาษาที่เป็น single inheritance เช่น PHP

Traits มีความคล้ายคลึงกับ class ต่างกันที่ Traits เป็นเพียงกลุ่มของ method เท่านั้น จึงไม่สามารถเรียกใช้งานแบบ instance ได้ นอกจากนั้น มันยังมีความสามารถเพิ่มเติม คือ การเรียกใช้ class member ของ class ที่เรียกใช้มันได้ โดยไม่ต้อง inherit อีกด้วย

Tuesday, February 25, 2020

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

สืบเนื่องจากโพสต์ [Laravel - Model] การเข้ารหัสและถอดรหัสค่าของฟิลด์ใน Laravel Model ที่เราเข้ารหัสข้อมูลก่อนเก็บลงฐานข้อมูล โดยใช้การเข้ารหัสและถอดรหัสของ Laravel ซึ่งใช้ APP_KEY ใน .env เป็น key ทำให้คนที่เข้าถึง application สามารถถอดรหัสข้อมูลได้

เพื่อเพิ่มความปลอดภัยขึ้นไปอีกขั้น เราจะเปลี่ยนจากการใช้ APP_KEY ใน .env เป็น SSH Keys ซึ่งแยกเป็น Public key และ Private key แทน โดยเราจะได้เพียง Public key มาใช้ในการเข้ารหัส แต่คนมีสิทธิ์ดูข้อมูลเท่านั้นที่จะมี Private key เพื่อใช้ถอดรหัสข้อมูล

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 ที่เราต้องการเข้ารหัสเท่านั้น

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
    

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;
}

Thursday, October 3, 2019

[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 โดยอัตโนมัติ

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

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 เป็นต้น

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