คำอธิบาย

การรับวัตถุการร้องขอ

Webman จะทำการแทรกวัตถุการร้องขอโดยอัตโนมัติไปในพารามิเตอร์แรกของเมธอด action เช่น

ตัวอย่าง

<?php
namespace app\controller;

use support\Request;

class UserController
{
    public function hello(Request $request)
    {
        $default_name = 'webman';
        // รับค่า parameter name จากการร้องขอแบบ get ถ้าไม่มีการส่งค่า parameter name จะคืนค่า $default_name
        $name = $request->get('name', $default_name);
        // ส่งคืนสตริงไปยังเบราว์เซอร์
        return response('hello ' . $name);
    }
}

ด้วยวัตถุ $request เราสามารถเข้าถึงข้อมูลที่เกี่ยวข้องกับการร้องขอได้ทุกประเภท

บางครั้งเราต้องการเข้าถึงวัตถุ $request ของการร้องขณะอยู่ในคลาสอื่น เราสามารถใช้ฟังก์ชันช่วย request() ได้เลย

การรับค่าพารามิเตอร์ get

รับค่าทั้งหมดในอาร์เรย์ get

$request->get();

ถ้าการร้องขอไม่มีพารามิเตอร์ get จะคืนค่าเป็นอาร์เรย์ว่างเปล่า

รับค่าหนึ่งค่าจากอาร์เรย์ get

$request->get('name');

ถ้าอาร์เรย์ get ไม่มีค่านั้นจะคืนค่าเป็น null

คุณยังสามารถส่งค่าค่าดีฟในพารามิเตอร์ที่สองของฟังก์ชัน get หากไม่พบค่าที่ตรงกันในอาร์เรย์ get จะคืนค่าเป็นค่าดีฟ ตัวอย่างเช่น:

$request->get('name', 'tom');

การรับค่าพารามิเตอร์ post

รับค่าทั้งหมดในอาร์เรย์ post

$request->post();

ถ้าการร้องขอไม่มีพารามิเตอร์ post จะคืนค่าเป็นอาร์เรย์ว่างเปล่า

รับค่าหนึ่งค่าจากอาร์เรย์ post

$request->post('name');

ถ้าอาร์เรย์ post ไม่มีค่านั้นจะคืนค่าเป็น null

เหมือนกับฟังก์ชัน get คุณยังสามารถส่งค่าค่าดีฟในพารามิเตอร์ที่สองของฟังก์ชัน post หากไม่พบค่าที่ตรงกันในอาร์เรย์ post จะคืนค่าเป็นค่าดีฟ ตัวอย่างเช่น:

$request->post('name', 'tom');

ฟังก์ชันช่วย input()

ฟังก์ชัน input() คล้ายกับ $request->input() ซึ่งสามารถเข้าถึงค่าทั้งหมดได้ โดยฟังก์ชันช่วย input() มีพารามิเตอร์ทั้งหมดสองตัว:

  1. name: ชื่อพารามิเตอร์ที่จะรับ (ถ้าเว้นว่าง จะได้รับอาร์เรย์ของค่าทั้งหมด)
  2. default: ค่าดีฟ (เมื่อการรับค่าจากพารามิเตอร์แรกล้มเหลว จะใช้ค่าพารามิเตอร์นี้)

ตัวอย่าง

// รับค่าพารามิเตอร์ name
$name = input('name');
// รับค่าพารามิเตอร์ name, หากไม่มีให้ใช้ค่าดีฟ
$name = input('name', '张三');
// รับค่าพารามิเตอร์ทั้งหมด
$all_params = input();

การรับข้อมูลแพ็กเกจโพสต์ดิบ

$post = $request->rawBody();

ฟังก์ชันนี้ทำงานคล้ายกับการใช้งาน file_get_contents("php://input"); ใน php-fpm ใช้เพื่อรับข้อมูลแพ็กเกจดิบ HTTP การรับข้อมูลจากการร้องขอแบบ post ที่ไม่เป็น application/x-www-form-urlencoded จะมีประโยชน์มาก

