What is Ticks in PHP

What is Ticks in PHP

PHP তে Ticks কি?

PHP -তে Ticks হল একটি script execute করার সময় নিয়মিত বিরতিতে একটি callback function রান করার একটি উপায়। Tick গুলো একটি স্ক্রিপ্টের প্রবাহ নিরীক্ষণ এবং নিয়ন্ত্রণ করার একটি উপায় প্রদান করে, যা low-level debugging, profiling এবং monitoring উদ্দেশ্যে তাদের প্রয়োজনীয় এবং কোন কোন ক্ষেত্রে অপরিহার্য করে তোলে। Tick গুলি আপনাকে আপনার script এর এক্সেকিউশন এর নির্দিষ্ট পয়েন্টগুলিতে কাস্টম কোড ইনজেক্ট করার অনুমতি দেয়।

কিভাবে Tick ফীচার Enable করবেন:

আপনি declare() statement ব্যবহার করে Tick ফীচার enable করতে পারেন। এর জন্য আপনাকে declare() ফাঙ্কশনে একটি argument হিসাবে tick interval নির্দিষ্ট করতে হবে। উদাহরণস্বরূপ, declare(ticks=1); এর মাধ্যমে প্রতিটি স্টেটমেন্টের এক্সেকিউট এর পরে tick গুলি এনাবল হয়। আপনি tick interval হিসাবে যেকোনো positive integer ব্যবহার করতে পারেন।

কিভাবে Tick ফাঙ্কশনকে রেজিস্টার করবেন :

একবার ticks এনাবল করা হলে, আপনাকে register_tick_function() function এর মাধ্যমে একটি callback function কে register করতে হবে। আর এই register_tick_function() ফাঙ্কশনটি প্রতিটি tick এ এক্সেকিউট করার জন্য একটি ফাংশনের নাম গ্রহণ করে।

Syntax

bool register_tick_function(callable $function)

একটি রেজিস্টার করা tick function কে কিভাবে আনরেজিস্টার করবেন:

PHP-তে রেজিস্টার করা একটি tick function আনরেজিস্টার করতে, আপনি unregister_tick_function() ফাংশন ব্যবহার করতে পারেন। এই ফাংশনটি argument হিসেবে tick function টির নাম গ্রহণ করে এবং এটিকে আনরেজিস্টার করে।

Syntax

bool unregister_tick_function(callable $function)

তো চলুন tick এর একটি ব্যবহার বা উদাহরণ দেখা যাক:

<?php
declare(ticks=1);

// Define a tick function
function tick_handler() {
    echo "Tick function called\n";
    // You can perform monitoring or debugging tasks here
}

// Register the tick function
register_tick_function('tick_handler');

// Code where ticks will be triggered
for ($i = 0; $i < 5; $i++) {
    // Simulate some work
    usleep(1000000); // Sleep for 1000 milliseconds
}

// Unregister the tick function
unregister_tick_function('tick_handler');
?>

এই উদাহরণে, tick_handler function টি লুপের মধ্যে প্রতিটি statement এর পরে কল করা হয়, যা আপনাকে script এর progress মনিটর করতে দেয়।

বাস্তব জীবনে Tick কি কি কাজে ব্যবহার হতে পারে?

১.Profiling:

আপনার কোডের নির্দিষ্ট অংশগুলি execute করতে যে সময় লাগে তা পরিমাপ করতে আপনি ticks ব্যবহার করতে পারেন। এটি আপনাকে আপনার script এর performance বাধা সনাক্ত করতে সাহায্য করতে পারে। নিম্নে PHP-তে profiling এর জন্য কীভাবে টিক ব্যবহার করতে হয় তার একটি বাস্তব উদাহরণ এখানে রয়েছে:

<?php
declare(ticks=1);

// Define a tick function to profile code execution time
function profile_tick() {
    static $startTime;

    if (!$startTime) {
        $startTime = microtime(true);
    } else {
        $endTime = microtime(true);
        $elapsedTime = round(($endTime - $startTime) * 1000, 2); // Calculate elapsed time in milliseconds
        echo "Time taken: {$elapsedTime} ms\n";
        $startTime = null; // Reset the start time for the next tick
    }
}

