প্রতিক্রিয়া

প্রতিক্রিয়া প্রকৃতপক্ষে একটি support\Response অবজেক্ট, এই অবজেক্টটি তৈরি করতে সহায়তার জন্য, ওয়েবম্যান কিছু সাহায্যকারী ফাংশন প্রদান করে।

যেকোনো প্রতিক্রিয়া ফেরত দিন

উদাহরণ

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response('hello webman');
    }
}

response ফাংশনের বাস্তবায়ন নিচে দেওয়া হলো:

function response($body = '', $status = 200, $headers = array())
{
    return new Response($status, $headers, $body);
}

আপনি একটি খালি response অবজেক্টও তৈরি করতে পারেন, তারপর প্রয়োজনমতো $response->cookie() $response->header() $response->withHeaders() $response->withBody() ব্যবহার করে ফেরত দেওয়ার বিষয়বস্তু সেট করতে পারেন।

public function hello(Request $request)
{
    // একটি অবজেক্ট তৈরি করুন
    $response = response();

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // কুকি সেট করুন
    $response->cookie('foo', 'value');

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // HTTP হেডার সেট করুন
    $response->header('Content-Type', 'application/json');
    $response->withHeaders([
                'X-Header-One' => 'Header Value 1',
                'X-Header-Tow' => 'Header Value 2',
            ]);

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // ফেরত দেওয়ার জন্য ডেটা সেট করুন
    $response->withBody('ফেরত দেওয়ার ডেটা');
    return $response;
}

JSON ফেরত দিন

উদাহরণ

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return json(['code' => 0, 'msg' => 'ok']);
    }
}

json ফাংশনের বাস্তবায়ন নিচে দেওয়া হলো:

function json($data, $options = JSON_UNESCAPED_UNICODE)
{
    return new Response(200, ['Content-Type' => 'application/json'], json_encode($data, $options));
}

XML ফেরত দিন

উদাহরণ

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        $xml = <<<XML
               <?xml version='1.0' standalone='yes'?>
               <values>
                   <truevalue>1</truevalue>
                   <falsevalue>0</falsevalue>
               </values>
               XML;
        return xml($xml);
    }
}

xml ফাংশনের বাস্তবায়ন নিচে দেওয়া হলো:

function xml($xml)
{
    if ($xml instanceof SimpleXMLElement) {
        $xml = $xml->asXML();
    }
    return new Response(200, ['Content-Type' => 'text/xml'], $xml);
}

ভিউ ফেরত দিন

নতুন ফাইল app/controller/FooController.php তৈরি করুন নিচে দিন অনুসারে

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return view('foo/hello', ['name' => 'webman']);
    }
}

নতুন ফাইল app/view/foo/hello.html তৈরি করুন নিচে দিন অনুসারে

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>webman</title>
</head>
<body>
hello <?=htmlspecialchars($name)?>
</body>
</html>

পুনঃনির্দেশনা

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return redirect('/user');
    }
}

redirect ফাংশনের বাস্তবায়ন নিচে দেওয়া হলো:

function redirect($location, $status = 302, $headers = [])
{
    $response = new Response($status, ['Location' => $location]);
    if (!empty($headers)) {
        $response->withHeaders($headers);
    }
    return $response;
}

হেডার সেটিং

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response('hello webman', 200, [
            'Content-Type' => 'application/json',
            'X-Header-One' => 'Header Value' 
        ]);
    }
}

একক বা ব্যাচে হেডার সেট করতে header এবং withHeaders পদ্ধতি ব্যবহার করা যেতে পারে।

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response('hello webman')
        ->header('Content-Type', 'application/json')
        ->withHeaders([
            'X-Header-One' => 'Header Value 1',
            'X-Header-Tow' => 'Header Value 2',
        ]);
    }
}

আপনি আগে থেকেই হেডার সেট করতে পারেন, পরে যে তথ্য ফেরত দিতে হবে সেটি সেট করতে পারেন।

public function hello(Request $request)
{
    // একটি অবজেক্ট তৈরি করুন
    $response = response();

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // HTTP হেডার সেট করুন
    $response->header('Content-Type', 'application/json');
    $response->withHeaders([
                'X-Header-One' => 'Header Value 1',
                'X-Header-Tow' => 'Header Value 2',
            ]);

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // ফেরত দেওয়ার জন্য ডেটা সেট করুন
    $response->withBody('ফেরত দেওয়ার ডেটা');
    return $response;
}