การรับ header

รับค่า header ทั้งหมดในอาร์เรย์

$request->header();

ถ้าการร้องขอไม่มีพารามิเตอร์ header จะคืนค่าเป็นอาร์เรย์ว่างเปล่า หมายเหตุ คีย์ทั้งหมดเป็นตัวพิมพ์เล็ก

รับค่าหนึ่งค่าจากอาร์เรย์ header

$request->header('host');

ถ้าอาร์เรย์ header ไม่มีค่านั้นจะคืนค่าเป็น null หมายเหตุ คีย์ทั้งหมดเป็นตัวพิมพ์เล็ก

เหมือนกับฟังก์ชัน get คุณยังสามารถส่งค่าค่าดีฟในพารามิเตอร์ที่สองของฟังก์ชัน header หากไม่พบค่าที่ตรงกันในอาร์เรย์ header จะคืนค่าเป็นค่าดีฟ ตัวอย่างเช่น:

$request->header('host', 'localhost');

การรับ cookie

รับค่า cookie ทั้งหมดในอาร์เรย์

$request->cookie();

ถ้าการร้องขอไม่มีพารามิเตอร์ cookie จะคืนค่าเป็นอาร์เรย์ว่างเปล่า

รับค่าหนึ่งค่าจากอาร์เรย์ cookie

$request->cookie('name');

ถ้าอาร์เรย์ cookie ไม่มีค่านั้นจะคืนค่าเป็น null

เหมือนกับฟังก์ชัน get คุณยังสามารถส่งค่าค่าดีฟในพารามิเตอร์ที่สองของฟังก์ชัน cookie หากไม่พบค่าที่ตรงกันในอาร์เรย์ cookie จะคืนค่าเป็นค่าดีฟ ตัวอย่างเช่น:

$request->cookie('name', 'tom');

การรับค่าทั้งหมดที่รับเข้ามา

รวมทั้งค่าจาก post และ get

$request->all();

การรับค่าที่ระบุ

จากการรวมกันของ post และ get รับค่าหนึ่งค่า

$request->input('name', $default_value);

การรับข้อมูลบางส่วนจาก input

จากการรวมกันของ post และ get รับข้อมูลบางส่วน

// รับอาร์เรย์ที่ประกอบด้วย username และ password หากไม่มีคีย์ที่เกี่ยวข้องจะถูกมองข้าม
$only = $request->only(['username', 'password']);
// รับค่าทั้งหมดยกเว้น avatar และ age
$except = $request->except(['avatar', 'age']);

การรับข้อมูลจากพารามิเตอร์ของตัวควบคุม

<?php
namespace app\controller;
use support\Response;

class UserController
{
    public function create(string $name, int $age = 18): Response
    {
        return json(['name' => $name, 'age' => $age]);
    }
}

ตรรกะของโค้ดคล้ายกับ

<?php
namespace app\controller;
use support\Request;
use support\Response;

class UserController
{
    public function create(Request $request): Response
    {
        $name = $request->input('name');
        $age = (int)$request->input('age', 18);
        return json(['name' => $name, 'age' => $age]);
    }
}

ข้อมูลเพิ่มเติมโปรดดูที่ การเชื่อมโยงพารามิเตอร์ของตัวควบคุม

การรับไฟล์ที่อัปโหลด

คำแนะนำ
การอัปโหลดไฟล์ต้องใช้ฟอร์มที่มีรูปแบบ multipart/form-data

การรับไฟล์ที่อัปโหลดทั้งหมดในอาร์เรย์

$request->file();

ฟอร์มมีลักษณะดังนี้:

<form method="post" action="http://127.0.0.1:8787/upload/files" enctype="multipart/form-data" />
<input name="file1" multiple="multiple" type="file">
<input name="file2" multiple="multiple" type="file">
<input type="submit">
</form>