// Register the tick function
register_tick_function('profile_tick');

// Code to be profiled
for ($i = 0; $i < 100; $i++) {
	usleep(1000000);
    // Simulate some work
    $result = sqrt($i);
}

// Unregister the tick function
unregister_tick_function('profile_tick');
?>

এই উদাহরণে:

  • আমরা declare(ticks=1); দিয়ে টিক চালু করি, যার মানে profile_tick function টি প্রতিটি statement পরে এক্সেকিউট করা হবে।
  • আমরা profile_tick function টি সংজ্ঞায়িত করি, যা tick গুলির মধ্যে কোড রান করার জন্য টাইম কাউন্ট করে এবং প্রদর্শন করে।
  • profiling করা কোডের ভিতরে (লুপের জন্য), আমরা কাজ অনুকরণ করতে কিছু ক্যালকুলেশন করি (এই ক্ষেত্রে, বর্গমূল ক্যালকুলেশন করা)। সেই সাথে usleep ফাঙ্কশন ব্যবহার করে code execution টাইম কে ইচ্ছে করেই ডিলে করি, এতে আমরা execution time ধরতে পারব।
  • profile_tick function টি tick গুলির মধ্যে কোডটি এক্সেকিউট করতে টাইম ক্যালকুলেট করে এবং প্রদর্শন করে। এটি tick ফাংশনের প্রথম কল এবং দ্বিতীয় কলের মধ্যে সময় পরিমাপ করে, যা একবার লুপের মধ্যে কোডটি এক্সেকিউট করতে যে সময় নেয় তার সাথে মিলে যায়।
  • আমরা প্রোফাইলিং করার পরে tick ফাংশনটি আনরেজিস্টার করি যাতে স্ক্রিপ্টের বাকি অংশে এটি কার্যকর না হয়।

আপনি যখন এই স্ক্রিপ্টটি রান করবেন, তখন আপনি লুপের ভিতরে কোডের জন্য মিলিসেকেন্ডে এক্সিকিউশন সময় দেখতে পাবেন। এটি আপনাকে কোডের নির্দিষ্ট বিভাগটি কার্যকর করতে কতক্ষণ সময় নেয় তা প্রোফাইল করতে দেয়। প্রোফাইলিং আপনাকে আপনার স্ক্রিপ্টে পারফরম্যান্সের বাধাগুলি সনাক্ত করতে এবং প্রয়োজনে এটি অপ্টিমাইজ করতে সহায়তা করতে পারে।

অনুগ্রহ করে মনে রাখবেন যে প্রোফাইলিং এর জন্য টিক ব্যবহার করা যেতে পারে, এছাড়াও PHP-এর জন্য ডেডিকেটেড প্রোফাইলিং টুল এবং এক্সটেনশন রয়েছে, যেমন Xdebug, যা আরও ব্যাপক প্রোফাইলিং বৈশিষ্ট্য এবং একটি ভাল সামগ্রিক প্রোফাইলিং অভিজ্ঞতা প্রদান করে। যাইহোক, tick গুলি আপনার কোডের মধ্যে সরাসরি কিছু বেসিক প্রোফাইলিং ইনফরমেশন পেতে একটি লাইটওয়েট উপায় হতে পারে।

২.Resource Monitoring:

আপনার স্ক্রিপ্টের বিভিন্ন পয়েন্টে রিসোর্স ব্যবহার, যেমন memory consumption বা database queries ট্র্যাক রাখতে Ticks ব্যবহার করা যেতে পারে। resource monitoring এর জন্য কীভাবে টিক ব্যবহার করতে হয় তার একটি বাস্তব উদাহরণ এখানে দেওয়া হল:

<?php
declare(ticks=1);

// Define a tick function to monitor memory usage
function monitor_memory() {
    $memoryUsage = memory_get_usage(true); // Get current memory usage in bytes
    $formattedMemoryUsage = formatBytes($memoryUsage);
    echo "Memory Usage: $formattedMemoryUsage\n";
}

// Register the tick function
register_tick_function('monitor_memory');