কুকি সেট করা

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response('hello webman')
        ->cookie('foo', 'value');
    }
}

আপনি আগেই কুকি সেট করতে পারেন, পরে ফিরতি ডেটা সেট করতে পারেন।

public function hello(Request $request)
{
    // একটি অবজেক্ট তৈরি করুন
    $response = response();

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // কুকি সেট করুন
    $response->cookie('foo', 'value');

    // .... ব্যবসায়িক লজিক বাদ দেওয়া হয়েছে

    // ফেরত দেওয়ার জন্য ডেটা সেট করুন
    $response->withBody('ফেরত দেওয়ার ডেটা');
    return $response;
}

কুকি পদ্ধতির সম্পূর্ণ প্যারামিটার如下:

cookie($name, $value = '', $max_age = 0, $path = '', $domain = '', $secure = false, $http_only = false)

ফাইল স্ট্রিম ফেরত দিন

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response()->file(public_path() . '/favicon.ico');
    }
}
  • ওয়েবম্যান বড় ফাইল পাঠানোর সমর্থন করে
  • বড় ফাইলের জন্য (2 এমবি এর বেশি), ওয়েবম্যান পুরো ফাইল একবারে মেমোরিতে পড়বে না, বরং সঠিক সময়ে ফাইলটি পরপর পড়বে এবং পাঠাবে
  • ওয়েবম্যান ক্লায়েন্টের গ্রহণের গতির উপর ভিত্তি করে ফাইল পড়ার এবং পাঠানোর গতিকে অপ্টিমাইজ করে, দ্রুত ফাইল পাঠানোর সময় মেমোরির ব্যবহার কমিয়ে দেয়
  • ডেটা পাঠানো অ-বাধা, এটি অন্যান্য অনুরোধের প্রক্রিয়াকরণের উপর প্রভাব ফেলবে না
  • file পদ্ধতি স্বয়ংক্রিয়ভাবে if-modified-since হেডার যুক্ত করবে এবং পরবর্তী অনুরোধের সময় if-modified-since হেডার পরীক্ষা করবে, যদি ফাইলটি পরিবর্তিত না হয় তবে সরাসরি 304 ফেরত দিবে যাতে ব্যান্ডউইথ সংরক্ষণ হয়
  • পাঠানো ফাইলগুলির জন্য ব্রাউজারে পাঠানো হবে উপযুক্ত Content-Type হেডার স্বয়ংক্রিয়ভাবে ব্যবহার করা হবে
  • যদি ফাইল না থাকে তবে এটি স্বয়ংক্রিয়ভাবে 404 প্রতিক্রিয়াতে পরিবর্তিত হবে

ফাইল ডাউনলোড

<?php
namespace app\controller;

use support\Request;

class FooController
{
    public function hello(Request $request)
    {
        return response()->download(public_path() . '/favicon.ico', 'ফাইলের নাম.ico');
    }
}

ডাউনলোড পদ্ধতি এবং ফাইল পদ্ধতির মধ্যে মূল পার্থক্য হল

  1. ডাউনলোডের জন্য ফাইলের নাম সেট করার পর ফাইলটি ডাউনলোড হবে, না যে ব্রাউজারে প্রদর্শিত হবে
  2. ডাউনলোড পদ্ধতি if-modified-since হেডার পরীক্ষা করবে না

আউটপুট পাওয়া

কিছু লাইব্রেরি ফাইলের বিষয়বস্তু সরাসরি স্ট্যান্ডার্ড আউটপুটে প্রিন্ট করে, অর্থাৎ ডেটা কমান্ড লাইন টার্মিনালে প্রিন্ট হবে, ব্রাউজারে নয়, সেক্ষেত্রে আমাদের ob_start(); ob_get_clean(); ব্যবহার করে ডেটা একটি ভেরিয়েবলে ক্যাপচার করতে হবে, তারপর ডেটা ব্রাউজারে পাঠানোর জন্য, যেমন:

<?php

namespace app\controller;