รูปแบบผลลัพธ์จาก $request->file() จะมีลักษณะคล้าย:

array (
    'file1' => object(webman\Http\UploadFile),
    'file2' => object(webman\Http\UploadFile)
)

เป็นอาร์เรย์ของอินสแตนซ์ webman\Http\UploadFile คลาส webman\Http\UploadFile สืบทอดจากคลาส SplFileInfo ที่มีอยู่ใน PHP และยังมีวิธีการที่ใช้ประโยชน์ได้อีกด้วย

<?php
namespace app\controller;

use support\Request;

class UploadController
{
    public function files(Request $request)
    {
        foreach ($request->file() as $key => $spl_file) {
            var_export($spl_file->isValid()); // ไฟล์มีความถูกต้องหรือไม่ เช่น true|false
            var_export($spl_file->getUploadExtension()); // นามสกุลไฟล์ที่อัปโหลด เช่น 'jpg'
            var_export($spl_file->getUploadMimeType()); // ประเภท mime ของไฟล์ที่อัปโหลด เช่น 'image/jpeg'
            var_export($spl_file->getUploadErrorCode()); // รหัสข้อผิดพลาดในการอัปโหลด เช่น UPLOAD_ERR_NO_TMP_DIR UPLOAD_ERR_NO_FILE UPLOAD_ERR_CANT_WRITE
            var_export($spl_file->getUploadName()); // ชื่อไฟล์ที่อัปโหลด เช่น 'my-test.jpg'
            var_export($spl_file->getSize()); // ขนาดไฟล์ เช่น 13364 หน่วยเป็นไบต์
            var_export($spl_file->getPath()); // เส้นทางที่อัปโหลด เช่น '/tmp'
            var_export($spl_file->getRealPath()); // เส้นทางไฟล์ชั่วคราว เช่น `/tmp/workerman.upload.SRliMu`
        }
        return response('ok');
    }
}

หมายเหตุ:

  • ไฟล์ที่อัปโหลดจะถูกตั้งชื่อเป็นไฟล์ชั่วคราว เช่น /tmp/workerman.upload.SRliMu
  • ขนาดไฟล์ที่อัปโหลดจะถูกจำกัดตาม defaultMaxPackageSize โดยค่ามาตรฐานคือ 10MB สามารถเปลี่ยนแปลงได้ในไฟล์ config/server.php โดยตั้งค่า max_package_size
  • หลังจากการร้องขอสิ้นสุด ไฟล์ชั่วคราวจะถูกลบออกโดยอัตโนมัติ
  • หากการร้องขอไม่มีไฟล์ที่อัปโหลด $request->file() จะคืนค่าเป็นอาร์เรย์ว่างเปล่า
  • ไฟล์ที่อัปโหลดไม่รองรับกับวิธี move_uploaded_file() กรุณาใช้วิธี $file->move() แทน ดูตัวอย่างด้านล่าง

การรับไฟล์ที่อัปโหลดเฉพาะ

$request->file('avatar');

หากไฟล์นั้นมีอยู่ จะคืนค่าเป็นอินสแตนซ์ webman\Http\UploadFile ที่ตรงกัน มิฉะนั้นจะคืนค่าเป็น null

ตัวอย่าง

<?php
namespace app\controller;

use support\Request;

class UploadController
{
    public function file(Request $request)
    {
        $file = $request->file('avatar');
        if ($file && $file->isValid()) {
            $file->move(public_path().'/files/myfile.'.$file->getUploadExtension());
            return json(['code' => 0, 'msg' => 'upload success']);
        }
        return json(['code' => 1, 'msg' => 'file not found']);
    }
}

การรับ host

รับข้อมูล host ของการร้องขอ

$request->host();

ถ้าที่อยู่การร้องขอไม่ได้ใช้พอร์ตมาตรฐาน 80 หรือ 443 ข้อมูล host อาจจะรวมพอร์ตอยู่ เช่น example.com:8080 ถ้าไม่ต้องการพอร์ต สามารถส่งพารามิเตอร์แรกเป็น true