// Helper function to format bytes in a human-readable format
function formatBytes($bytes, $precision = 2) {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];

    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);

    $bytes /= (1 << (10 * $pow));

    return round($bytes, $precision) . ' ' . $units[$pow];
}

// Code to be monitored for memory usage
$largeArray = range(1, 1000000); // Create a large array

// Unregister the tick function
unregister_tick_function('monitor_memory');
?>

এই উদাহরণে:

  • আমরা declare(ticks=1); দিয়ে টিক সক্রিয় করি, যার মানে প্রতিটি স্টেটমেন্টের পরে monitor_memory() ফাংশনটি কার্যকর করা হবে।
  • আমরা monitor_memory() ফাংশন সংজ্ঞায়িত করি, যা স্ক্রিপ্টের মেমরি ব্যবহার মনিটর এবং প্রদর্শন করে।
  • মনিটর করা কোডের ভিতরে (একটি বৃহৎ অ্যারের তৈরি), আমরা একটি অপারেশন করি যা উল্লেখযোগ্য পরিমাণে মেমরি গ্রাস করে।
  • monitor_memory() ফাংশনটি বাইটে বর্তমান মেমরি ব্যবহার পুনরুদ্ধার করতে memory_get_usage() ফাংশন ব্যবহার করে এবং তারপর এটি formatBytes() হেল্পার ফাংশন ব্যবহার করে human-readable format এ memory usage কে ফরম্যাট করে এবং প্রদর্শন করে।
  • আমরা tick ফাংশনটি monitoring এর পরে unregister করি যাতে স্ক্রিপ্টের বাকি অংশে এটি কার্যকর না হয়।

আপনি যখন এই script টি চালাবেন, আপনি প্রতিটি tick এর পরে মেমরি ব্যবহারের তথ্য দেখতে পাবেন, যা আপনাকে আপনার কোড কার্যকর করার সময় মেমরি consumption কীভাবে পরিবর্তিত হয় তা মনিটর করতে দেয়।

৩.Debugging:

Script এর আচরণ পর্যবেক্ষণ করতে এবং এর ভিতরের অবস্থা দেখতে আপনি debugging statements সন্নিবেশ করতে পারেন বা নির্দিষ্ট বিরতিতে custom debugging actions সম্পাদন করতে পারেন। debugging এর জন্য tick গুলি কীভাবে ব্যবহার করবেন তার একটি বাস্তব উদাহরণ এখানে রয়েছে:

<?php
declare(ticks=1);

// Define a tick function for debugging
function debug_tick() {
    static $tickCount = 0;

    $tickCount++;

    echo "Debug tick $tickCount\n";

    // You can insert custom debugging actions here
    // For example, logging variables or checking conditions
    $variableToDebug = "Some value";
    echo "Debugging variable: $variableToDebug\n";
    
    // Add a condition for debugging
    if ($tickCount == 3) {
        echo "Debug condition met at tick $tickCount\n";
    }
}

// Register the tick function
register_tick_function('debug_tick');

// Code to be debugged
for ($i = 0; $i < 5; $i++) {
    // Simulate some work
    $result = $i * 2;
}

// Unregister the tick function
unregister_tick_function('debug_tick');
?>

এই উদাহরণে:

  • আমরা declare(ticks=1); দিয়ে tick সক্রিয় করি, যার মানে debug_tick() ফাংশনটি প্রতিটি স্টেটমেন্টের পরে কার্যকর করা হবে।
  • আমরা debug_tick() ফাংশন সংজ্ঞায়িত করি, যা একটি tick কাউন্টার বৃদ্ধি করে এবং custom debugging actions সম্পাদন করে।
  • debug_tick() ফাংশনের ভিতরে, আমরা debugging statements সন্নিবেশ করি যেমন variable এর value গুলো echoing করা বা conditions গুলি চেক করা।
  • আমরা debug_tick() ফাংশনটি রেজিস্টার করি যেন প্রতিটি tick এক্সেকিউট করা যায়।
  • ডিবাগ করা কোডের ভিতরে (লুপের জন্য), আমরা কিছু ক্যালকুলেশন করি।
  • debug_tick() ফাংশনটি লুপের মধ্যে প্রতিটি স্টেটমেন্টের পরে কল করা হয়, যা আমাদের ডিবাগিং অ্যাকশন সঞ্চালন করতে এবং এক্সিকিউশন ফ্লো নিরীক্ষণ করতে দেয়।
  • আমরা টিক ফাংশনটিকে ডিবাগ করার পরে unregister করি যাতে স্ক্রিপ্টের বাকি অংশে এটি কার্যকর না হয়।