use support\Request;

class ImageController
{
    public function get(Request $request)
    {
        // একটি চিত্র তৈরি করুন
        $im = imagecreatetruecolor(120, 20);
        $text_color = imagecolorallocate($im, 233, 14, 91);
        imagestring($im, 1, 5, 5,  'A Simple Text String', $text_color);

        // আউটপুট গ্রহণ শুরু করুন
        ob_start();
        // চিত্র আউটপুট করুন
        imagejpeg($im);
        // চিত্র বিষয়বস্তু নিন
        $image = ob_get_clean();

        // চিত্র পাঠান
        return response($image)->header('Content-Type', 'image/jpeg');
    }
}

অংশীদার প্রতিক্রিয়া

কখনো কখনো আমরা অংশ ভাগ করে প্রতিক্রিয়া পাঠাতে চাই, নিচের উদাহরণটি দেখুন।

<?php

namespace app\controller;

use support\Request;
use support\Response;
use Workerman\Protocols\Http\Chunk;
use Workerman\Timer;

class IndexController
{
    public function index(Request $request): Response
    {
        // সংযোগটি পান
        $connection = $request->connection;
        // HTTP প্যাকেজ কন্টেন্ট সময়সীমা পাঠান
        $timer = Timer::add(1, function () use ($connection, &$timer) {
            static $i = 0;
            if ($i++ < 10) {
                // HTTP প্যাকেজ কন্টেন্ট পাঠান
                $connection->send(new Chunk($i));
            } else {
                // বাঁধাকলা সময়কর্তা যত বেশি হয়ে যায় তত বেশি মেমরি লিক রোধ করতে অপ্রয়োজনীয় টাইমার মুছে ফেলুন
                Timer::del($timer);
                // ক্লায়েন্টকে প্রতিক্রিয়া শেষ হওয়ার জন্য খালি Chunk প্যাকেজ আউটপুট করুন
                $connection->send(new Chunk(''));
            }
        });
        // প্রথমে একটি Transfer-Encoding: chunked সহ HTTP হেডার আউটপুট করুন, HTTP প্যাকেট কন্টেন্ট আশিঘোনীয়ভাবে পাঠানো হবে
        return response()->withHeaders([
            "Transfer-Encoding" => "chunked",
        ]);
    }

}

যদি আপনি একটি বড় মডেল কল করেন তবে নিচের উদাহরণটি দেখুন।

composer require webman/openai
<?php
namespace app\controller;
use support\Request;

use Webman\Openai\Chat;
use Workerman\Protocols\Http\Chunk;

class ChatController
{
    public function completions(Request $request)
    {
        $connection = $request->connection;
        // https://api.openai.com দেশীয়ভাবে অ্যাক্সেস করা না হলে https://api.openai-proxy.com ঠিকানা প্রতিস্থাপন করতে পারেন
        $chat = new Chat(['apikey' => 'sk-xx', 'api' => 'https://api.openai.com']);
        $chat->completions(
            [
                'model' => 'gpt-3.5-turbo',
                'stream' => true,
                'messages' => [['role' => 'user', 'content' => 'hello']],
            ], [
            'stream' => function($data) use ($connection) {
                // যখন openai ইন্টারফেস ডেটা ফেরত দেয় তখন এটি ব্রাউজারে পাঠান
                $connection->send(new Chunk(json_encode($data, JSON_UNESCAPED_UNICODE) . "\n"));
            },
            'complete' => function($result, $response) use ($connection) {
                // প্রতিক্রিয়া শেষ হলে যদি কোনো ত্রুটি থাকে তা পরীক্ষা করুন
                if (isset($result['error'])) {
                    $connection->send(new Chunk(json_encode($result, JSON_UNESCAPED_UNICODE) . "\n"));
                }
                // খালি chunk ফেরত দিলে তা প্রতিক্রিয়া শেষ করছে নির্দেশ করে
                $connection->send(new Chunk(''));
            },
        ]);
        // প্রথমে একটি HTTP হেডার ফেরত দিন, পরবর্তী ডেটা নিম্নত্তর উপস্থিত হবে
        return response()->withHeaders([
            "Transfer-Encoding" => "chunked",
        ]);
    }
}