$request->host(true);

การรับวิธีการร้องขอ

$request->method();

ค่าที่ส่งคืนอาจเป็นหนึ่งใน GETPOSTPUTDELETEOPTIONSHEAD

การรับ uri ของการร้องขอ

$request->uri();

ส่งค่าที่เป็น uri ของการร้องขอ รวมถึง path และ queryString

การรับเส้นทางการร้องขอ

$request->path();

ส่งค่าที่เป็น path ของการร้องขอ

การรับ queryString ของการร้องขอ

$request->queryString();

ส่งค่าที่เป็น queryString ของการร้องขอ

การรับ url ของการร้องขอ

เมธอด url() จะคืนค่า URL โดยไม่รวม Query parameter

$request->url();

ส่งค่าที่คล้าย //www.workerman.net/workerman-chat

เมธอด fullUrl() จะคืนค่า URL พร้อมกับ Query parameter

$request->fullUrl();

ส่งค่าที่คล้าย //www.workerman.net/workerman-chat?type=download

หมายเหตุ
url() และ fullUrl() ไม่ได้ส่งคืนส่วนของโปรโตคอล (ไม่มีการส่งคืน http หรือ https)
เนื่องจากในเบราว์เซอร์เมื่อใช้อยู่ //example.com แบบที่เริ่มต้นด้วย // จะสามารถระบุโปรโตคอลของไซต์ในปัจจุบันได้โดยอัตโนมัติ และจะส่งคำร้องขอด้วย http หรือ https

หากคุณใช้ nginx เป็นพร็อกซี โปรดเพิ่ม proxy_set_header X-Forwarded-Proto $scheme; ลงในกำหนดการ nginx,ดูพร็อกซี nginx
จากนั้นคุณสามารถใช้ $request->header('x-forwarded-proto'); เพื่อตรวจสอบว่าเป็น http หรือ https เช่น:

echo $request->header('x-forwarded-proto'); // ส่งออก http หรือ https

การรับเวอร์ชัน HTTP ของการร้องขอ

$request->protocolVersion();

ส่งคืนสตริง 1.1 หรือ 1.0

การรับ sessionId ของการร้องขอ

$request->sessionId();

ส่งคืนสตริงที่ประกอบด้วยตัวอักษรและตัวเลข

การรับ IP ของไคลเอนต์ที่ทำการร้องขอ

$request->getRemoteIp();

การรับพอร์ตของไคลเอนต์ที่ทำการร้องขอ

$request->getRemotePort();

การรับ IP จริงของไคลเอนต์ที่ทำการร้องขอ

$request->getRealIp($safe_mode=true);

เมื่อโปรเจกต์ใช้พร็อกซี (เช่น nginx) IP ที่ได้จาก $request->getRemoteIp() มักจะเป็น IP ของเซิร์ฟเวอร์พร็อกซี (เช่น 127.0.0.1 192.168.x.x) แทนที่จะเป็น IP จริงของไคลเอนต์ ในกรณีนี้สามารถลองใช้ $request->getRealIp() เพื่อรับ IP จริงของไคลเอนต์

$request->getRealIp() จะพยายามดึง IP จริงจาก HTTP header ของ x-forwarded-forx-real-ipclient-ipx-client-ipvia

เนื่องจาก HTTP header สามารถปลอมแปลงได้ง่าย วิธีการนี้จึงไม่สามารถเชื่อถือได้ 100% โดยเฉพาะเมื่อ $safe_mode เป็น false วิธีที่เชื่อถือได้ในการรับ IP จริงของไคลเอนต์ผ่านพร็อกซีคือการรู้จัก IP ของเซิร์ฟเวอร์พร็อกซีที่ปลอดภัย และทราบว่า HTTP header ใดที่มี IP จริง ถ้า IP ที่คืนค่าจาก $request->getRemoteIp() ถูกยืนยันว่าเป็น IP ของเซิร์ฟเวอร์พร็อกซีที่ปลอดภัย ก็สามารถใช้ $request->header('HTTP_HEADER_WITH_REAL_IP') เพื่อรับ IP จริงได้