আপনি যখন এই স্ক্রিপ্টটি চালাবেন, আপনি প্রতিটি tick এর পরে ডিবাগিং ইনফরমেশন দেখতে পাবেন। এটি আপনাকে এক্সেকিউশন করার সময় নির্দিষ্ট বিরতিতে আপনার কোডে custom debugging actions এবং statement গুলোকে ইনজেক্ট করতে দেয়।

যদিও tick গুলি ডিবাগিংয়ের জন্য ব্যবহার করা যেতে পারে, তবে এগুলো পিএইচপি-তে সবচেয়ে সাধারণ ডিবাগিং কৌশল নয়। বেশিরভাগ ডিবাগিং কাজের জন্য ডেভেলপাররা প্রায়ই আরো স্ট্যান্ডার্ড ডিবাগিং অনুশীলনের উপর নির্ভর করে, যেমন echo, var_dump, বা dedicated debugging tools এবং লাইব্রেরি সমূহ ব্যবহার করে। tick গুলি সাধারণত বিশেষ পরিস্থিতিতে ব্যবহৃত হয় যেখানে সূক্ষানুসূক্ষ্য পর্যবেক্ষণ এবং ডিবাগিং প্রয়োজন।

Tick ব্যবহারে সতর্কতা এবং বিবেচনা:

১.Performance Overhead: ticks এনাবল করার ফলে আপনার প্রজেক্টে Performance Overhead হতে পারে, বিশেষ করে যদি tick interval টি ছোট হয় বা প্রতিটি tick এ জটিল অপারেশন করা হয়।

২.Compatibility: Ticks সব PHP environments সাপোর্ট করেনা এবং কিছু কনফিগারেশনে আশানুরূপ কাজ নাও করতে পারে৷

৩.Not for Production: Ticks সাধারণত প্রোডাকশন কোডে ব্যবহার করা হয় না বরং এটি ডেভেলপমেন্ট এবং ডিবাগিং উদ্দেশ্যে বেশি উপযুক্ত।

৪.Ticks and Loops: লুপগুলিতে ticks ব্যবহার করার সময় সতর্ক থাকতে হবে, কারণ এটি সাবধানে ম্যানেজ না করলে ticks আপনার script execution কে উল্লেখযোগ্যভাবে ধীর করে দিতে পারে।

৫.Unregistering Ticks: যখন আপনার আর tick প্রয়োজন হবে না তখন আপনি unregister_tick_function() ব্যবহার করে টিক ফাংশনগুলিকে unregister করতে পারেন।

সামগ্রিকভাবে, ticks একটি পাওয়ারফুল ফীচার কিন্তু PHP-তে এটি খুব কমই ব্যবহৃত ফীচার । এগুলি নির্দিষ্ট পরিস্থিতিতে ব্যবহার হতে পারে যেখানে সূক্ষ্ম-সুক্ষ মনিটরিং এবং ডিবাগিং প্রয়োজন, তবে পার্ফমেন্স এর উপর তাদের ticks এর প্রভাবের কারণে এগুলি বিচক্ষণতার সাথে ব্যবহার করা উচিত। বেশিরভাগ PHP ডেভেলপাররা তাদের প্রতিদিনের ডেভেলপমেন্ট এবং ডিবাগিং কাজের জন্য আরও জেনারেল ডিবাগিং টেকনিকস এবং টুল গুলির উপর নির্ভর করে।

একটি practical এবং real-world example

এখানে একটি real-world উদাহরণ দেওয়া হল যে কীভাবে PHP tick দিয়ে একটি basic logging mechanism বাস্তবায়নের জন্য ব্যবহার করা যেতে পারে যা কোডের বিভিন্ন sections গুলির এক্সেকিউশনের সময় রেকর্ড করে:

