คำอธิบาย
การรับวัตถุการร้องขอ
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() มีพารามิเตอร์ทั้งหมดสองตัว:
- name: ชื่อพารามิเตอร์ที่จะรับ (ถ้าเว้นว่าง จะได้รับอาร์เรย์ของค่าทั้งหมด)
- 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();
ค่าที่ส่งคืนอาจเป็นหนึ่งใน GET
、POST
、PUT
、DELETE
、OPTIONS
、HEAD
。
การรับ 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-for
、x-real-ip
、client-ip
、x-client-ip
、via
เนื่องจาก 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