การรับ IP ของเซิร์ฟเวอร์

$request->getLocalIp();

การรับพอร์ตของเซิร์ฟเวอร์

$request->getLocalPort();

ตรวจสอบว่าการร้องขอเป็น ajax หรือไม่

$request->isAjax();

ตรวจสอบว่าการร้องขอเป็น pjax หรือไม่

$request->isPjax();

ตรวจสอบว่ารอการส่งคืนเป็น json หรือไม่

$request->expectsJson();

ตรวจสอบว่าไคลเอนต์ยอมรับการส่งคืนเป็น json หรือไม่

$request->acceptJson();

รับชื่อปลั๊กอินของการร้องขอ

การร้องขอที่ไม่ใช่ปลั๊กอินจะคืนค่าว่าง ''

$request->plugin;

รับชื่อแอปพลิเคชันของการร้องขอ

เมื่อเป็นแอปเดียวจะคืนค่าว่าง ''เมื่อเป็นหลายแอป จะคืนชื่อแอป

$request->app;

เนื่องจากฟังก์ชันปิดไม่อยู่ในแอปใด ๆ จึงทำให้การร้องขอจากเส้นทางที่เป็นฟังก์ชันปิด $request->app จะคืนค่าว่าง '' เสมอ
เส้นทางฟังก์ชันปิดดูที่ เส้นทาง

รับชื่อคลาสของตัวควบคุมที่ทำการร้องขอ

รับชื่อคลาสที่ตรงกันของตัวควบคุม

$request->controller;

ส่งค่าที่คล้ายกับ app\controller\IndexController

เนื่องจากฟังก์ชันปิดไม่อยู่ในตัวควบคุมใด ๆ การร้องขอที่มาจากเส้นทางฟังก์ชันปิด $request->controller จะคืนค่าว่าง '' เสมอ
เส้นทางฟังก์ชันปิดดูที่ เส้นทาง

รับชื่อเมธอดของการร้องขอ

รับชื่อเมธอดของตัวควบคุมที่ตรงกัน

$request->action;

ส่งค่าที่คล้ายกับ index

เนื่องจากฟังก์ชันปิดไม่อยู่ในตัวควบคุมใด ๆ การร้องขอที่มาจากเส้นทางฟังก์ชันปิด $request->action จะคืนค่าว่าง '' เสมอ
เส้นทางฟังก์ชันปิดดูที่ เส้นทาง

การเขียนทับพารามิเตอร์

บางครั้งเราต้องการเขียนทับพารามิเตอร์ของการร้องขอ เช่นการกรองพารามิเตอร์ เพื่อเขียนค่าทับในวัตถุการร้องขอ เราสามารถใช้วิธี setGet() setPost() setHeader() ได้

การเขียนทับพารามิเตอร์ GET

$request->get(); // สมมติว่าได้ ['name' => 'tom', 'age' => 18]
$request->setGet(['name' => 'tom']);
$request->get(); // จะได้ ['name' => 'tom']

หมายเหตุ
ตามตัวอย่าง setGet() เป็นการเขียนทับพารามิเตอร์ GET ทั้งหมด setPost() setHeader() ก็ทำงานในลักษณะเดียวกัน

การเขียนทับพารามิเตอร์ POST

$post = $request->post();
foreach ($post as $key => $value) {
    $post[$key] = htmlspecialchars($value);
}
$request->setPost($post);
$request->post(); // จะได้พารามิเตอร์โพสต์ที่กรองแล้ว

การเขียนทับพารามิเตอร์ HEADER

$request->setHeader(['host' => 'example.com']);
$request->header('host'); // ส่งออก example.com