<?php
declare(ticks=1);

// Initialize an array to store log entries
$log = [];

// Define a tick function to log execution time
function log_execution_time() {
    global $log;
    static $startTime;

    if (!$startTime) {
        $startTime = microtime(true);
    } else {
        $endTime = microtime(true);
        $elapsedTime = round(($endTime - $startTime) * 1000, 2); // Calculate elapsed time in milliseconds
        $caller = debug_backtrace()[1]['function']; // Get the calling function's name
        $log[] = "$caller took $elapsedTime ms to execute";
        $startTime = null; // Reset the start time for the next tick
    }
}

// Register the tick function
register_tick_function('log_execution_time');

// Code with different sections to profile
function section1() {
    usleep(50000); // Simulate some work
}

function section2() {
    usleep(20000); // Simulate some work
}

// Trigger the code sections
for ($i = 0; $i < 3; $i++) {
    section1();
    section2();
}

// Unregister the tick function
unregister_tick_function('log_execution_time');

// Display the log entries
foreach ($log as $entry) {
    echo $entry . PHP_EOL;
}

এই উদাহরণে:

  • আমরা declare(ticks=1); ব্যবহার করে প্রথমে ticks এনাবল করি, যাতে আমাদের কোড গুলোর section গুলির execution time লগ করার জন্য log_execution_time ফাংশন রেজিস্টার করতে দেয়।
  • আমরা log_execution_time ফাংশন ডিফাইন করি, যাতে টিকগুলির মধ্যে অতিবাহিত সময় ক্যালকুলেট করে এবং এবং সেই টাইমটা রেকর্ড করে। এটি debug_backtrace() ব্যবহার করে কলিং ফাংশন সনাক্ত করে।
  • আমরা register_tick_function(‘log_execution_time’) ব্যবহার করে একটি tick ফাংশন হিসাবে log_execution_time ফাংশন register করি।
  • আমাদের কাছে দুটি code section আছে, একটি section1() এবং অন্যটি section2(), প্রত্যেকটি usleep() ব্যবহার করে কিছু কাজ simulating করে।
  • আমরা এই code section গুলিকে একটি লুপে একাধিকবার তাদের এক্সেকিউশন করার সময়টি প্রোফাইল করতে কল করি।
  • profiling করার পরে, আমরা unregister_tick_function(‘log_execution_time’) ব্যবহার করে tick ফাংশনটি unregister করি; আরও profiling বন্ধ করতে।
  • সর্বশেষে, আমরা log entry গুলি ডিসপ্লে করি, যা দেখায় যে প্রতিটি code section টি এক্সেকিউশন করতে কত সময় নিয়েছে।

এই উদাহরণটি দেখায় যে কোডের বিভিন্ন সেক্শনে execution time মনিটরের জন্য একটি basic profiling এবং logging mechanism তৈরি করতে কীভাবে tick ব্যবহার করা যেতে পারে। যদিও এটি একটি সরলীকৃত উদাহরণ, real-world এ PHP অ্যাপ্লিকেশনগুলিতে আরও জটিল প্রোফাইলিং এবং ডিবাগিং scenario এর জন্য ticks মূল্যবান হতে পারে।

ticks ব্যবহার করে আরো একটি real-world example

একটি real-world PHP application এ, আপনি আরও জটিল profiling এবং debugging পরিস্থিতির জন্য ticks ব্যবহার করতে পারেন। বিভিন্ন ফাংশনের এক্সিকিউশন সময় পরিমাপ করতে এবং ফাইলে পার্ফমেন্স ডেটা লগ করার জন্য আপনি কীভাবে একটি profiling system বাস্তবায়ন করতে পারেন তার একটি উদাহরণ এখানে দেওয়া হল:

<?php
declare(ticks=1);

// Initialize a log file
$logFileName = 'profile.log';
$logFile = fopen($logFileName, 'a');

// Define a tick function to profile function execution time
function profile_function_execution() {
    global $logFile;
    static $startTime;
    static $functionName;

    $debugBacktrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);

    if (!$startTime) {
        $startTime = microtime(true);
        $functionName = $debugBacktrace[1]['function'];
    } else {
        $endTime = microtime(true);
        $elapsedTime = round(($endTime - $startTime) * 1000, 2); // Calculate elapsed time in milliseconds

        $callerFunction = $debugBacktrace[1]['function'];
        $callerFile = $debugBacktrace[0]['file'];
        $callerLine = $debugBacktrace[0]['line'];

        $logEntry = "Function: $functionName (called by $callerFunction in $callerFile:$callerLine) took $elapsedTime ms to execute.\n";

        fwrite($logFile, $logEntry);

        $startTime = null; // Reset the start time for the next tick
    }
}

// Register the tick function
register_tick_function('profile_function_execution');

// Simulate a complex application with various functions
function foo() {
    usleep(100000); // Simulate some work
}

function bar() {
    usleep(50000); // Simulate some work
    foo(); // Call another function
}

// Trigger the functions
for ($i = 0; $i < 3; $i++) {
    bar();
}

// Unregister the tick function
unregister_tick_function('profile_function_execution');

// Close the log file
fclose($logFile);

echo "Profiling data has been logged to $logFileName.\n";

এই উদাহরণে:

  • আমরা declare(ticks=1);. দিয়ে টিক সক্রিয় করি;
  • আমরা একটি লগ ফাইল (profile.log) তৈরি করি যেখানে আমরা প্রোফাইলিং ডেটা রেকর্ড করব।
  • আমরা profile_function_execution tick function টি ডিফাইন করি, যা ফাংশনের এক্সেকিউশনের সময় রেকর্ড করে এবং লগ ফাইলে ডেটা লগ করে। এটি calling function সম্পর্কে তথ্য পেতে debug_backtrace() ব্যবহার করে।
  • আমরা profile_function_execution ফাংশনটিকে একটি tick function হিসাবে রেজিস্টার করি।
  • আমরা দুটি example functions ডিফাইন করি, একটি হচ্ছে foo এবং অপরটি bar, যা complex operation গুলোকে অনুকরণ করে। bar এছাড়াও foo কে কল করে.
  • nested function call সহ একটি complex application simulate করতে আমরা একটি লুপে একাধিকবার ফাংশনগুলি ট্রিগার করি।
  • profiling করার পরে, আমরা tick function টি unregister করি।
  • সবশেষে , আমরা লগ ফাইলটি ক্লোজ করি এবং ব্যবহারকারীকে জানাই যেখানে প্রোফাইলিং ডেটা লগ করা হয়েছে।

এই উদাহরণটি দেখায় কিভাবে একটি real-world PHP অ্যাপ্লিকেশনে আরও জটিল profiling পরিস্থিতির জন্য tick ব্যবহার করা যেতে পারে। log file (profile.log) বিভিন্ন ফাংশন এক্সেকিউশন টাইম সম্পর্কে বিস্তারিত তথ্য থাকবে, এর মধ্যে কোন ফাংশন থেকে এবং কোন ফাইল এবং লাইন নম্বর থেকে। এই ধরনের প্রোফাইলিং ডেটা পারফরম্যান্সের বাধাগুলি সনাক্ত করতে এবং আপনার অ্যাপ্লিকেশনটিকে অপ্টিমাইজ করার জন্য মূল্যবান হতে পারে।

আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ১৫ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller, Amarbebsha Ltd সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ডেটা সাইন্স, মেশিন লার্নিং, বিগ ডেটা, ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। এছাড়াও বাংলাদেশের ১৮৫ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ১২০ এরও অধিক ছাত্র আমার হাতে জেন্ড সার্টিফাইড ইঞ্জিনিয়ার হয়েছেন। বর্তমানে w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -8.2 Engineering, Laravel Mastering Course with ReactJS, Python Beginning To Advance with Blockchain, Machine Learning and Data Science, Professional WordPress Plugin Development Beginning to Advance কোর্স করাই। আর অবসর সময়ে w3programmers.com এ ওয়েব টেকনোলজি নিয়ে লেখালেখি করি।

Leave a Reply